I have a game where a tank shoots shell of ammunition. My goal with this part of the code is to check if they collide with a "collision" tile and if so remove it and the tile.
The code looks like this and is checked every 1/60 of a second:
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();
}
}
}
I somehow get the error: Exception in thread "main" java.lang.IllegalStateException. I predict this is happening due to the if statement but I don't really know how to prevent it from happening as I just learnt what the "Iterator" class did. I found out how to write the code above through links such as this
Visualisation:
The GIF below displays how it looks like. The shot hits the stone and it then prints the error in the console. It should however remove the shot and the tile.
What have I tried?
If I remove "iterator.remove" it will result in no errors. The tiles will disappear still, but that is due to me having "tileIterator.remove()" in the code. Only when removing the ammo does the "error" happen. This makes me believe that there is something weird going on inside that if statement. Also, sometimes it seems to work and sometimes it doesn't..
Stack trace:
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)
The Iterator.remove
method throws this exception if you have already removed the item. Given the structure of the code, it seems most likely that the exception came from iterator.remove()
, meaning you've already removed the current item from shots
and are trying to remove it again.
I don't know what this code is supposed to do, but perhaps breaking out of the inner loop so that you move on to the next item from shots
is the right thing.
if (tile.getHitbox().intersects(tempShot.getHitbox()) && tile.isHardObject()) {
tileIterator.remove();
iterator.remove();
break; // get next item from shots iterator
}