pacman can get stuck when turning in a wall
and i keep getting this error message
java.lang.ArrayIndexOutOfBoundsException: 840
at Level.generateLevel(Level.java:91)
at Level.<init>(Level.java:74)
import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot) import java.util.Iterator; /** * * The PacMan Class is for the user to play PacMan. * It has controls to move PacMan with either the arrow * or w,a,s,d keys. * * PacMan will eat the food and Energizer pills when he moves * over them and will die if he touches a Ghost when the Ghost * is normal. If PacMan eats an Energizer pill the Ghosts * will change into their danger behaviour mode, and if PacMan * touches them then they will change into their dead mode. * * PacMan also cannot move across the light blue PacManWall * instances which the Ghosts can. */ public class PacMan extends Actor { // the player's speed private static final int SPEED = 2; // movement types private static final int NONE = 0, // movement is allowed RIGHT = 1, // move right LEFT = 2, // move left DOWN = 3, // move down UP = 4; // move up // frame number private static final int FULL = 3, CLOSED = 2, SEMI_OPEN = 1, OPEN = 0; // if the player is dead or not private boolean dead = false; // the direction the player is moving in // first one to keep track of what the direction is before the control input private int originalDirection = NONE; // second to keep track of the direction inputted by the controls private int moveDirection = NONE; // to check if the mouth should be opening or closing private boolean mouthOpening = true; // the frame to use currently private int frameType = FULL; // animatedImages private GreenfootImage imageFull; private AnimatedImage imageUp; private AnimatedImage imageDown; private AnimatedImage imageLeft; private AnimatedImage imageRight; private AnimatedImage imageDeath; /** * PacMan Constructor * It created all the animated images, * and one for when pacman is a full circle. * * It also sets the image, * and states the frameType to match. */ public PacMan() { imageFull = new GreenfootImage("pacmanFull.png"); imageUp = new AnimatedImage("pacmanAnimUp.png", 3, 16, 16); imageDown = new AnimatedImage("pacmanAnimDown.png", 3, 16, 16); imageLeft = new AnimatedImage("pacmanAnimLeft.png", 3, 16, 16); imageRight = new AnimatedImage("pacmanAnimRight.png", 3, 16, 16); imageDeath = new AnimatedImage("pacmanAnimDeath.png", 7, 16, 16); setImage( imageRight.getFrame(SEMI_OPEN) ); frameType = SEMI_OPEN; Greenfoot.playSound("pacman_intro.wav"); } /** * Method to be run on each frame. * * If the player isn't dead the controls will be taken. * The player will then move in the required direction, * update the player's frame * and check for food, ghosts, cherrys and energizers. * * If the player is dead it will simply run the animation * of dying. */ public void act() { if (!dead) { // make a second reference to the direction of the player originalDirection = moveDirection; controls(); // Move the player. move(SPEED); updateFrame(); // Check for food. checkForFood(); checkForEnergizer(); checkForGhost(); } else { updateFrame(); } } /** * Checks if the key's 'right', 'left', 'up', * 'down', 'w', 'a', 's' of 'd' are pressed, and updates * the movementDirection of the player, so they will * now attempt to move in that direction. */ private void controls() { if ( Greenfoot.isKeyDown("right") || Greenfoot.isKeyDown("D") ) { moveDirection = RIGHT; } else if ( Greenfoot.isKeyDown("left") || Greenfoot.isKeyDown("A") ) { moveDirection = LEFT; } else if ( Greenfoot.isKeyDown("up") || Greenfoot.isKeyDown("W") ) { moveDirection = UP; } else if ( Greenfoot.isKeyDown("down") || Greenfoot.isKeyDown("S") ) { moveDirection = DOWN; } } /** * Works out where the player will move to, then * checks if the player can move there, and if so will * move there. * If they cannot move there it will run again with the * direction from before the controls were taken. * * @param speed the speed the player will travel at */ public void move(int speed) { // get the x and y position of the player int x = getX(); int y = getY(); // change it according to the movement if (moveDirection == RIGHT) { x = x+speed; } else if (moveDirection == LEFT) { x = x-speed; } else if (moveDirection == DOWN) { y = y+speed; } else if (moveDirection == UP) { y = y-speed; } // get the width and height of the world int worldWidth = getWorld().getWidth(); int worldHeight = getWorld().getHeight(); // check if the x co-ordinate is within the world if (x < 0) { x += worldWidth; } else if (x > worldWidth-1) { x -= worldWidth; } // check if the y co-ordinate is within the world if (y < 0) { y += worldHeight; } else if (y > worldHeight-1) { y -= worldHeight; } // unless there is a wall at the next position if (!checkForWall(x,y)) { // if the new direction is different to the previous direction if (moveDirection != originalDirection) { // I change the image to match updateImage(); } // move the player to there setLocation(x, y); } else { // check if the original direction was different to the direction just used if (moveDirection != originalDirection) { // as the player cannot move there, I restore the direction moveDirection = originalDirection; // and move the player in the direction they were travelling in move(speed); } } if(checkForWall(x,y)){ moveDirection = originalDirection; } } /** * Works out which frame should be used. This depends * on if the player is dead, the direction the player is * travelling in and the frame of the image. */ private void updateImage() { // check if the player is dead if (dead) { setImage(imageDeath.getFrame(frameType) ); } // check if the player is a full pacman else if (frameType == FULL) { setImage(imageFull); } // check if the player is moving right else if (moveDirection == RIGHT) { setImage( imageRight.getFrame(frameType) ); } // check if the player is moving left else if (moveDirection == LEFT) { setImage( imageLeft.getFrame(frameType) ); } // check if the player is moving up else if (moveDirection == UP) { setImage( imageUp.getFrame(frameType) ); } // check if the player is moving down else if (moveDirection == DOWN) { setImage( imageDown.getFrame(frameType) ); } } /** * Updates the frame number to be used when drawing. * The frame type will either be counting up or down depending * on if the player's mouth is opening or closing, * unless the player is dead. */ private void updateFrame() { if (dead) { if (frameType < imageDeath.getNumberOfFrames()-1) { frameType++; } else { // end the method return; } } else if (mouthOpening) { if (frameType < FULL) { frameType++; } else { mouthOpening = false; frameType--; } } else { if (frameType > OPEN) { frameType--; } else { mouthOpening = true; frameType++; } } updateImage(); } /** * Checks for a wall and a PacManWall * at the given co-ordinates. * * @param x the x co-ordinate * @param y the y co-ordinate * @return true if there is a wall or PacMan wall, false if not. */ private boolean checkForWall(int x, int y) { int origX = getX(); int origY = getY(); // Finds a wall object at the offset to the player. setLocation(x , y); Actor wall = getOneIntersectingObject( Wall.class ); Actor pacManWall = getOneIntersectingObject( PacManWall.class ); setLocation(origX, origY); return (wall != null || pacManWall != null); } /** * Checks for a Food instance at PacMan's location, * and if there is one the Food will be removed from * the world. */ private void checkForFood() { // Finds a food object in the same tile. Food food = (Food) getOneIntersectingObject(Food.class); // If a food object has been found. if (food != null) { // and removes the food. getWorld().removeObject(food); Greenfoot.playSound("pacman_eat_pellet.wav"); } } /** * Checks for an Energizer instance at PacMan's location, * and if there is one the Energizer will be removed from * the world and the Ghosts will enter their danger behaviour * mode. */ private void checkForEnergizer() { // find the energizer Energizer energizer = (Energizer) getOneIntersectingObject(Energizer.class); if (energizer != null) { Iterator ghostIterator = getWorld().getObjects(Ghost.class).iterator(); while (ghostIterator.hasNext()) { Ghost ghost = (Ghost) ghostIterator.next(); ghost.setDanger(); } getWorld().removeObject(energizer); Greenfoot.playSound("pacman_eat_pellet.wav"); } } /** * Checks for a Ghost instance at PacMan's * current location. If one is found it's current * behaviour state will be checked. * If the Ghost is normal then PacMan will die. * If the Ghost is in danger then the Ghost will * be set to dead behaviour mode. * If the Ghost is dead, nothing will happen. */ private void checkForGhost() { // find a ghost touching pacman Ghost ghost = (Ghost) getOneIntersectingObject(Ghost.class); // check if a ghost is found if (ghost != null) { // check if the ghost is normal if (ghost.isNormal()) { // if so pacman is now dead died(); Greenfoot.playSound("pacman_death.wav"); } // check if the ghost is in danger (if it's blue) else if (ghost.isDanger()) { // in which case the ghost is now dead ghost.setDead(); Greenfoot.playSound("pacman_eat_ghost.wav"); } } } /** * Sets PacMan to be dead, and starts the death * animation. */ public void died() { if (!dead) { dead = true; frameType = -1; } } }