嵌套迭代器循环导致碰撞导致 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
}
我有一个游戏,其中坦克发射 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
}