出于某种原因,我查看过很多帖子,但我仍然不知道如何解决这个问题。 在我的游戏的更新方法中,我有一个for循环来更新所有现有的GameObjects。
private static void update() {
for (GameObject g : GameObjectManager.getGameObjects()) {
g.update();
}
canvas.repaint();
}
它说for循环的行有一个ConcurrentModificationException错误。 像某些人说的那样,我试过要获取游戏对象列表的迭代器然后使用它,但它仍然无法正常工作。 即使它说错误行是在for循环,当我删除g.update时,没有更多的错误。 编辑:我发现了错误。它将游戏对象添加到GameObjectManager.registerGameObject()中的列表中。 使用此更新的唯一其他类是:
public class PaintCanvas extends JPanel {
private static final long serialVersionUID = 6718161148154673832L;
{
this.setDoubleBuffered(true);
this.setVisible(true);
}
@Override
public void paint(Graphics g) {
g.setColor(Color.RED);
for (GameObject go : GameObjectManager.getGameObjects()) {
g.fillRect(go.getPosition().getX(), go.getPosition().getY(), 30, 30);
}
}
}
唯一的更新方法是:
@Override
public void update() {
Random r = new Random();
int spawn = r.nextInt(100);
// 5% Chance to spawn
if (spawn <= 5) {
Spawner s = new Spawner();
s.setPosition(new Point(4, 50));
}
}
答案 0 :(得分:2)
迭代时无法修改列表。您的游戏对象的一个更新方法必须是添加或删除项目。
您可以迭代副本:
for (GameObject g : new ArrayList(GameObjectManager.getGameObjects())) {
g.update();
}
或者使用普通for循环,这里的对象可以安全添加,但不能删除:
List<GameObject> objects = GameObjectManager.getGameObjects();
int size = objects.size();
for(int i = 0; i < size; i++) {
GameObject g = objects.get(i);
g.update();
}
或者修复GameObjectManager.registerGameObject()
以添加到临时列表,而不是主列表,并将它们移到现有代码之前的主列表中。删除也可以这样做。
GameObjectManager.promoteNewGameObjects(); //promote objects added in the last frame
for (GameObject g : GameObjectManager.getGameObjects()) {
g.update(); //as before
}
答案 1 :(得分:2)
在这种情况下,当某些东西试图修改数组而其他东西正在使用它时(迭代它等),将抛出此异常。就像,一个新怪物在地图上产生并添加到一些怪物列表中,而游戏循环当前正在迭代所述列表。在 GameObjectManager 类中,您使用什么来存储 GameObject ?如果它是普通列表,您应该考虑将其更改为CopyOnWriteArrayList或任何其他线程安全列表,它应该可以解决问题。