Вложенные циклы итератора для возникновения коллизии IllegalStateException - PullRequest
2 голосов
/ 14 июля 2020

У меня есть игра, где танк стреляет снарядом из боеприпасов. Моя цель с этой частью кода - проверить, не сталкиваются ли они с плиткой "столкновения", и, если да, удалить ее вместе с плиткой.

Код выглядит так и проверяется каждые 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();
                }
            }
            
            
            

        }

Я почему-то получаю сообщение об ошибке: Исключение в потоке «main» java .lang.IllegalStateException . Я предполагаю, что это происходит из-за оператора if , но я действительно не знаю, как предотвратить это, поскольку я только что узнал, что сделал класс "Iterator" . Я узнал, как написать приведенный выше код с помощью таких ссылок, как 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)

1 Ответ

2 голосов
/ 14 июля 2020

Метод Iterator.remove вызывает это исключение, если вы уже удалили элемент. Учитывая структуру кода, наиболее вероятно, что исключение произошло из iterator.remove(), что означает, что вы уже удалили текущий элемент из shots и пытаетесь удалить его снова.

Я не делаю ' Я не знаю, что должен делать этот код, но, возможно, вырваться из внутреннего l oop, чтобы перейти к следующему элементу из shots, - это правильно.

if (tile.getHitbox().intersects(tempShot.getHitbox()) && tile.isHardObject()) {
    tileIterator.remove();
    iterator.remove();
    break; // get next item from shots iterator
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...