Search code examples
javaswing2d-games

Space Invaders ArrayList IndexOutOfBoundsException


Okey, I've searched for this error and found out that the cause is probably that my update of the Arraylist is somehow conflicting with my repaint() method. I have changed my code many times trying to fix it but either I can't compile or I end up with the exact same error. I am creating Space Invaders and the game runs fine until I shoot to fast (ie. tap the UP button to fast) and this error comes up: (NB:the x in "Index: x, Size: x" is not always 1 it has ranged from 1 to 6)

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at Board.checkCollisions(Board.java:185)
at Board.actionPerformed(Board.java:172)
at javax.swing.Timer.fireActionPerformed(Timer.java:312)
at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Here is the part of the code that seems to cause the problem.

        public void actionPerformed(ActionEvent e){
    if(enemies.size() == 0){
        ingame = false;
    }

    ArrayList ss = gun.getShots();

    for(int i = 0; i < ss.size(); i++){
        Shot s = (Shot) ss.get(i);
        if(s.isVisible()){
            s.move();
        }
        else{
            ss.remove(i);
        }
    }

    for(int i = 0; i < enemies.size(); i++){
        Enemy en = (Enemy) enemies.get(i);
        if(en.isVisible()){
            en.move();
        }
        else{
            enemies.remove(i);
        }
    }

    for(int i = 0; i < bunkers.size(); i++){
        Bunker b = (Bunker) bunkers.get(i);
        if(b.isVisible() == false){
            bunkers.remove(i);
        }
    }

    gun.move();
    checkCollisions();
    repaint();
}

public void checkCollisions(){

    ArrayList ss = gun.getShots();

    for(int i = 0; i < ss.size(); i++){
        Shot s = (Shot) ss.get(i);
        Rectangle r1 = s.getBounds();
        //Collision for Enemies
        for(int j = 0; j < enemies.size(); j++){
            Enemy en = (Enemy) enemies.get(i);
            Rectangle r2 = en.getBounds();

            if(r1.intersects(r2)){
                s.setVisible(false);
                en.setVisible(false);
            }
        }
        //Collision for Bunker
        for(int j = 0; j < bunkers.size(); j++){
            Bunker b = (Bunker) bunkers.get(i);
            Rectangle r2 = b.getBounds();

            if(r1.intersects(r2)){
                s.setVisible(false);
                b.setVisible(false);
                score++;
            }
        }

    }
}

More specifically these lines of code:

checkCollisions();
Enemy en = (Enemy) enemies.get(i);

and sometimes

checkCollisions();
Bunker b = (Bunker) bunkers.get(i);

Also there is another problem. For some reason when I shoot the aliens or when I shoot at the bunker I always have to shoot the one that is first in the ArrayList for it too disappear. If I shoot the others first nothing happens, the shot just flies through them. This is not my primary concern so I understand if you do not want to waste time explaining that to me. Thanks in advance.


Solution

  • I guess that these two snippets are the problem:

        for(int j = 0; j < enemies.size(); j++){
            Enemy en = (Enemy) enemies.get(i);
    
    
        for(int j = 0; j < bunkers.size(); j++){
            Bunker b = (Bunker) bunkers.get(i);
    

    You iterate with j, but you use i in the getter.