我在 Comets vs Spaceship 游戏中获得 "IndexOutOfBounds"

I get "IndexOutOfBounds" in my Comets vs Spaceship Game

我上周开始开发 "Spaceship vs Comets" 风格的游戏,现在我已经停下来了。

游戏的目的是在彗星经过您的飞船之前射击它们。你通过向彗星开火使它们爆炸。简单的想法!

但是,有时我在玩游戏时会遇到 "IndexOutOfBounds" 错误它几乎总是在我有一段时间没有开火时出现(我的镜头 ArrayList 的大小为 0),然后当我开火时它发生碰撞它崩溃了。

所以我的代码中有某种错误,但我真的看不到。我现在希望你们中的任何一个能明白为什么会发生这种情况,并使我免于进一步 "IndexOutOfBounds" 错误! :)

这是失败的代码部分,包括我用来移动彗星和镜头的函数:

游戏CLASS

    if(!Game.player.getShots().isEmpty() && !comet.getComets().isEmpty()) { //Om de är tomma så ignorera

        for(int x = 0; x < Game.player.getShots().size(); x++) {    //Shots X

            if(!comet.getComets().isEmpty() && !comet.getComets().isEmpty()) {



                for(int y = 0; y < comet.getComets().size(); y++) {     //Comets Y

                    if(comet.getComets().get(y).intersects(Game.player.getShots().get(x)) && !comet.getComets().isEmpty() && !Game.player.getShots().isEmpty()) {   
    //the for loop above is the line that won't compile sometimes

                        comet.getComets().remove(y);
                        Game.player.getShots().remove(x);   

                        score++;
                    }

                }
            }

        }
    }

    //Comet spawn timer
    comet.addComets();

    //Move the comets and shots!
    Game.player.moveShots();
    comet.moveComets();
    repaint();

彗星CLASS

public ArrayList<Rectangle> getComets() {

    return comets;
}

public void moveComets() {
    if(!comets.isEmpty()) {

        for(int x = 0; x < comets.size(); x++) {

            comets.get(x).x -= cometSpeed;
        }
    }

}

PLAYER CLASS(投篮在此class)

public void fire() {


    shots.add(new Rectangle(x + player.width, y + 23, shotWidth,shotHeight));
}
public ArrayList<Rectangle> getShots() {

    return shots;

}

public void moveShots() {
    if(!shots.isEmpty()) {
        for(int x = 0; x < shots.size(); x++) {

            shots.get(x).x += fireSpeed;
        }
    }
}

记住彗星和炮弹都是"ArrayList out of the object Rectangle"

我会在下面提供错误截图和游戏图片!

上面代码中标记了错误行,if语句应该可以阻止它崩溃(我认为)。

提前致谢!感谢所有帮助! :)

这里尝试调整if(!comet.getComets().isEmpty() && !comet.getComets().isEmpty())。您正在检查彗星阵列两次。

如果有效请告诉我。

您应该更改 if 语句的顺序以避免它计算其中的一部分。 您应该将您的条件更改为:

if( x < Game.player.getShots().size() && comet.getComets().get(y).intersects(Game.player.getShots().get(x))) {

那是因为你正在删除一个镜头并且在彗星内部,因为当在下一次彗星迭代中删除镜头时它会抛出 IndexOutOfBounds 因为阵列不再有你​​正在检查的镜头如果,那么您需要再次检查镜头中是否存在 x。 您也可以在 for 处执行此操作,检查两个条件并让相交仅在 if 处检查。

更好的表现是:

if(!Game.player.getShots().isEmpty() || !comet.getComets().isEmpty()) { 
//if one of them is empty, won't be intersections

        for(int x = 0; x < Game.player.getShots().size(); x++) {    //Shots X
                for(int y = 0; y < comet.getComets().size() && x < Game.player.getShots().size(); y++) {
 //Comets Y only if the shoot still available

                    if(comet.getComets().get(y).intersects(Game.player.getShots().get(x))) {   
    //the for loop above is the line that won't compile sometimes

                        comet.getComets().remove(y);
                        Game.player.getShots().remove(x);   

                        score++;
                        y = 0; // if you don't set the y = 0 the next shoot (as you removed the x, getShots.get(x) would be the x + 1 shoot) will only evaluate for the comets after y, won't evaluate the firsts comets at the array.
                    }

                }
            }

        }

这段代码是多线程的吗? 我也想知道你为什么要验证comet.getComets().isEmpty()那么多次

我的猜测是您在代码的其他部分操纵了 ArrayList。我认为这是因为您多次检查列表的大小,并且因为在 for 循环中您最后只是删除,所以这不应该是问题所在。

例如,如果您 运行 同时在两个线程中使用此方法,则可以在某一点检查 ArrayList,但在检查大小后可以减少。然后当例如大小为 10,但变成 9,但你仍然尝试删除值为 10 的 x,你将得到越界错误。