Search code examples
javaarraysindexoutofboundsexception

Trying to convert java if/else to loops


I'm building a Java game as part of my university studies and am trying to convert a large number of if/else statements into loops.

The current, nonworking code is:

    public void kickBall() {
        if(ballDirection == 1) {
            for (int y = 0; y < 15; y++)
            {
                gamePosition[ballPositionX][ballPositionY].setIcon(bg_icon);
                gamePosition[ballPositionX][++ballPositionY].setIcon(ball_icon);
                if(y == baby2PositionY) {
                    gamePosition[ballPositionX][ballPositionY].setIcon(baby2_icon);
                    ballDirection = 2;
                }
            }

Eclipse console log:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 16
    at CBabyBallBounce.kickBall(CBabyBallBounce.java:613)
    at CBabyBallBounce$14.actionPerformed(CBabyBallBounce.java:516)
    at javax.swing.Timer.fireActionPerformed(Unknown Source)
    at javax.swing.Timer$DoPostEvent.run(Unknown Source)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

line 613 indicated is the second gamePosition line, and 516 is the method call, but i'm having trouble understanding what the issue is and how I would rectify it?

previous code if it is useful..

        if (ballPositionY == 1 && ballDirection == 1) {
                gamePosition[ballPositionX][ballPositionY].setIcon(bg_icon);
                gamePosition[ballPositionX][++ballPositionY].setIcon(ball_icon);
            }
            else if(ballPositionY == 2 && ballDirection == 1) {
                gamePosition[ballPositionX][ballPositionY].setIcon(bg_icon);
                gamePosition[ballPositionX][++ballPositionY].setIcon(ball_icon);
            }
etc..

gamePosition code - this is within a 13x16 GridLayout JPanel:

    private JButton gamePosition[][] = new JButton[13][16];
.....

    for (int i=0; i<13; i++)
        for (int j=0; j<16; j++)
        {
            JButton game_display = new JButton(bg_icon);
            game_display.setContentAreaFilled(false);
            game_display.setBorder(null);
            game_display.setFocusable(false);
            gamePosition[i][j] = game_display;
            gamePosition[i][j].setFocusable(false);

            if(j==8)
            {
                gamePosition[i][j].setIcon(wall_icon);
            }
        }

Thanks


Solution

  • There are two problems in your code:

    1. You haven't checked the bounds of the arrays.
    2. You haven't checked for null.

    Do it as follows:

    public void kickBall() {
        if (ballDirection == 1) {
            for (int y = 0; y < 15 && ballPositionX < gamePosition.length
                    && ballPositionY < gamePosition[ballPositionX].length
                    && gamePosition[ballPositionX][ballPositionY] != null; y++) {
                gamePosition[ballPositionX][ballPositionY].setIcon(bg_icon);
                ballPositionY++;
                if (ballPositionY < gamePosition[ballPositionX] && gamePosition[ballPositionX][ballPositionY] != null) {
                    gamePosition[ballPositionX][ballPositionY].setIcon(ball_icon);
                    if (y == baby2PositionY) {
                        gamePosition[ballPositionX][ballPositionY].setIcon(baby2_icon);
                        ballDirection = 2;
                    }
                }
            }
            // ...
        }
        // ...
    }