C # -> Индекс был вне диапазона ошибки | Использование списков

1

Я использую XNA для создания танковой игры. Я реализовал функцию для стрельбы по пулям, используя список. После съемки я хочу проверить, приближалась ли пуля к границам экрана. Если это так, удалите эту конкретную марку из списка.

Ошибка появляется только в том случае, если на экране в каждый момент времени отображается более одной пули. Вот код:


Класс бака:

List<Bullet> bulletList = new List<Bullet>();
bool spacebarPrepared = true;    //for shooting every 0.5 seconds
short count = 0;


//Shoot
if (Keyboard.GetState().IsKeyDown(Keys.Space) && spacebarPrepared == true)
   {
        bulletList.Add(new Bullet(sprBullet, position, turretDirection, turretAngle));
        spacebarPrepared = false;
   }


if (spacebarPrepared == false)
    {
        spacebarCount += (float)gameTime.ElapsedGameTime.TotalSeconds;

        if (spacebarCount > 0.5)
        {
            spacebarPrepared = true;
            spacebarCount = 0;
        }
    }


//Update bullets
foreach (Bullet bullet in bulletList)
{
    bullet.Update(bounds);
}


count = (short)bulletList.Count;

//Remove unwanted bullets
for (short i = 0; i < count; i++)
{
    if (bulletList[i].Alive == false)
    {
        bulletList.Remove(bulletList[i]);
    }
 }

Класс пули:

class Bullet
{
    Texture2D spr;
    Vector2 origin, pos, dir, turretLength;
    float rotation, scale, turretLeng;
    short speed;
    bool alive = true;


    public Bullet(Texture2D sprite, Vector2 position, Vector2 direction, float angle)
    {
        spr = sprite;
        scale = 0.15f;
        turretLeng = (110 + spr.Width) * scale;
        speed = 5;
        rotation = angle;
        pos = position;
        dir = direction;
        origin = new Vector2(spr.Width / 2, spr.Height / 2);
        FindTurretLength();
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        Matrix bulletTranslation = Matrix.CreateRotationZ(rotation) * Matrix.CreateTranslation(pos.X + turretLength.X, pos.Y + turretLength.Y, 0);

        spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, null, null, bulletTranslation);
        spriteBatch.Draw(spr, Vector2.Zero, null, Color.White, 0, origin, 0.15f, SpriteEffects.None, 1f);
        spriteBatch.End();
    }

    public void Update(Vector2 boundary)
    {
        pos += dir * speed;


        if (pos.X < 50 || pos.X > boundary.X - 50 || pos.Y < 50 || pos.Y > boundary.Y - 50)
        {
            alive = false;
        }
    }

    public void FindTurretLength()
    {
        turretLength = new Vector2(turretLeng * dir.X, turretLeng * dir.Y);
    }

    public Vector2 Pos
    {
        get
        {
            return pos;
        }
        set
        {
            pos = value;
        }
    }

    public bool Alive
    {
        get
        {
            return alive;
        }
        set
        {
            alive = value;
        }
    }
}

Что я заметил сам, когда отладка заключалась в том, что моя собственная переменная count = 2, но bulletList.Count = 1. Может быть, проблема? Как это происходит?

Любая помощь приветствуется.

  • 1
    эта ошибка возникает, когда вы пытаетесь получить доступ к элементу в списке или массиве, который превышает количество элементов в указанном списке. Вы должны быть в состоянии выяснить, где это происходит, отладив и изучив строку, в которую он добавлен, затем вернувшись назад и пройдя по нему, чтобы увидеть, как выполняется код.
  • 0
    Кроме того, почему вы объявляете count short ? Кажется, int будет более естественным.
Показать ещё 4 комментария
Теги:
list
count
xna

1 ответ

1
Лучший ответ

Проблема заключается в вашей петле for, которая удаляет пули.

Допустим, у вас есть список из 10 пуль (индексы 0 - 9) при запуске цикла. 1-я пуля (с индексом 0) удаляется.... теперь ваш список имеет 9 пуль (индексы 0 - 8), но переменная count не обновлена, поэтому ваш цикл по-прежнему считает, что у него 10.

Когда вы достигнете точки, где "i" больше, чем ACTUAL количество пуль вживую, вы получите "Индекс был вне допустимого диапазона". ошибка.

Существует несколько способов устранения этой ошибки.

Я бы пошел:

bulletList.RemoveAll(x => !x.Alive);
  • 0
    Это идеальный ответ. Я принял ответ AlexD, так как он был быстрее в освоении. Спасибо!
  • 2
    @meestaman Не принимайте ответ, основываясь на том, насколько быстро кто-то, но на качестве.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню