我正在制作一个基于太空入侵者的2D java游戏。在我的Game课程中,我有以下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()
方法中,我浏览了Enemy
列表中的每个enemiesLeft
,并检查了与Missile
列表中每个missiles
的冲突,但是抛出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)
游戏顺利进行,直到发生碰撞。 请帮帮我!
答案 0 :(得分:5)
您可以使用ListIterator的remove()
方法。
使用以下代码代替missiles.remove(m);
iterMissiles.remove();
和从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();
}
}
答案 1 :(得分:0)
问题在于在迭代时修改列表。如果要修改,则在迭代时不允许更改列表。
保存要删除的实例,然后在(伪代码)后删除它们:
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();
答案 2 :(得分:0)
有人可能不会改变正在迭代的列表:
enemiesKilled.add(enemiesLeft.remove(enemiesLeft.indexOf(e)));
应该是:
iterEnimies.remove();
enemiesKilled.add(e);
答案 3 :(得分:0)
问题出在这里:
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循环中从原始missilesForRemove
列表中删除此missiles
:
missiles.removeAll(missilesForRemove);