我正在制作一款基于太空入侵者的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();