0

I have got 2 arraylists, one for bullets and another for enemies, both with their respective classes ('Enemy' and 'Bullet').

I am trying to do a collision check to see if the bullet hits the enemy, if it does, it removes the bullet and some of the enemies health. The method currently works perfectly if there is only one bullet on the screen at a time, if more than one shot is fired, as soon as the first bullet hits the enemy, there is an 'index out of bounds exception' and crashes. Here is my code:

private void checkBulletCollisions() {
    int len = bullets.size();
    int enemyLen = enemies.size();
    for (int i = 0; i < len; i++) {
        Bullet bullet = bullets.get(i);
        for (int j = 0; j < enemyLen; j++) {

            Enemy enemy = enemies.get(j);
            if (bullet.bounds.overlaps(enemy.bounds)) {
                bullets.remove(bullet);
                enemy.health--;

                if (enemy.health <= 0) {
                    enemies.remove(enemy);
                    break;
                }
            }
        }
    }

}

By commenting out the bullets.remove line and enemy.health --, there are no errors.

I'm guessing its because when the bullet is removed, the index changes on the remaining bullets. I'm not sure if the problem lies somewhere in the order of the code or if a completely different method is required. Thank you for any help

1 Answers1

2

You are right, the problem is that you remove an entry from the list without updating the list size you use to iterate over the entries. For example, if the list as three entries in the beginning and you remove one entry, there are only two entries left. Nevertheless you try to access the third entry in your loop.

In general, it is not a good idea to modify a list in a for or foreach loop iterating over it. Use a while loop and an Iterator instead, as described in this answer.

For example:

Iterator<Bullet> bulletIterator = bullets.iterator();
while (bulletIterator.hasNext()) {
    Bullet bullet = bulletIterator.next();
    Iterator<Enemy> enemyIterator = enemies.iterator();
    while (enemyIterator.hasNext()) {
        Enemy enemy = enemyIterator.next();
        if (/* check if you have to remove the bullet */) {
            bulletIterator.remove();
        }
        if (/* check if you have to remove the enemy */) {
            enemyIterator.remove();
        }
    }
}
Community
  • 1
  • 1
Robin Krahl
  • 5,268
  • 19
  • 32