Java游戏与LinkedList的碰撞检测崩溃



我正在制作一款基于太空入侵者的2D java游戏。在我的游戏课上,我有以下3个字段:

//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>();

在我的checkCollision()方法中,我遍历enemiesLeft列表中的每个Enemy,并检查是否与missiles列表中的每一个Missile发生冲突,但它抛出了一个ConcurrentModificationException

以下是checkCollision()方法:

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();
}

这就是我得到的错误:

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)

游戏运行平稳,直到发生碰撞。请帮帮我!

您可以使用ListIterator的remove()方法。

使用以下代码代替missiles.remove(m);

iterMissiles.remove();

并且对于从CCD_ 10中去除也是如此。

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();
  }
}

不能更改正在迭代的列表:

enemiesKilled.add(enemiesLeft.remove(enemiesLeft.indexOf(e)));

应该是:

iterEnimies.remove();
enemiesKilled.add(e);

问题就在这里:

 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);
      }

当对missiles进行迭代时,您尝试从它中删除项。它抛出java.util.ConcurrentModificationException

missiles:上迭代之前添加新列表

LinkedList<Missile> missilesForRemove = new LinkedList<Missile>();

并将m变量添加到此列表中,在while循环之后,从原始missiles列表中删除此missilesForRemove

missiles.removeAll(missilesForRemove);

问题在于在对列表进行迭代时对其进行修改。如果您想进行修改,则不允许在对其进行迭代时更改列表。

保存要删除的实例,然后在(伪代码):之后删除它们

ArrayList<Item> ItemsToRemove = new ArrayList<Item>();
for(Item item : allItems){
  if(shouldItemBeRemoved(item)){
    ItemsToRemove.add(item)
  }
}
//Remove the items for the allItems list
for(Item item : itemToRemove){
  allItems.remove(item);
}

或者使用迭代器删除项目:

iterMissiles.remove();

最新更新