-3

I'm creating a pacman game, and I'm getting an exception that I can't figure out:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -11
at p.PacBoard.moveGhosts(PacBoard.java:207)

And here is where the logic of my game is (I marked off the line that has thrown the exception):

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class PacBoard extends JPanel implements ActionListener {

Dimension d;
String s = "Press s to start.";;
Font small = new Font("Helvetica", Font.BOLD, 14);
FontMetrics metr = this.getFontMetrics(small);

Image ii;
Color dotcolor = new Color(192, 192, 0);
Color mazecolor;

boolean ingame = false;
boolean dying = false;

final int blocksize = 24;
final int nrofblocks = 15;
final int scrsize = nrofblocks * blocksize;
final int pacanimdelay = 2;
final int pacmananimcount = 4;
final int maxghosts = 6;
final int pacmanspeed = 6;

int pacanimcount = pacanimdelay;
int pacanimdir = 1;
int pacmananimpos = 0;
int nrofghosts = 4;
int pacsleft, score;
int deathcounter;
int[] dx, dy;
int[] ghostx, ghosty, ghostdx, ghostdy, ghostspeed;

Image ghost;
Image pacman1, pacman2up, pacman2left, pacman2right, pacman2down;
Image pacman3up, pacman3down, pacman3left, pacman3right;
Image pacman4up, pacman4down, pacman4left, pacman4right;

int pacmanx, pacmany, pacmandx, pacmandy;
int reqdx, reqdy, viewdx, viewdy;

final short leveldata[] =
{ 3, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 22, 3, 10, 6,
  1, 25, 24, 16, 16, 16, 16, 16, 16, 16, 16, 20, 5, 15, 5,
  1, 0, 0, 17, 16, 16, 16, 16, 16, 16, 16, 20, 9, 10, 12, 
  19, 18, 18, 16, 16, 16, 24, 16, 24, 16, 16, 24, 18, 18, 22,
  17, 16, 16, 16, 16, 28, 0, 21, 0, 17, 20, 0, 17, 16, 20,
  17, 16, 16, 16, 28, 0, 19, 20, 0, 25, 28, 0, 17, 16, 20,
  17, 16, 16, 28, 0, 19, 16, 20, 0, 0, 0, 0, 17, 16, 20,
  17, 16, 20, 0, 27, 16, 16, 16, 18, 18, 22, 0, 17, 16, 20,
  17, 16, 16, 22, 0, 25, 16, 16, 16, 16, 20, 0, 17, 16, 20,
  17, 16, 16, 16, 22, 0, 25, 16, 16, 16, 20, 0, 17, 16, 20,
  17, 16, 16, 16, 16, 22, 0, 17, 16, 16, 20, 0, 17, 16, 20,
  25, 16, 24, 16, 16, 16, 18, 16, 16, 16, 16, 18, 24, 24, 28,
  1, 21, 0, 17, 16, 16, 16, 16, 16, 16, 16, 20, 0, 8, 12,
  9, 29, 0, 17, 16, 16, 16, 16, 16, 16, 16, 20, 0, 10, 14,
  9, 15, 27, 24, 24, 24, 24, 24, 24, 24, 24, 28, 8, 10, 14};

final int validspeeds[] = {1, 2, 3, 4, 5, 6};
final int maxspeed = 6;

int currentspeed = 3;
short[] screendata;
Timer timer;


public PacBoard() {

    GetImages();

    addKeyListener(new TAdapter());

    screendata = new short[nrofblocks * nrofblocks];
    mazecolor = new Color(255, 0, 5);
    setFocusable(true);

    d = new Dimension(400, 400);

    setBackground(Color.black);
    setDoubleBuffered(true);

    ghostx = new int[maxghosts];
    ghostdx = new int[maxghosts];
    ghosty = new int[maxghosts];
    ghostdy = new int[maxghosts];
    ghostspeed = new int[maxghosts];
    dx = new int[4];
    dy = new int[4];
    timer = new Timer(40, this);
    timer.start();
}

public void addNotify() {
    super.addNotify();
    GameInit();
}


public void DoAnim() {
    pacanimcount--;
    if (pacanimcount <= 0) {
        pacanimcount = pacanimdelay;
        pacmananimpos = pacmananimpos + pacanimdir;
        if (pacmananimpos == (pacmananimcount - 1) || pacmananimpos == 0)
            pacanimdir = -pacanimdir;
    }
}


public void PlayGame(Graphics2D g2d) {
    if (dying) {
        Death();
    } else {
        MovePacMan();
        DrawPacMan(g2d);
        moveGhosts(g2d);
        CheckMaze();
    }
}


public void ShowIntroScreen(Graphics2D g2d) {

    g2d.setColor(new Color(0, 32, 48));
    g2d.fillRect(50, scrsize / 2 - 30, scrsize - 100, 50);
    g2d.setColor(Color.white);
    g2d.drawRect(50, scrsize / 2 - 30, scrsize - 100, 50);
    g2d.setColor(Color.white);
    g2d.setFont(small);
    g2d.drawString(s, (scrsize - metr.stringWidth(s)) / 2, scrsize / 2);
}


public void DrawScore(Graphics2D g) {
    int i;
    String s;

    g.setFont(small);
    g.setColor(new Color(96, 128, 255));
    s = "Score: " + score;
    g.drawString(s, scrsize / 2 + 96, scrsize + 16);
    for (i = 0; i < pacsleft; i++) {
        g.drawImage(pacman3left, i * 28 + 8, scrsize + 1, this);
    }
}


public void CheckMaze() {
    short i = 0;
    boolean finished = true;

    while (i < nrofblocks * nrofblocks && finished) {
        if ((screendata[i] & 48) != 0)
            finished = false;
        i++;
    }

    if (finished) {
        score += 50;

        if (nrofghosts < maxghosts)
            nrofghosts++;
        if (currentspeed < maxspeed)
            currentspeed++;
        LevelInit();
    }
}

public void Death() {

    pacsleft--;
    if (pacsleft == 0)
        ingame = false;
    LevelContinue();
}


public void moveGhosts(Graphics2D g2d) {
    short i;
    int pos;
    int count;

    for (i = 0; i < nrofghosts; i++) {
        if (ghostx[i] % blocksize == 0 && ghosty[i] % blocksize == 0) {
            pos = ghostx[i] / blocksize + nrofblocks * (int)(ghosty[i] / blocksize);

            count = 0;
//line that causes problems below
            if ((screendata[pos] & 1) == 0 && ghostdx[i] != 1) {
//line that causes problems above
                dx[count] = -1;
                dy[count] = 0;
                count++;
            }
            if ((screendata[pos] & 2) == 0 && ghostdy[i] != 1) {
                dx[count] = 0;
                dy[count] = -1;
                count++;
            }
            if ((screendata[pos] & 4) == 0 && ghostdx[i] != -1) {
                dx[count] = 1;
                dy[count] = 0;
                count++;
            }
            if ((screendata[pos] & 8) == 0 && ghostdy[i] != -1) {
                dx[count] = 0;
                dy[count] = 1;
                count++;
            }

            if (count == 0) {
                if ((screendata[pos] & 15) == 15) {
                    ghostdx[i] = 0;
                    ghostdy[i] = 0;
                } else {
                    ghostdx[i] = -ghostdx[i];
                    ghostdy[i] = -ghostdy[i];
                }
            } else {
                count = (int)(Math.random() * count);
                if (count > 3)
                    count = 3;
                ghostdx[i] = dx[count];
                ghostdy[i] = dy[count];
            }

        }
        ghostx[i] = ghostx[i] + (ghostdx[i] * ghostspeed[i]);
        ghosty[i] = ghosty[i] + (ghostdy[i] * ghostspeed[i]);
        DrawGhost(g2d, ghostx[i] + 1, ghosty[i] + 1);

        if (pacmanx > (ghostx[i] - 12) && pacmanx < (ghostx[i] + 12) &&
            pacmany > (ghosty[i] - 12) && pacmany < (ghosty[i] + 12) &&
            ingame) {

            dying = true;
            deathcounter = 64;

        }
    }
}


public void DrawGhost(Graphics2D g2d, int x, int y) {
    g2d.drawImage(ghost, x, y, this);
}


public void MovePacMan() {
    int pos;
    short ch;

    if (reqdx == -pacmandx && reqdy == -pacmandy) {
        pacmandx = reqdx;
        pacmandy = reqdy;
        viewdx = pacmandx;
        viewdy = pacmandy;
    }
    if (pacmanx % blocksize == 0 && pacmany % blocksize == 0) {
        pos = pacmanx / blocksize + nrofblocks * (int)(pacmany / blocksize);
        ch = screendata[pos];

        if ((ch & 16) != 0) {
            screendata[pos] = (short)(ch & 15);
            score++;
        }

        if (reqdx != 0 || reqdy != 0) {
            if (!((reqdx == -1 && reqdy == 0 && (ch & 1) != 0) ||
                  (reqdx == 1 && reqdy == 0 && (ch & 4) != 0) ||
                  (reqdx == 0 && reqdy == -1 && (ch & 2) != 0) ||
                  (reqdx == 0 && reqdy == 1 && (ch & 8) != 0))) {
                pacmandx = reqdx;
                pacmandy = reqdy;
                viewdx = pacmandx;
                viewdy = pacmandy;
            }
        }

        // Check for standstill
        if ((pacmandx == -1 && pacmandy == 0 && (ch & 1) != 0) ||
            (pacmandx == 1 && pacmandy == 0 && (ch & 4) != 0) ||
            (pacmandx == 0 && pacmandy == -1 && (ch & 2) != 0) ||
            (pacmandx == 0 && pacmandy == 1 && (ch & 8) != 0)) {
            pacmandx = 0;
            pacmandy = 0;
        }
    }
    pacmanx = pacmanx + pacmanspeed * pacmandx;
    pacmany = pacmany + pacmanspeed * pacmandy;
}


public void DrawPacMan(Graphics2D g2d) {
    if (viewdx == -1)
        DrawPacManLeft(g2d);
    else if (viewdx == 1)
        DrawPacManRight(g2d);
    else if (viewdy == -1)
        DrawPacManUp(g2d);
    else
        DrawPacManDown(g2d);
}

public void DrawPacManUp(Graphics2D g2d) {
    switch (pacmananimpos) {
    case 1:
        g2d.drawImage(pacman2up, pacmanx + 1, pacmany + 1, this);
        break;
    case 2:
        g2d.drawImage(pacman3up, pacmanx + 1, pacmany + 1, this);
        break;
    case 3:
        g2d.drawImage(pacman4up, pacmanx + 1, pacmany + 1, this);
        break;
    default:
        g2d.drawImage(pacman1, pacmanx + 1, pacmany + 1, this);
        break;
    }
}


public void DrawPacManDown(Graphics2D g2d) {
    switch (pacmananimpos) {
    case 1:
        g2d.drawImage(pacman2down, pacmanx + 1, pacmany + 1, this);
        break;
    case 2:
        g2d.drawImage(pacman3down, pacmanx + 1, pacmany + 1, this);
        break;
    case 3:
        g2d.drawImage(pacman4down, pacmanx + 1, pacmany + 1, this);
        break;
    default:
        g2d.drawImage(pacman1, pacmanx + 1, pacmany + 1, this);
        break;
    }
}


public void DrawPacManLeft(Graphics2D g2d) {
    switch (pacmananimpos) {
    case 1:
        g2d.drawImage(pacman2left, pacmanx + 1, pacmany + 1, this);
        break;
    case 2:
        g2d.drawImage(pacman3left, pacmanx + 1, pacmany + 1, this);
        break;
    case 3:
        g2d.drawImage(pacman4left, pacmanx + 1, pacmany + 1, this);
        break;
    default:
        g2d.drawImage(pacman1, pacmanx + 1, pacmany + 1, this);
        break;
    }
}


public void DrawPacManRight(Graphics2D g2d) {
    switch (pacmananimpos) {
    case 1:
        g2d.drawImage(pacman2right, pacmanx + 1, pacmany + 1, this);
        break;
    case 2:
        g2d.drawImage(pacman3right, pacmanx + 1, pacmany + 1, this);
        break;
    case 3:
        g2d.drawImage(pacman4right, pacmanx + 1, pacmany + 1, this);
        break;
    default:
        g2d.drawImage(pacman1, pacmanx + 1, pacmany + 1, this);
        break;
    }
}


public void DrawMaze(Graphics2D g2d) {
    short i = 0;
    int x, y;

    for (y = 0; y < scrsize; y += blocksize) {
        for (x = 0; x < scrsize; x += blocksize) {
            g2d.setColor(mazecolor);
            g2d.setStroke(new BasicStroke(2));

            if ((screendata[i] & 1) != 0) // draws left
            {
                g2d.drawLine(x, y, x, y + blocksize - 1);
            }
            if ((screendata[i] & 2) != 0) // draws top
            {
                g2d.drawLine(x, y, x + blocksize - 1, y);
            }
            if ((screendata[i] & 4) != 0) // draws right
            {
                g2d.drawLine(x + blocksize - 1, y, x + blocksize - 1,
                             y + blocksize - 1);
            }
            if ((screendata[i] & 8) != 0) // draws bottom
            {
                g2d.drawLine(x, y + blocksize - 1, x + blocksize - 1,
                             y + blocksize - 1);
            }
            if ((screendata[i] & 16) != 0) // draws point
            {
                g2d.setColor(dotcolor);
                g2d.fillRect(x + 11, y + 11, 2, 2);
            }
            i++;
        }
    }
}

public void GameInit() {
    pacsleft = 3;
    score = 0;
    LevelInit();
    nrofghosts = 4;
    currentspeed = 3;
}


public void LevelInit() {
    int i;
    for (i = 0; i < nrofblocks * nrofblocks; i++)
        screendata[i] = leveldata[i];

    LevelContinue();
}


public void LevelContinue() {
    short i;
    int dx = 1;
    int random;

    for (i = 0; i < nrofghosts; i++) {
        ghosty[i] = 4 * blocksize;
        ghostx[i] = 4 * blocksize;
        ghostdy[i] = 0;
        ghostdx[i] = dx;
        dx = -dx;
        random = (int)(Math.random() * (currentspeed + 1));
        if (random > currentspeed)
            random = currentspeed;
        ghostspeed[i] = validspeeds[random];
    }

    pacmanx = 7 * blocksize;
    pacmany = 11 * blocksize;
    pacmandx = 0;
    pacmandy = 0;
    reqdx = 0;
    reqdy = 0;
    viewdx = -1;
    viewdy = 0;
    dying = false;
}

public void GetImages()
{

  ghost = new ImageIcon(PacBoard.class.getResource("../pacpix/ghost.gif")).getImage();
  pacman1 = new ImageIcon(PacBoard.class.getResource("../pacpix/pacman.png")).getImage();
  pacman2up = new ImageIcon(PacBoard.class.getResource("../pacpix/up1.png")).getImage();
  pacman3up = new ImageIcon(PacBoard.class.getResource("../pacpix/up2.png")).getImage();
  pacman4up = new ImageIcon(PacBoard.class.getResource("../pacpix/up3.png")).getImage();
  pacman2down = new ImageIcon(PacBoard.class.getResource("../pacpix/down1.png")).getImage();
  pacman3down = new ImageIcon(PacBoard.class.getResource("../pacpix/down2.png")).getImage(); 
  pacman4down = new ImageIcon(PacBoard.class.getResource("../pacpix/down3.png")).getImage();
  pacman2left = new ImageIcon(PacBoard.class.getResource("../pacpix/left1.png")).getImage();
  pacman3left = new ImageIcon(PacBoard.class.getResource("../pacpix/left2.png")).getImage();
  pacman4left = new ImageIcon(PacBoard.class.getResource("../pacpix/left3.png")).getImage();
  pacman2right = new ImageIcon(PacBoard.class.getResource("../pacpix/right1.png")).getImage();
  pacman3right = new ImageIcon(PacBoard.class.getResource("../pacpix/right2.png")).getImage();
  pacman4right = new ImageIcon(PacBoard.class.getResource("../pacpix/right3.png")).getImage();

}

public void paint(Graphics g)
{
  super.paint(g);

  Graphics2D g2d = (Graphics2D) g;

  g2d.setColor(Color.black);
  g2d.fillRect(0, 0, d.width, d.height);

  DrawMaze(g2d);
  DrawScore(g2d);
  DoAnim();
  if (ingame){
    PlayGame(g2d);
  }
  else{
    ShowIntroScreen(g2d);
  }

  g.drawImage(ii, 5, 5, this);
  Toolkit.getDefaultToolkit().sync();
  g.dispose();
}

class TAdapter extends KeyAdapter {
    public void keyPressed(KeyEvent e) {

      int key = e.getKeyCode();

      if (ingame)
      {
        if (key == KeyEvent.VK_LEFT)
        {
          reqdx=-1;
          reqdy=0;
        }
        else if (key == KeyEvent.VK_RIGHT)
        {
          reqdx=1;
          reqdy=0;
        }
        else if (key == KeyEvent.VK_UP)
        {
          reqdx=0;
          reqdy=-1;
        }
        else if (key == KeyEvent.VK_DOWN)
        {
          reqdx=0;
          reqdy=1;
        }
        else if (key == KeyEvent.VK_ESCAPE && timer.isRunning())
        {
          ingame=false;
        }
        else if (key == KeyEvent.VK_PAUSE) {
            if (timer.isRunning())
                timer.stop();
            else timer.start();
        }
      }
      else
      {
        if (key == 's' || key == 'S')
      {
          ingame=true;
          GameInit();
        }
      }
  }

      public void keyReleased(KeyEvent e) {
          int key = e.getKeyCode();

          if (key == Event.LEFT || key == Event.RIGHT || 
             key == Event.UP ||  key == Event.DOWN)
          {
            reqdx=0;
            reqdy=0;
          }
      }
  }

public void actionPerformed(ActionEvent e) {
    repaint();  
}
}

Sorry I know that's a lot of code but I'm not sure where the problem is being created. Here is the line that it is being caught at:

if ((screendata[pos] & 1) == 0 && ghostdx[i] != 1) {

I know it has to be increasing or decreasing the size of the array to an illegal number, but where? And why? That's what I don't understand. Oh, and I got the exception in my output window about 10 times, not sure why though. Would this mean it's getting increased in one of my for loops?

Thanks to anyone who will help, and I will provide more information as needed.

To compile:

import javax.swing.JFrame;


public class Pacman extends JFrame
{

  public Pacman()
  {
    add(new PacBoard());
    setTitle("Pacman");
    setSize(380, 420);
    setLocationRelativeTo(null);
    setVisible(true);
  }

  public static void main(String[] args) {
        new Pacman();
  }
}
CodeAddict
  • 194
  • 2
  • 5
  • 19
  • 2
    `pos` or `i` is greater than one of the array length (`screendata` or `ghostdx` respectively). Please **debug** your code in order to find the error and think on a solution. – Luiggi Mendoza Mar 19 '13 at 22:36
  • I don't think it's `i` because it is set to always be less than `nrofghosts`. Must be `pos` then but that doesn't make sense. – CodeAddict Mar 19 '13 at 22:39
  • 2
    The index out of bounds is *shown* in the exception: it's negative. It must be pos which is miscalculated, since i is just an increasing counter. – Frank Pavageau Mar 19 '13 at 22:41
  • Pos is calculated here: pos = ghostx[i] / blocksize + nrofblocks * (int)(ghosty[i] / blocksize); Which means, that ghostx[i], or ghosty[i] will need to be negative, if pos is negative. (The rest are just max size specifiers) – Georges Oates Larsen Mar 19 '13 at 22:45
  • 1
    Again, **please debug your code** in order to search which variable breaks your program and then think on a solution. – Luiggi Mendoza Mar 19 '13 at 22:50
  • The problem is the ghost is moving to a negative coordinate, in most cases -11, if that has any significance. no number should ever be negative, but for some reason pos is turning negative. Oh, and it only happens in round 2, so boolean `finished` turns true, and then false. Of course, this could all be moot, I have no clue. Just trying to trigger a solution. – CodeAddict Mar 19 '13 at 22:53
  • @LuiggiMendoza, I know which line and variable is causing the problem, and when, I just don't know why. What else do you think I should do to debug? – CodeAddict Mar 19 '13 at 22:54
  • @CodeAddict Do you know how to debug? and what IDE you are using? If you are using eclispe [Eclipse Debugging Tutorials](http://www.comscigate.com/debug/learn_Debug.htm) – Smit Mar 19 '13 at 22:55
  • When debugging, you will find the cause of the problem and then search for the root cause of the problem (what you haven't done yet). In this problem, a cause of the cause is that `pos` contains negative value or is bigger than `screendata.length` (similar for `i` and `ghostdx`), now you should review your code/debug **why this happens**. – Luiggi Mendoza Mar 19 '13 at 22:57
  • CodeAddict, what you describe sounds like exactly what my answer explains -- Have a look, and please let me know what the line about dx = -dx; does. That way we can replace it with something that works better and doesn't make pos negative. If you'd like anything I said explained better (I was in a rush, sorry!) please let me know – Georges Oates Larsen Mar 19 '13 at 23:00
  • @LuiggiMendoza, I believe so, the way I debug (on Netbeans btw) is use `System.out.print` to show the values of variables as they are used throughout the program. Is that right or should I be doing something different? – CodeAddict Mar 19 '13 at 23:03
  • That's one way. AFAIK NetBeans has a window where it displays the variables and their values for local vars, parameters, class instance attributes, etc. – Luiggi Mendoza Mar 19 '13 at 23:04
  • After reading all the code slowly, I guess the problem is when calculating `pos` value, it looks like your formula doesn't give you the right results leading to a value bigger than `screendata.length` (what means @FrankPavageau was right from the beginning). – Luiggi Mendoza Mar 19 '13 at 23:44

2 Answers2

1

I think I know (with the help of other commenters) where your problem is:

We have deduced that either ghostx[i] is negative, or ghosty[i] is negative.

Notice here that you set dx to one, and then set ghostx[i] to dx. The problem arises when you set dx to be the negative of dx (dx = -dx;) This means that on the next iteration, dx is negative, and therefore out of bounds.

(It is out of bounds, because pos is calculated based on ghostx[i]. And ghostx[i] is calculated based on dx. If dx is negative, so will ghostx[i] be, and so will pos, causing big problems)

I am not sure what you were trying to do here, but definitely change this line and see if it fixes your problems. Leave a comment with what dx = -dx; is supposed to do, and I'll help you figure it out.

Code which is the culprit:

public void LevelContinue() {
    short i;
    int dx = 1;
    int random;

    for (i = 0; i < nrofghosts; i++) {
        ghosty[i] = 4 * blocksize;
        ghostx[i] = 4 * blocksize;
        ghostdy[i] = 0;
        ghostdx[i] = dx;



        dx = -dx;//Line which kills your code



        random = (int)(Math.random() * (currentspeed + 1));
        if (random > currentspeed)
            random = currentspeed;
        ghostspeed[i] = validspeeds[random];
    }

To sum it all up, the code I posted above (particularly the "Line which kills your code") sets ghosty[i] to a negative. It will only do this at odd indexes (ghostx[0], and ghostx[2] will be positive, but [1] (which is the index you have stated having issues with) will be negative.

Later down the line, this bit of code here:

pos = ghostx[i] / blocksize + nrofblocks * (int)(ghosty[i] / blocksize);

uses ghostx[] in a division, causing the whole thing to become negative.

You then, at the line of code you stated to be bad, use screendata[pos], which results in you using a negative index.


EDIT: New answer proposal.

Now, the only lines of code I have found so far that modify ghostx or ghosty are:

ghostx[i] = ghostx[i] + (ghostdx[i] * ghostspeed[i]);
ghosty[i] = ghosty[i] + (ghostdy[i] * ghostspeed[i]);

and

 ghosty[i] = 4 * blocksize;
 ghostx[i] = 4 * blocksize;

We know the latter of the two can't be it, because blocksize and 4 are both positive.

That means that

ghostx[i] = ghostx[i] + (ghostdx[i] * ghostspeed[i]);
ghosty[i] = ghosty[i] + (ghostdy[i] * ghostspeed[i]);

are the problem.

Looking at this, it appears to me that your ghosts are wandering outside your board! I noticed that ghostdx can be negative (ghostdx being ghost delta x right?) This means that when your ghost is traveling in the negative direction, it ends up going so far that it ends up going outside the board.

Right after those lines, I suggest adding these lines:

if (ghostx[i] < 0) ghostx[i] = 0;
if (ghosty[i] < 0) ghosty[i] = 0;
if (ghostx[i] >= WHATEVER_YOUR_MAX_POSITION_IS) ghostx[i] = WHATEVER_YOUR_MAX_POSITION_IS - 1;
if (ghosty[i] >= WHATEVER_YOUR_MAX_POSITION_IS) ghosty[i] = WHATEVER_YOUR_MAX_POSITION_IS - 1;

See if that fixes your problems please!

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Georges Oates Larsen
  • 6,812
  • 12
  • 51
  • 67
  • I don't understand how a negative element of an array can turn into an `ArrayIndexOutOfBoundsException`. – Luiggi Mendoza Mar 19 '13 at 22:51
  • Well think of it this way, the indexes of an array go from zero to the length of the array minus one. If the index is negative, then you are accessing an element from BEFORE the array starts (causing that index to be outside the range of valid indexes) Because the index is outside the range of valid indexes, it is out of bounds. – Georges Oates Larsen Mar 19 '13 at 22:53
  • @LuiggiMendoza Because that element is used to compute an index (pos, used in screendata[pos]). – Frank Pavageau Mar 19 '13 at 22:54
  • You're talking about array index and I don't see `dx` nor `ghostdx[i]` with negative value as index of any array in your answer (note: I haven't read all the boilerplate code in OP's question). – Luiggi Mendoza Mar 19 '13 at 22:54
  • @Luiggi Mendoza, see the for loop in my answer? That's where the code is -- See how that for loop sets dx to be negative dx at the line that I marked as "Line which kills your code"? And do you see how the next time the for loop gets called, it will set ghostdx[i] to dx? Because of that, ghostdx[i] will be negative, because dx was negative. Later in his program, he uses ghostdx[i] to calculate an index in the array "screendata" Because ghostdx has a negative value, the index he calculates will (at some point) be negative too – Georges Oates Larsen Mar 19 '13 at 22:56
  • As I've said, I haven't read the whole code (and I can bet lot of people won't do either), so you should post in which part of the code OP uses `ghostdx[i]` as index thus generating the exception. – Luiggi Mendoza Mar 19 '13 at 23:01
  • I misread your comments sorry. The part of the code is here: pos = ghostx[i] / blocksize + nrofblocks * (int)(ghosty[i] / blocksize); Blocksize and nrofblocks are both positive. That means for pos to be negative (which we know from comments that pos IS negative) ghostx[i] or ghosty[i] must be negative. I found a part of code that set ghostx[i] to negative, so I suspect that is where the negative is coming from. I will add this to my post above. – Georges Oates Larsen Mar 19 '13 at 23:04
  • Care to add that last piece of info in your answer instead of comment? – Luiggi Mendoza Mar 19 '13 at 23:04
  • Sure! I even said that I would :) It just takes time to write these things, you know. – Georges Oates Larsen Mar 19 '13 at 23:08
  • First I would like to point out that I'm a girl, just fyi. And as for `dx = -dx`, when I took it out it didn't fix the problem. In fact it didn't alter the outcome at all. – CodeAddict Mar 19 '13 at 23:13
  • @CodeAddict Sorry for calling you a He, and, also, sorry for my confusion -- I just realized I completely misread `ghostdx[i] = dx;` for `ghostx[i] = dx;` – Georges Oates Larsen Mar 19 '13 at 23:14
  • I will keep looking for why ghostx or ghosty are negative – Georges Oates Larsen Mar 19 '13 at 23:14
  • Alright, CodeAddict, I think I found it... Updating my answer – Georges Oates Larsen Mar 19 '13 at 23:16
  • @CodeAddict nice to know a girl that wants to learn programming (like lot of people here). Still, boy or girl, there are [rules](http://stackoverflow.com/faq#howtoask) that applies to everyone in case of asking questions. Please change your code in form of [SSCCE](http://sscce.org) so people could help you (instead of downvoting). – Luiggi Mendoza Mar 19 '13 at 23:19
  • I thought my code would compile, it should just be copy and paste (minus the pictures of course) I'm new to programming, I'm mostly self taught and I'm nowhere near being a master. Also I'm young so I have a long ways to go, but this is definitely what I wan to do. (and I'm new to the site and how things go round here) Thanks for the advice! – CodeAddict Mar 19 '13 at 23:22
  • @CodeAddict I've tried to copy/paste your code in Eclipse and it compiles but I don't know how to make it run. I'm no Java Desktop developer so I would like to know how to test your code in order to provide some help. – Luiggi Mendoza Mar 19 '13 at 23:25
  • @CodeAddict No worries! You'd have better success if you try to isolate the problem more, but this is one of your first questions... I've updated my answer in light of what you have said and in light of my idiotic fumbles – Georges Oates Larsen Mar 19 '13 at 23:26
  • I don't understand how you can try to give an answer without even testing it =\. Also, you should not completely erase an answer content just to post a new content, instead add the new *proposed* solution and mark the first as obsolete **or** post a new answer. – Luiggi Mendoza Mar 19 '13 at 23:27
  • @Luiggi the point is to keep trying ideas until one works. I'm doing the best I can since I can't compile the code myself. As for my old answer, it was idiotic, and almost completely invalid, I'd prefer to remove it to avoid confusion – Georges Oates Larsen Mar 19 '13 at 23:29
  • In this context, *keep trying ideas until one works* is more like a blind that tries to guide another blind through the darkness =\. – Luiggi Mendoza Mar 19 '13 at 23:30
  • @LuiggiMendoza I think we got off on the wrong foot here, truce? As for the validity of my method, I don't have much of a choice either way – Georges Oates Larsen Mar 19 '13 at 23:31
  • Then don't post an answer at all. – Luiggi Mendoza Mar 19 '13 at 23:32
  • Progress! Although the ghost commits suicide (goes off the screen) I'm okay with that, because there's no red error lines :) if I have another problem I'll post another question (hopefully correctly) and go from there. Thanks Georges and Luiggi for your help! – CodeAddict Mar 19 '13 at 23:32
  • @CodeAddict you're welcome (I guess). – Luiggi Mendoza Mar 19 '13 at 23:33
  • @CodeAddict Glad I could have helped! This is why we keep trying, Luiggi -- We WILL find an answer eventually. – Georges Oates Larsen Mar 19 '13 at 23:33
  • Luiggi, theres another class that actually runs the program (it has the main method) I can post it if you would like. And I like the try until one works method, thank you Georges :) – CodeAddict Mar 19 '13 at 23:33
  • 1
    @CodeAddict Happy to help! Have fun playing pac-man :D – Georges Oates Larsen Mar 19 '13 at 23:35
  • @CodeAddict I'm not complaining about *try until it works*, I'm complaining about *try whatever you may think it could solve the problem until it magically disappears* which leads to an unprofessional answer (IMO). – Luiggi Mendoza Mar 19 '13 at 23:39
  • @LuiggiMendoza While there is some truth in that (and there is) the important distinction is that my guesses were not uneducated -- simply wrong. I misread a few lines the first few times I tried. I got to it eventually though. Think of it like the process of elimination – Georges Oates Larsen Mar 19 '13 at 23:41
  • this isn't a professional assignment :) but I see where you're coming from. but it is only for fun :) – CodeAddict Mar 19 '13 at 23:41
  • 1
    @GeorgesOatesLarsen, I did `WHATEVER_YOUR_MAX_POSITION_IS - 2` instead of 1, so they don't get stuck. Solved! – CodeAddict Mar 19 '13 at 23:47
  • @CodeAddict Ahh, good thinking! Glad you got it solved :D – Georges Oates Larsen Mar 19 '13 at 23:48
  • @LuiggiMendoza I see what you mean now about having the original answer in there -- Thanks for adding it back in! – Georges Oates Larsen Mar 19 '13 at 23:56
0

pos = pacmanx / blocksize + nrofblocks * (int)(pacmany / blocksize);

make sure your assignd value cannot be > nrofblocks*nrofblocks, also make sure that your divisor is allways > 0, as far as i remember in java you can devide by zero but this will result in NaN , pos[NaN] is obviously out of bounds.. ah but i dont think this makes sense for int , which is your variable pos.

Iam just providing some thoughts i would check first, its too late to crunch the numbers, sorry ;)

Btw, why not use vectors for the coordinates ? should be much easier

Jalatiphra
  • 248
  • 1
  • 10
  • *why not use vectors* I guess you meant `List` backed up with `ArrayList` instead of `Vector`. Refer to [Why is Java Vector class considered obsolete or deprecated?](http://stackoverflow.com/q/1386275/1065197) and [What does it mean to “program to an interface”?](http://stackoverflow.com/q/383947/1065197). – Luiggi Mendoza Mar 19 '13 at 22:49