I get "IndexOutOfBounds" in my Comets vs Spaceship Game

Liam Andersson :

I began developing a "Spaceship vs Comets" style game last week and now I have come to a stop.

The purpose of the game is to shoot the comets before they pass your ship. You make the comets explode by firing at them. Simple idea!

However, sometimes when I play I get the "IndexOutOfBounds" error. It almost always appears when I haven't fired for a while (The size of my shots ArrayList is 0) and when I then fire and it collides it crashes.

So I have some kind of error in my code, but I really can't see it. I now hope that one of you might see why this accurs and save me from further "IndexOutOfBounds" errors! :)

Here is the part of the code that fails, including the functions that I use to move the comets and shots:

GAME 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();

COMET 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 (Shots are in this 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;
        }
    }
}

Keep in mind that comets and shots are both "ArrayList out of the object Rectangle"

I will provide screenshots of error and a picture of the game below!

Picture of the GUI

Picture of the error in console

The error line is marked in the code above, the if statement should block it from crashing (I thought).

Thanks in advance! All help is appreciated! :)

BrunoLoops :

You should change the order at the if statement to avoid it from evaluate one part of it. You should change your condition to:

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

That's because you're removing a shot and inside the comets for when the shoot is removed at the next comet iteration it will throw IndexOutOfBounds as the array no longer have the shot you're checking at the if, so you'll need to check again for the x existing on shots. You can also do it at the for, you check for both conditions and you let the intersect as only check at the if.

A better performance if would be:

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.
                    }

                }
            }

        }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=237321&siteId=1