碰撞检测中的java.util.NoSuchElementException错误

时间:2014-12-06 08:56:28

标签: java iterator collision-detection rectangles nosuchelementexception

我正在开发一款简单光滑的游戏,其中玩家正在拍摄流星体。我有两个图像的碰撞检测问题。我有两个激光器和流星体列表,每个物体都有一个X和Y位置。我想要做的是将当前图像(激光和流星体)的位置实现为两个矩形,以便我可以检查它们是否相互作用,如果它们相互作用,则从两个列表中删除元素。 我的逻辑可能有问题,所以如果有更常见或更合适的方法,请告诉我。

这是碰撞检测方法

public void checkCollision(){           

        ListIterator<Shoot> shootItr = shots.listIterator();
        ListIterator<Meteor> metItr = meteors.listIterator();
        Rectangle2D rectMet;
        Rectangle2D rectSh;

        while(shootItr.hasNext()){
            rectSh = new Rectangle2D.Float(shootItr.next().getBeamPositionX(), shootItr.next().getBeamPositionY(), 10, 10);
            while(metItr.hasNext()){
                rectMet = new Rectangle2D.Float(metItr.next().getMetPositionX(), metItr.next().getMetPositionY(), 20, 20);
                if(rectSh.intersects(rectMet)){
                    metItr.remove();
                    shootItr.remove();
                }

            }
        }
    }

以下是例外:

java.util.NoSuchElementException
    at java.util.ArrayList$Itr.next(Unknown Source)

1 个答案:

答案 0 :(得分:-1)

每次调用next()都会移动迭代器。当你每次迭代只需要一个元素时,两次调用会移动两次。如果您想多次使用它,请缓存该值。

    while(shootItr.hasNext()){
        Shoot shoot = shootItr.next(); // cached
        rectSh = new Rectangle2D.Float(shoot.getBeamPositionX(), shoot.getBeamPositionY(), 10, 10);
        while(metItr.hasNext()){
            Meteor meteor = metItr.next(); // cached
            rectMet = new Rectangle2D.Float(meteor.getMetPositionX(), meteor.getMetPositionY(), 20, 20);
            if(rectSh.intersects(rectMet)){
                metItr.remove();
                shootItr.remove();
                break; // otherwise you'll get IllegalStateException if one shot got into two meteors
            }

        }
    }

请注意,您也可以使用Streams在Java 8的功能样式中执行此操作,尽管这可能对初学者来说太过分了。