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)


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | 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 ; } } } |