Search code examples
javamultithreadinglinked-listconcurrentmodification

Java game crash on collision detection with LinkedList


I am making a 2D java game based on Space Invaders. In my Game class I have these 3 fields:

//enemies left to kill
private LinkedList<Enemy> enemiesLeft = new LinkedList<Enemy>(); 
//enemies killed
private LinkedList<Enemy> enemiesKilled = new LinkedList<Enemy>();
//missiles that have been fired
private LinkedList<Missile> missiles = new LinkedList<Missile>();

In my checkCollision() method I run through each Enemy in the enemiesLeft list and check for collision with each Missile in the missiles list, but it throws a ConcurrentModificationException.

Here is the checkCollision() method:

private void checkCollisions(){
  //make an iterator over enemies
  ListIterator<Enemy> iterEnemies = enemiesLeft.listIterator();   

  //loop through enemies
  while(iterEnemies.hasNext()){
    //error is thrown at below line
    Enemy e = iterEnemies.next();  //current Enemy

    //go through each Missile
    ListIterator<Missile> iterMissiles = missiles.listIterator(); 
    while(iterMissiles.hasNext()){
      Missile m = iterMissiles.next();  //current Missile
      if(e.doesIntersect(m)){           
      //remove Enemy from enemiesLeft and add it to enemiesKilled list
      enemiesKilled.add(enemiesLeft.remove(enemiesLeft.indexOf(e)));
      //remove Missile
      missiles.remove(m);
      }
    }
  }
   updateScore();
}

And this is the error I get:

java.util.ConcurrentModificationException
   at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
   at java.util.LinkedList$ListItr.next(Unknown Source)
   at Game.checkCollisions(Game.java:168)
   at Game.run(Game.java:197)
   at Game.main(Game.java:279)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at      edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

The game runs smooth until a collision occurs. Please help me!


Solution

  • You can use ListIterator's remove() method.

    Use below code instead of missiles.remove(m);

    iterMissiles.remove();
    

    and same for removing from enemiesLeft.

    while(iterMissiles.hasNext()){
      Missile m = iterMissiles.next();  //current Missile
      if(e.doesIntersect(m)){           
      //remove Enemy from enemiesLeft and add it to enemiesKilled list
      enemiesKilled.add(e);
      iterEnemies.remove();
    
      //remove Missile
      iterMissiles.remove();
      }
    }