嵌套迭代器循环导致碰撞导致 IllegalStateException

Nested Iterator loops for collision cause IllegalStateException

我有一个游戏,其中坦克发射 shell 弹药。我对这部分代码的目标是检查它们是否与“碰撞”图块发生碰撞,如果是,则将其和图块移除。

代码如下所示,每 1/60 秒检查一次:

Iterator<Shot> iterator = shots.iterator();
        
        while(iterator.hasNext()) {
            
            Shot tempShot = iterator.next();
            tempShot.moveShot();
            
            Iterator<Tile> tileIterator = tiles.iterator();
            while(tileIterator.hasNext()) {
                Tile tile = tileIterator.next();
                if(tile.getHitbox().intersects(tempShot.getHitbox()) && tile.isHardObject()) {
                    tileIterator.remove();
                    iterator.remove();
                }
            }
            
            
            

        }

我以某种方式收到错误:线程“主”中的异常java.lang.IllegalStateException。我预测这是由于 if 语句 而发生的,但我真的不知道如何防止它发生,因为我刚刚了解了 "Iterator"[=41] =] class 做到了。我通过 this

等链接了解了如何编写上面的代码

可视化:

下面的GIF显示了它的样子。子弹击中石头,然后在控制台中打印错误。然而,它应该删除镜头和瓷砖。

我尝试了什么?

如果我删除 "iterator.remove",则不会出现任何错误。瓷砖仍然会消失,但这是由于我在代码中有 "tileIterator.remove()"。只有在取出弹药时才会发生“错误”。这让我相信 if 语句中发生了一些奇怪的事情。另外,有时它似乎有效,有时它不起作用..

堆栈跟踪:

Exception in thread "main" java.lang.IllegalStateException
at java.base/java.util.ArrayList$Itr.remove(ArrayList.java:979)
at com.dubstepzedd.tankgame.entities.Player.fire(Player.java:159)
at com.dubstepzedd.tankgame.entities.Player.tick(Player.java:53)
at com.dubstepzedd.tankgame.Application.tick(Application.java:65)
at com.dubstepzedd.tankgame.GameLoop.loop(GameLoop.java:63)
at com.dubstepzedd.tankgame.GameLoop.run(GameLoop.java:37)
at java.base/java.lang.Thread.run(Thread.java:832)
at com.dubstepzedd.tankgame.GameLoop.main(GameLoop.java:104)

如果您已经删除了该项目,Iterator.remove 方法将抛出此异常。鉴于代码的结构,异常似乎最有可能来自 iterator.remove(),这意味着您已经从 shots 中删除了当前项目并正在尝试再次删除它。

我不知道这段代码应该做什么,但也许跳出内部循环以便您从 shots 继续到下一个项目是正确的。

if (tile.getHitbox().intersects(tempShot.getHitbox()) && tile.isHardObject()) {
    tileIterator.remove();
    iterator.remove();
    break; // get next item from shots iterator
}