Removing bullet object from ArrayList error.

Hey, I get random(!) errors while removing my bullet from ArrayList once it hits the player.
I think its because of the for loop but dont know how to do it different…

This is how I create the bullet:

    ArrayList <Projectile> enemyBullets = new ArrayList<Projectile>();  // GegnerTyp2 Geschosse

  
projectile = new Projectile(enemyContainer.get(enemys).x, enemyContainer.get(enemys).y, sprites.projectile ,2);
enemyBullets.add(projectile);

This is the collision:


 // Go through each enemy bullets
       for(int x = 0; x < enemyBullets.size(); x++)
       {
           
        // Go through each enemy
               for(int z = 0; z < enemyContainer.size(); z++)
               {
                   // Does the bullet hit the player?
                    if(enemyBullets.get(x).x > player.x && enemyBullets.get(x).x < player.x + 64 + value 
                    && enemyBullets.get(x).y > player.y && enemyBullets.get(x).y < player.y + 37 )
                    {
                        // If the player has shield left it will damage this first.
                        if(player.shield>0)
                             player.shield = player.shield - 2f;
                        else
                        {
                            // The damage the player get
                            damageValue = (enemyContainer.get(z).laser - player.armor);
                            
                            if(damageValue>0)
                              player.hp = player.hp - Math.abs(damageValue);
                        } 
                        enemyBullets.get(x).sprite = sprites.emptyProjectile; // I remove the bullet graphic here.
                        enemyBullets.remove(x);   //!!! Here I remove the bullet but I get random error.
                    }
                }
             
       }

So any ideas how I can solve it to remove the bullet without this error warning:

You don’t break out of the inner loop having removed a bullet. Which means the same bullet might hit two gidrahs and you then attempt to remove it again.

Cas :slight_smile:

Hm…But I have to remove the bullet when it hits the player…
So there do you say I should place it?

And what is an gidrahs?? The Player? The bullet only can hit one event and thats the player. Hm…

(Ah and I forgot to take out the for loop with the enemyContainer, I dont need anymore)

if you remove the enemyContainer loop, you just have to decrease x after the removal so that you don’t skip a bullet, but anyway in this case you shouldn’t get an IndexOutOfBoundsException anymore.
I suggest you to use an Iterator to loop through the bullets and use its remove method to remove the current bullet from the list … this way you will not have to handle the index yourself. And instead of doing lots of enemyBullets.get(x), do it once at the begining of the loop and store it in a variable ( if you use an Iterator you will be forced to anyway :slight_smile: ).

A gidrah is princec’s fancy shmancy way of calling enemies :stuck_out_tongue:

If ‘x’ is the last element in the list, removing it makes ‘x’ outside the bounds of the list. Since you don’t break out of the inner loop, you are accessing ‘x’ again! What you should do is stop the inner loop as soon as the bullet is removed, by using a boolean or something.

You shouldn’t remove bullets while looping through them either, it will cause a concurrent modification exception.

Either make a seperate list of bullets to remove, which you then remove all at once after the collision code with enemyBullets.removeAll(bulletsToRemove);

or use an iterator(better) as deathpat said:

Iterator<Projectile> it = enemyBullets.iterator();

while (it.hasNext())
{
      Projectile bullet = it.next();
      boolean hit = false;
      for(Enemy enemy: enemyContainer)
      {
             //do collision
             <if collided> //TODO replace this line with your collision code
             hit = true;
             break;
      }
      if (hit)
         it.remove(); //removes the current bullet from the list of bullets SAFELY.
}

Your inner loop also does some strange stuff.
You are checking if the bullet collides with the player for each enemy. You should only check if each bullet collides with the player once.

for(int x = 0; x < enemyBullets.size(); x++)
       {
              //do player-bullet collision here

              //you should make each bullet store a damage variable, then you dont need to loop through the enemies at all.
              //when the enemy creates a bullet, it gives the bullet the amount of damage an enemy does.
}

Create another ArrayList to hold queue of being removed bullet. Then use removeAll(ArrayList) method to clear main ArrayList so you can avoid that issue.