Mario.java (62720B)
1 2 /* Copyright (c) Mary Percival 2003 */ 3 /* Mario game Created May 2003 */ 4 5 import java.awt.Color; 6 import java.awt.Image; 7 import java.awt.Point; 8 import java.awt.event.KeyEvent; 9 import java.awt.event.KeyListener; 10 11 import javax.swing.JFrame; 12 13 public class Mario extends JFrame implements KeyListener, Runnable { 14 private static final long serialVersionUID = 7030451342808203557L; 15 boolean easymode = true; 16 static int MAXLEVEL = 9; 17 static int level = 0; 18 19 // the levels so far are: 20 // 1 beginner level: 1 piranha & 1 goomba 21 // 2 introducing green koopa 22 // 3 more of the same 23 // 4 introducing red koopa (flying) 24 // 5 more and harder 25 // 6 ? 26 // 7 ? 27 // 8 ? 28 // 9 ? 29 30 static int LEFT = 1; 31 static int RIGHT = 0; 32 // the next 2 constants are overridden in init once we know the screen size 33 static int RIGHTEDGE = 789; 34 static int BOTTOMEDGE = 800; 35 static int PAGEWIDTH = 741; 36 37 static Point IMAGESIZE = new Point(152, 107); 38 static final int LEFTEDGE = -45; 39 static final int TOPEDGE = -10; 40 static int GROUNDLEVEL = 503; 41 static int startPosY; 42 static int JUMPAMOUNT = 90; 43 static int BOUNCEAMOUNT = 90; 44 static final int FALLAMOUNT = 16; // amount he falls each time interval 45 static final int RISEAMOUNT = 16; // amount he rises each time interval 46 static final int XAMOUNT = 12; 47 48 static final int X = 1; 49 static final int Y = 2; 50 static final int NOT = 3; 51 static final int DELAY = 50; 52 53 static final int OBSTACLEIMAGES = 19; 54 static final int HEROIMAGES = 4; 55 static final int ENEMYIMAGES = 3; 56 57 // ---------------------------------------------------------------------------------------------- 58 // ENEMY TYPES 59 // ---------------------------------------------------------------------------------------------- 60 static final int ENEMYTYPES = 15; // goomba, koopa red, koopa green, koopa red flying, banzai, wiggler, boo, 61 // fireboo,bobomb,warship,yeti,chainchomp,atom 62 static final int GOOMBA = 0; 63 static final int KOOPARED = 1; 64 static final int KOOPAGREEN = 2; 65 static final int KOOPAREDFLYING = 3; 66 static final int BANZAI = 4; 67 static final int WIGGLER = 5; 68 static final int BOO = 6; 69 static final int FIREBOO = 7; 70 static final int BOBOMB = 8; 71 static final int BULLET = 9; 72 static final int WARSHIP = 10; 73 static final int YETI = 11; 74 static final int FLYER = 12; 75 static final int CHOMP = 13; 76 static final int ATOM = 14; 77 78 // enemy positions (height) 79 static final int GOOMBAHEIGHT = GROUNDLEVEL + 55; 80 static final int KOOPAREDHEIGHT = GROUNDLEVEL + 39; 81 static final int KOOPAGREENHEIGHT = GROUNDLEVEL + 39; 82 static final int KOOPAREDFLYINGHEIGHT = GROUNDLEVEL - 16; 83 static final int BANZAIHEIGHT = GROUNDLEVEL - 90; 84 static final int WIGGLERHEIGHT = GROUNDLEVEL + 16; 85 static final int BOOHEIGHT = GROUNDLEVEL - 7; 86 static final int FIREBOOHEIGHT = GROUNDLEVEL - 7; 87 static final int BOBOMBHEIGHT = GROUNDLEVEL + 5; 88 static final int BULLETHEIGHT = GROUNDLEVEL + 55; 89 static final int WARSHIPHEIGHT = GROUNDLEVEL + 100; 90 static final int YETIHEIGHT = GROUNDLEVEL; 91 static final int FLYERHEIGHT = GROUNDLEVEL - 20; 92 static final int CHOMPHEIGHT = GROUNDLEVEL - 55; 93 static final int ATOMHEIGHT = GROUNDLEVEL + 40; 94 static int enemyHeight[] = new int[ENEMYTYPES]; 95 96 static final int enemySize[] = { 27, 42, 42, 42, 172, 75, 37, 37, 74, 8, 152, 86, 86, 75, 25 }; 97 static final int enemyTopSpace[] = { 4, 13, 13, 0, 0, 10, 6, 6, 7, 0, 20, 8, 17, 10, 0 }; 98 99 static final int SPACE_FROM_X_TO_MARIO = 55; 100 static final int MARIOHEIGHT = 86; 101 static final int MARIOOFFSET = 21; 102 static final int MARIOCROUCHOFFSET = 39; 103 static final int MARIOSTANDINGSIZE = 65; 104 static final int MARIOCROUCHINGSIZE = 45; 105 106 static final int JUMPDURATION = 5; 107 static final int SUPERJUMPDURATION = 8; 108 static final int MARIOLEFTOFOBSTACLE = 45; // fudge factor because Mario image is diff size to obstacle image 109 static final int MARIORIGHTOFOBSTACLE = 10; // fudge factor because Mario image is diff size to obstacle image 110 static final int ENEMYLEFTOFOBSTACLE = 16; // fudge factor for enemy images 111 static final int ENEMYRIGHTOFOBSTACLE = 49; // >49 causes panic! 112 static final int MARIOLEFTOFENEMY = 73; 113 static final int MARIORIGHTOFENEMY = -23; 114 115 static final int LEFTDOWN = 0; 116 static final int RIGHTDOWN = 1; 117 static final int DOWNDOWN = 2; 118 static final int SPACEDOWN = 3; 119 120 static final int OBSTACLEHEIGHT = 42; 121 static final int TALLOBSTACLEDIFF = 28; 122 static final int OBSTACLEWIDTH = 86; 123 static int GROUNDDIFF = 605 - GROUNDLEVEL; 124 125 // all member variables 'static' because shared with the enemy action thread 126 static MarioArea area; 127 static Thread timer; 128 static boolean finished = false; 129 static boolean ingame = false; 130 static boolean juststarted = true; 131 static Point warpzone; 132 static int[] keysdown = new int[4]; 133 static Point[] enemyPositions; 134 static Point playerPosition; 135 static Point[] obstaclePositions; 136 static boolean[] piranhaPopping; // one for each obstacle 137 static boolean[] hasPiranha; // one for each obstacle 138 static boolean[] isTall; // one for each obstacle 139 static int enemyDirection[]; 140 static int enemyNumber = 1, enemiesRemaining = 1, obstacleNumber = 1; 141 static boolean herocrouching = false; 142 static boolean onTheWayUp = false; 143 static boolean bouncing = false; 144 static boolean wasbouncing = false; 145 static boolean dead = false; 146 static int page = 0; 147 static int heroImageNo = 0; 148 static int enemyImageNo[]; 149 static int levellength = 1482; 150 static Image[] heroImages = new Image[HEROIMAGES]; 151 static Image[] obstacleImages = new Image[OBSTACLEIMAGES]; // pipe, piranhapeep, piranha peepy etc 152 static Image[] squished = new Image[ENEMYTYPES]; // squished images for each enemy type 153 static Image[][][] enemyImages = new Image[ENEMYTYPES][2][ENEMYIMAGES]; // left right left right or whatever 154 static int obstacleImageNo[]; // what is the current image for obstacle n 155 static Image[][] enemyImage = new Image[ENEMYTYPES][ENEMYIMAGES];// what is the current image for enemy n? 156 static Image floors[] = new Image[MAXLEVEL]; 157 static int enemyType[]; // what is the type of enemy n? 158 static boolean enemyDead[]; // is enemy n dead? 159 static boolean heroleft = false; 160 static boolean jumping = false; 161 static int enemyMove[] = new int[ENEMYTYPES]; 162 boolean somethingChangedSinceRepaint = false; 163 164 // ************************************************************* 165 public static void main(String[] args) { 166 Mario mario = new Mario(); 167 mario.setLayout(null); 168 mario.setBackground(Color.white); 169 mario.setSize(RIGHTEDGE, BOTTOMEDGE); 170 mario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 171 mario.setTitle("Mario"); 172 area = new MarioArea(mario); 173 mario.add(area); 174 //RIGHTEDGE = (Mario.getBounds().width / XAMOUNT) * XAMOUNT + LEFTEDGE; 175 //BOTTOMEDGE = Mario.getBounds().height - 1; 176 mario.setVisible(true); 177 area.setBounds(0, 0, RIGHTEDGE, BOTTOMEDGE); 178 //GROUNDLEVEL = Mario.getBounds().height - GROUNDDIFF; 179 //GROUNDLEVEL = BOTTOMEDGE;// - GROUNDDIFF; 180 startPosY = GROUNDLEVEL; 181 //MarioArea.FLOORLEVEL = Mario.getBounds().height - MarioArea.FLOORDIFF; 182 area.setVisible(true); 183 184 mario.addKeyListener(mario); 185 area.addKeyListener(mario); 186 area.requestFocus(); 187 188 obstacleImages[0] = area.obstacle; 189 obstacleImages[1] = area.obstacle; 190 obstacleImages[2] = area.obstacle; 191 obstacleImages[3] = area.obstacle; 192 obstacleImages[4] = area.piranhapeepo; 193 obstacleImages[5] = area.piranhapeep; 194 obstacleImages[6] = area.piranhapeepy; 195 obstacleImages[7] = area.piranha1; 196 obstacleImages[8] = area.piranha1; 197 obstacleImages[9] = area.piranha1; 198 obstacleImages[10] = area.piranha2; // 199 obstacleImages[11] = area.piranha2; // 200 obstacleImages[12] = area.piranha2; // 201 obstacleImages[13] = area.piranhapeepy; // 202 obstacleImages[14] = area.piranhapeep; // 203 obstacleImages[15] = area.piranhapeepo; 204 obstacleImages[16] = area.obstacle; // 205 obstacleImages[17] = area.obstacle; // 206 obstacleImages[18] = area.obstacle; // 207 208 enemyImages[GOOMBA][RIGHT][0] = area.goomba; 209 enemyImages[GOOMBA][RIGHT][1] = area.goomba2; 210 enemyImages[GOOMBA][LEFT][0] = area.goombaleft; 211 enemyImages[GOOMBA][LEFT][1] = area.goomba2left; 212 213 enemyImages[KOOPARED][RIGHT][0] = area.kooparedleft; 214 enemyImages[KOOPARED][RIGHT][1] = area.kooparedleft; 215 enemyImages[KOOPARED][LEFT][0] = area.koopared; 216 enemyImages[KOOPARED][LEFT][1] = area.koopared; 217 218 enemyImages[KOOPAGREEN][RIGHT][0] = area.koopagreen; 219 enemyImages[KOOPAGREEN][RIGHT][1] = area.koopagreen; 220 enemyImages[KOOPAGREEN][LEFT][0] = area.koopagreenleft; 221 enemyImages[KOOPAGREEN][LEFT][1] = area.koopagreenleft; 222 223 enemyImages[KOOPAREDFLYING][RIGHT][0] = area.kooparedfleft; 224 enemyImages[KOOPAREDFLYING][RIGHT][1] = area.kooparedfleft; 225 enemyImages[KOOPAREDFLYING][LEFT][0] = area.kooparedf; 226 enemyImages[KOOPAREDFLYING][LEFT][1] = area.kooparedf; 227 228 enemyImages[BANZAI][RIGHT][0] = area.Banzai; 229 enemyImages[BANZAI][RIGHT][1] = area.Banzai; 230 enemyImages[BANZAI][LEFT][0] = area.Banzai; 231 enemyImages[BANZAI][LEFT][1] = area.Banzai; 232 233 enemyImages[WIGGLER][RIGHT][0] = area.Wiglerright; 234 enemyImages[WIGGLER][RIGHT][1] = area.Wiglerright1; 235 enemyImages[WIGGLER][RIGHT][2] = area.Wiglerright2; 236 enemyImages[WIGGLER][LEFT][0] = area.Wiglerleft; 237 enemyImages[WIGGLER][LEFT][1] = area.Wiglerleft1; 238 enemyImages[WIGGLER][LEFT][2] = area.Wiglerleft2; 239 240 enemyImages[BOO][RIGHT][0] = area.Boo2; 241 enemyImages[BOO][RIGHT][1] = area.Boo2; 242 enemyImages[BOO][LEFT][0] = area.Boo1; 243 enemyImages[BOO][LEFT][1] = area.Boo1; 244 245 enemyImages[FIREBOO][RIGHT][0] = area.Fireboo2; 246 enemyImages[FIREBOO][RIGHT][1] = area.Fireboo2; 247 enemyImages[FIREBOO][LEFT][0] = area.Fireboo1; 248 enemyImages[FIREBOO][LEFT][1] = area.Fireboo1; 249 250 enemyImages[BOBOMB][LEFT][0] = area.Bobomb; 251 enemyImages[BOBOMB][LEFT][1] = area.Bobomb2; 252 enemyImages[BOBOMB][RIGHT][0] = area.Bobombf; 253 enemyImages[BOBOMB][RIGHT][1] = area.Bobombf2; 254 255 enemyImages[BULLET][LEFT][0] = area.Bullet; 256 enemyImages[BULLET][LEFT][1] = area.Bullet; 257 enemyImages[BULLET][RIGHT][0] = area.Bullet; 258 enemyImages[BULLET][RIGHT][1] = area.Bullet; 259 260 enemyImages[WARSHIP][LEFT][0] = area.Warship1; 261 enemyImages[WARSHIP][LEFT][1] = area.Warship2; 262 enemyImages[WARSHIP][RIGHT][0] = area.Warship1; 263 enemyImages[WARSHIP][RIGHT][1] = area.Warship2; 264 265 enemyImages[YETI][LEFT][0] = area.Yetil1; 266 enemyImages[YETI][LEFT][1] = area.Yetil2; 267 enemyImages[YETI][RIGHT][0] = area.Yetir1; 268 enemyImages[YETI][RIGHT][1] = area.Yetir2; 269 270 enemyImages[FLYER][LEFT][0] = area.p1fl; 271 enemyImages[FLYER][LEFT][1] = area.p2fl; 272 enemyImages[FLYER][RIGHT][0] = area.p1fr; 273 enemyImages[FLYER][RIGHT][1] = area.p2fr; 274 275 enemyImages[CHOMP][LEFT][0] = area.chainchomp1; 276 enemyImages[CHOMP][LEFT][1] = area.chainchomp2; 277 enemyImages[CHOMP][RIGHT][0] = area.chainchomp1; 278 enemyImages[CHOMP][RIGHT][1] = area.chainchomp2; 279 280 enemyImages[ATOM][LEFT][0] = area.Atom1; 281 enemyImages[ATOM][LEFT][1] = area.Atom2; 282 enemyImages[ATOM][RIGHT][0] = area.Atom1; 283 enemyImages[ATOM][RIGHT][1] = area.Atom2; 284 285 enemyMove[GOOMBA] = 5; 286 enemyMove[KOOPARED] = 5; 287 enemyMove[KOOPAGREEN] = 5; 288 enemyMove[KOOPAREDFLYING] = 8; 289 enemyMove[BANZAI] = 16; 290 enemyMove[WIGGLER] = 15; 291 enemyMove[BOO] = 5; 292 enemyMove[FIREBOO] = 10; 293 enemyMove[BOBOMB] = 5; 294 enemyMove[BULLET] = 10; 295 enemyMove[WARSHIP] = 20; 296 enemyMove[YETI] = 5; 297 enemyMove[FLYER] = 10; 298 enemyMove[CHOMP] = 0; 299 enemyMove[ATOM] = 1; 300 301 enemyHeight[GOOMBA] = 40; 302 enemyHeight[KOOPARED] = 33; 303 enemyHeight[KOOPAGREEN] = 33; 304 enemyHeight[KOOPAREDFLYING] = 33; 305 enemyHeight[BANZAI] = 60; 306 enemyHeight[WIGGLER] = 33; 307 enemyHeight[BOO] = 33; 308 enemyHeight[FIREBOO] = 33; 309 enemyHeight[BOBOMB] = 33; 310 enemyHeight[BULLET] = 5; 311 enemyHeight[WARSHIP] = 50; 312 enemyHeight[YETI] = 33; 313 enemyHeight[FLYER] = 50; 314 enemyHeight[CHOMP] = 60; 315 enemyHeight[ATOM] = 22; 316 317 squished[GOOMBA] = area.squishedgoomba; 318 squished[KOOPARED] = area.redshell; 319 squished[KOOPAGREEN] = area.greenshell; 320 squished[KOOPAREDFLYING] = area.koopared; 321 squished[BANZAI] = area.Banzai; // not actually used 322 squished[WIGGLER] = area.Wiglerleft; // not actually used 323 squished[BOO] = area.Boo1; 324 squished[FIREBOO] = area.Fireboo1; 325 squished[BOBOMB] = area.Bobomb; 326 squished[BULLET] = area.Bullet; 327 squished[WARSHIP] = area.Warship2; 328 squished[YETI] = area.Yetil1; 329 squished[FLYER] = area.p1fl; 330 squished[CHOMP] = area.chainchompdead; 331 squished[ATOM] = area.Atom1; 332 333 for (int i = 0; i < MAXLEVEL; i++) { 334 floors[i] = area.floor4; 335 } 336 337 floors[0] = area.floor4; 338 floors[1] = area.floor5; 339 floors[2] = area.floor3; 340 floors[3] = area.floor7; 341 floors[4] = area.floor8; 342 floors[5] = area.floor9; 343 floors[6] = area.floor2; 344 floors[7] = area.floor6; 345 floors[8] = area.Floor10; 346 347 timer = new Thread(mario); 348 timer.start(); 349 350 } 351 352 synchronized void faceRight() { 353 heroImages[0] = area.herostand; 354 heroImages[1] = area.hero1; 355 heroImages[2] = area.herostand; 356 heroImages[3] = area.hero2; 357 heroImageNo = 0; 358 heroleft = false; 359 } 360 361 synchronized void faceLeft() { 362 heroImages[0] = area.herostandleft; 363 heroImages[1] = area.hero1left; 364 heroImages[2] = area.herostandleft; 365 heroImages[3] = area.hero2left; 366 heroImageNo = 0; 367 heroleft = true; 368 } 369 370 synchronized void enemyFaceRight(int enemyno) { 371 enemyImage[enemyno][0] = enemyImages[enemyType[enemyno]][RIGHT][0]; 372 enemyImage[enemyno][1] = enemyImages[enemyType[enemyno]][RIGHT][1]; 373 if (enemyType[enemyno] == WIGGLER) 374 enemyImage[enemyno][2] = enemyImages[enemyType[enemyno]][RIGHT][2]; 375 enemyDirection[enemyno] = RIGHT; 376 } 377 378 synchronized void enemyFaceLeft(int enemyno) { 379 enemyImage[enemyno][0] = enemyImages[enemyType[enemyno]][LEFT][0]; 380 enemyImage[enemyno][1] = enemyImages[enemyType[enemyno]][LEFT][1]; 381 if (enemyType[enemyno] == WIGGLER) 382 enemyImage[enemyno][2] = enemyImages[enemyType[enemyno]][LEFT][2]; 383 enemyDirection[enemyno] = LEFT; 384 } 385 386 synchronized void enemyDie(int enemyno) { 387 // displayStatus(); 388 enemyImage[enemyno][0] = squished[enemyType[enemyno]]; 389 enemyImage[enemyno][1] = squished[enemyType[enemyno]]; 390 if (enemyType[enemyno] == WIGGLER) 391 enemyImage[enemyno][2] = squished[enemyType[enemyno]]; 392 } 393 394 synchronized void standStill() { 395 heroImageNo = 0; 396 } 397 398 public void doLevel(int level) { 399 // this runs one 'level' 400 juststarted = true; 401 dead = false; 402 403 // position Hero at the bottom left 404 playerPosition = new Point(LEFTEDGE, GROUNDLEVEL); 405 faceRight(); 406 407 // *********** THIS STUFF DEPENDS WHAT LEVEL YOU ARE ON ************ 408 switch (level) { 409 case 1: 410 obstacleNumber = 4; // 4 pipes for level 1 411 enemyNumber = 1; 412 levellength = 1482; // 2 pages 413 break; 414 case 2: 415 obstacleNumber = 11; 416 enemyNumber = 5; 417 levellength = 2964; // 4 pages 418 break; 419 case 3: 420 obstacleNumber = 13; 421 enemyNumber = 8; 422 levellength = 2223; // 3 pages 423 break; 424 case 4: 425 obstacleNumber = 11; 426 enemyNumber = 12; 427 levellength = 4446; // 6 pages 428 break; 429 case 5: 430 obstacleNumber = 17; 431 enemyNumber = 13; 432 levellength = 5928; // 8 pages 433 break; 434 case 6: 435 obstacleNumber = 14; 436 enemyNumber = 1; 437 levellength = 5928; // 8 pages 438 break; 439 case 7: 440 obstacleNumber = 14; 441 enemyNumber = 6; 442 levellength = 3705; // 5 pages 443 break; 444 case 8: 445 obstacleNumber = 16; 446 enemyNumber = 9; 447 levellength = 5928; // 8 pages 448 break; 449 case 9: 450 obstacleNumber = 6; 451 enemyNumber = 9; 452 levellength = 3705; // 5 pages 453 break; 454 case 10: 455 obstacleNumber = 29; 456 enemyNumber = 0; 457 levellength = 4446; // 6 pages 458 default: 459 System.out.println("Level " + level + " has not yet been implemented"); 460 } 461 462 enemyImage = new Image[enemyNumber][ENEMYIMAGES];// what is the current image for enemy n? 463 // initialise piranha states 464 obstacleImageNo = new int[obstacleNumber]; 465 hasPiranha = new boolean[obstacleNumber]; 466 piranhaPopping = new boolean[obstacleNumber]; 467 isTall = new boolean[obstacleNumber]; 468 469 // initialise the arrays of enemies, etc 470 enemyPositions = new Point[enemyNumber]; 471 enemyType = new int[enemyNumber]; 472 enemyDead = new boolean[enemyNumber]; 473 obstaclePositions = new Point[obstacleNumber]; 474 enemyDirection = new int[enemyNumber]; 475 enemyImageNo = new int[enemyNumber]; 476 477 for (int i = 0; i < enemyNumber; i++) { 478 enemyImageNo[i] = 0; 479 } 480 481 switch (level) { 482 // --------------------------------- 483 // LEVEL 1 484 // --------------------------------- 485 case 1: 486 for (int i = 0; i < obstacleNumber; i++) { 487 isTall[i] = false; 488 if (i == 0) { 489 piranhaPopping[i] = true; 490 hasPiranha[i] = true; 491 } else { 492 if (i == 3) 493 isTall[i] = true; 494 piranhaPopping[i] = false; 495 hasPiranha[i] = false; 496 } 497 } 498 obstaclePositions[0] = new Point(400, GROUNDLEVEL); 499 obstaclePositions[1] = new Point(950, GROUNDLEVEL); 500 obstaclePositions[2] = new Point(1245, GROUNDLEVEL); // 1255 for adjacent 501 obstaclePositions[3] = new Point(1320, GROUNDLEVEL); 502 503 enemyPositions[0] = new Point(1000, GOOMBAHEIGHT); 504 enemyType = new int[] { GOOMBA }; 505 break; 506 // ----------------------------------------------- 507 // LEVEL 2 508 // ----------------------------------------------- 509 case 2: 510 for (int i = 0; i < obstacleNumber; i++) { 511 isTall[i] = false; 512 if (i == 2 || i == 7 || i == 8) { 513 piranhaPopping[i] = true; 514 hasPiranha[i] = true; 515 } else { 516 if (i == 4 || i == 6 || i == 10) 517 isTall[i] = true; 518 piranhaPopping[i] = false; 519 hasPiranha[i] = false; 520 } 521 } 522 523 // PAGE 1 524 obstaclePositions[0] = new Point(150, GROUNDLEVEL); 525 obstaclePositions[1] = new Point(225, GROUNDLEVEL); 526 obstaclePositions[2] = new Point(300, GROUNDLEVEL); 527 // PAGE 2 528 obstaclePositions[3] = new Point(891, GROUNDLEVEL); 529 obstaclePositions[4] = new Point(966, GROUNDLEVEL); 530 // PAGE 3 531 obstaclePositions[5] = new Point(1632, GROUNDLEVEL); 532 obstaclePositions[6] = new Point(1707, GROUNDLEVEL); 533 obstaclePositions[7] = new Point(1782, GROUNDLEVEL); 534 // PAGE 4 535 obstaclePositions[8] = new Point(2373, GROUNDLEVEL); 536 obstaclePositions[9] = new Point(2743, GROUNDLEVEL); 537 obstaclePositions[10] = new Point(2818, GROUNDLEVEL); 538 539 enemyType = new int[] { KOOPAGREEN, GOOMBA, GOOMBA, GOOMBA, GOOMBA }; 540 enemyPositions[0] = new Point(375, KOOPAGREENHEIGHT); 541 enemyPositions[1] = new Point(1041, GOOMBAHEIGHT); 542 enemyPositions[2] = new Point(1141, GOOMBAHEIGHT); 543 enemyPositions[3] = new Point(1882, GOOMBAHEIGHT); 544 enemyPositions[4] = new Point(2473, GOOMBAHEIGHT); 545 break; 546 // ----------------------------------------------- 547 // LEVEL 3 548 // ----------------------------------------------- 549 case 3: 550 for (int i = 0; i < obstacleNumber; i++) { 551 isTall[i] = false; 552 if (i == 4) 553 isTall[i] = true; 554 if (i != 4 && i != 11 && i != 12) { 555 piranhaPopping[i] = true; 556 hasPiranha[i] = true; 557 } else { 558 piranhaPopping[i] = false; 559 hasPiranha[i] = false; 560 } 561 } 562 // PAGE 1 563 obstaclePositions[0] = new Point(50, GROUNDLEVEL); 564 obstaclePositions[1] = new Point(130, GROUNDLEVEL); 565 obstaclePositions[2] = new Point(210, GROUNDLEVEL); 566 567 obstaclePositions[3] = new Point(540, GROUNDLEVEL); 568 obstaclePositions[4] = new Point(620, GROUNDLEVEL); 569 obstaclePositions[5] = new Point(700, GROUNDLEVEL); 570 // PAGE 2 571 obstaclePositions[6] = new Point(850, GROUNDLEVEL); 572 obstaclePositions[7] = new Point(925, GROUNDLEVEL); 573 obstaclePositions[8] = new Point(1000, GROUNDLEVEL); 574 obstaclePositions[9] = new Point(1075, GROUNDLEVEL); 575 obstaclePositions[10] = new Point(1150, GROUNDLEVEL); 576 obstaclePositions[11] = new Point(1350, GROUNDLEVEL); 577 578 // PAGE 3 579 obstaclePositions[12] = new Point(2000, GROUNDLEVEL); 580 581 enemyType = new int[] { KOOPAGREEN, GOOMBA, GOOMBA, GOOMBA, GOOMBA, GOOMBA, GOOMBA, GOOMBA }; 582 583 enemyPositions[0] = new Point(365, KOOPAGREENHEIGHT); 584 enemyPositions[1] = new Point(420, GOOMBAHEIGHT); 585 enemyPositions[2] = new Point(495, GOOMBAHEIGHT); 586 enemyPositions[3] = new Point(1250, GOOMBAHEIGHT); 587 enemyPositions[4] = new Point(1500, GOOMBAHEIGHT); 588 enemyPositions[5] = new Point(1575, GOOMBAHEIGHT); 589 enemyPositions[6] = new Point(1650, GOOMBAHEIGHT); 590 enemyPositions[7] = new Point(1725, GOOMBAHEIGHT); 591 592 break; 593 // ----------------------------------------------- 594 // LEVEL 4 595 // ----------------------------------------------- 596 case 4: 597 for (int i = 0; i < obstacleNumber; i++) { 598 isTall[i] = false; 599 if (i == 2 || i == 5 || i == 7 || i == 8 || i == 9 || i == 10) { 600 piranhaPopping[i] = true; 601 hasPiranha[i] = true; 602 } else { 603 if (i == 1 || i == 4 || i == 6) 604 isTall[i] = true; 605 piranhaPopping[i] = false; 606 hasPiranha[i] = false; 607 } 608 } 609 610 // PAGE 1 611 obstaclePositions[0] = new Point(185, GROUNDLEVEL); 612 obstaclePositions[1] = new Point(370, GROUNDLEVEL); 613 obstaclePositions[2] = new Point(700, GROUNDLEVEL); 614 // PAGE 2 615 obstaclePositions[3] = new Point(900, GROUNDLEVEL); 616 obstaclePositions[4] = new Point(1300, GROUNDLEVEL); 617 // PAGE 3 618 obstaclePositions[5] = new Point(1500, GROUNDLEVEL); 619 obstaclePositions[6] = new Point(1750, GROUNDLEVEL); 620 obstaclePositions[7] = new Point(2000, GROUNDLEVEL); 621 // PAGE 4 622 623 // PAGE 5 624 obstaclePositions[8] = new Point(3064, GROUNDLEVEL); 625 obstaclePositions[9] = new Point(3264, GROUNDLEVEL); 626 // PAGE 6 627 obstaclePositions[10] = new Point(4100, GROUNDLEVEL); 628 629 enemyType = new int[] { KOOPARED, KOOPARED, KOOPAREDFLYING, GOOMBA, GOOMBA, GOOMBA, GOOMBA, KOOPAREDFLYING, 630 KOOPARED, KOOPARED, KOOPARED, FLYER }; 631 632 enemyPositions[0] = new Point(470, KOOPAREDHEIGHT); 633 enemyPositions[1] = new Point(520, KOOPAREDHEIGHT); 634 635 enemyPositions[2] = new Point(1000, KOOPAREDFLYINGHEIGHT); 636 enemyPositions[3] = new Point(1400, GOOMBAHEIGHT); 637 638 enemyPositions[4] = new Point(2230, GOOMBAHEIGHT); 639 enemyPositions[5] = new Point(2280, GOOMBAHEIGHT); 640 enemyPositions[6] = new Point(2320, GOOMBAHEIGHT); 641 642 enemyPositions[7] = new Point(3600, KOOPAREDFLYINGHEIGHT); 643 644 enemyPositions[8] = new Point(3710, KOOPAREDHEIGHT); 645 enemyPositions[9] = new Point(3760, KOOPAREDHEIGHT); 646 enemyPositions[10] = new Point(3810, KOOPAREDHEIGHT); 647 enemyPositions[11] = new Point(3500, FLYERHEIGHT); 648 649 break; 650 // ----------------------------------------------- 651 // LEVEL 5 652 // ----------------------------------------------- 653 case 5: 654 for (int i = 0; i < obstacleNumber; i++) { 655 isTall[i] = false; 656 if (i == 0 || i == 2 || i == 4 || i == 10 || i == 11 || i == 14 || i == 16) { 657 piranhaPopping[i] = true; 658 hasPiranha[i] = true; 659 } else { 660 if (i == 1 || i == 3 || i == 6 || i == 7 || i == 8 || i == 9 || i == 12 || i == 15) 661 isTall[i] = true; 662 piranhaPopping[i] = false; 663 hasPiranha[i] = false; 664 } 665 } 666 // page1 667 obstaclePositions[0] = new Point(150, GROUNDLEVEL); 668 obstaclePositions[1] = new Point(300, GROUNDLEVEL); 669 obstaclePositions[2] = new Point(600, GROUNDLEVEL); 670 // page2 671 obstaclePositions[3] = new Point(800, GROUNDLEVEL); 672 obstaclePositions[4] = new Point(900, GROUNDLEVEL); 673 // page3 674 obstaclePositions[5] = new Point(1600, GROUNDLEVEL); 675 obstaclePositions[6] = new Point(1700, GROUNDLEVEL); 676 obstaclePositions[7] = new Point(1800, GROUNDLEVEL); 677 obstaclePositions[8] = new Point(1900, GROUNDLEVEL); 678 obstaclePositions[9] = new Point(2000, GROUNDLEVEL); 679 // page4 680 obstaclePositions[10] = new Point(2400, GROUNDLEVEL); 681 // page5 682 obstaclePositions[11] = new Point(3100, GROUNDLEVEL); 683 obstaclePositions[12] = new Point(3200, GROUNDLEVEL); 684 // page6 685 obstaclePositions[13] = new Point(3850, GROUNDLEVEL); 686 obstaclePositions[14] = new Point(3950, GROUNDLEVEL); 687 obstaclePositions[15] = new Point(4050, GROUNDLEVEL); 688 // page7 689 // NONE\ 690 // page8 691 obstaclePositions[16] = new Point(5550, GROUNDLEVEL); 692 693 enemyType = new int[] { KOOPAREDFLYING, GOOMBA, GOOMBA, KOOPAGREEN, KOOPAREDFLYING, KOOPAGREEN, KOOPAGREEN, 694 KOOPAGREEN, KOOPAREDFLYING, KOOPAREDFLYING, GOOMBA, GOOMBA, GOOMBA }; 695 696 enemyPositions[0] = new Point(450, KOOPAREDFLYINGHEIGHT); 697 enemyPositions[1] = new Point(700, GOOMBAHEIGHT); 698 enemyPositions[2] = new Point(1000, GOOMBAHEIGHT); 699 enemyPositions[3] = new Point(1100, KOOPAGREENHEIGHT); 700 enemyPositions[4] = new Point(2100, KOOPAREDFLYINGHEIGHT); 701 enemyPositions[5] = new Point(2500, KOOPAGREENHEIGHT); 702 enemyPositions[6] = new Point(2600, KOOPAGREENHEIGHT); 703 enemyPositions[7] = new Point(2700, KOOPAGREENHEIGHT); 704 enemyPositions[8] = new Point(3400, KOOPAREDFLYINGHEIGHT); 705 enemyPositions[9] = new Point(3600, KOOPAREDFLYINGHEIGHT); 706 enemyPositions[10] = new Point(4700, GOOMBAHEIGHT); 707 enemyPositions[11] = new Point(4800, GOOMBAHEIGHT); 708 enemyPositions[12] = new Point(4800, GOOMBAHEIGHT); 709 break; 710 // ----------------------------------------------- 711 // LEVEL 6 712 // ----------------------------------------------- 713 case 6: 714 for (int i = 0; i < obstacleNumber; i++) { 715 isTall[i] = false; 716 piranhaPopping[i] = false; 717 hasPiranha[i] = false; 718 if (i == 2 || i == 3 || i == 4 || i == 5 || i == 7 || i == 10 || i == 11) { 719 isTall[i] = true; 720 } else { 721 if (i == 13) { 722 piranhaPopping[i] = true; 723 hasPiranha[i] = true; 724 } 725 726 } 727 } 728 obstaclePositions[0] = new Point(350, GROUNDLEVEL); 729 obstaclePositions[1] = new Point(1091, GROUNDLEVEL); 730 obstaclePositions[2] = new Point(1191, GROUNDLEVEL); 731 obstaclePositions[3] = new Point(1600, GROUNDLEVEL); 732 obstaclePositions[4] = new Point(1675, GROUNDLEVEL); 733 obstaclePositions[5] = new Point(1750, GROUNDLEVEL); 734 obstaclePositions[6] = new Point(2500, GROUNDLEVEL); 735 obstaclePositions[7] = new Point(2600, GROUNDLEVEL); 736 obstaclePositions[8] = new Point(2700, GROUNDLEVEL); 737 obstaclePositions[9] = new Point(3975, GROUNDLEVEL); 738 obstaclePositions[10] = new Point(4050, GROUNDLEVEL); 739 obstaclePositions[11] = new Point(4150, GROUNDLEVEL); 740 obstaclePositions[12] = new Point(4225, GROUNDLEVEL); 741 obstaclePositions[13] = new Point(5550, GROUNDLEVEL); 742 743 enemyPositions[0] = new Point(-400, BANZAIHEIGHT); 744 enemyType[0] = BANZAI; 745 746 break; 747 748 // ----------------------------------------------- 749 // LEVEL 7 750 // ----------------------------------------------- 751 case 7: 752 753 for (int i = 0; i < obstacleNumber; i++) { 754 isTall[i] = false; 755 piranhaPopping[i] = false; 756 hasPiranha[i] = false; 757 if (i == 1 || i == 2 || i == 8) { 758 isTall[i] = true; 759 } else { 760 if (i == 0 || i == 3 || i == 5 || i == 7 || i == 9 || i == 10 || i == 11) { 761 piranhaPopping[i] = true; 762 hasPiranha[i] = true; 763 } 764 } 765 } 766 obstaclePositions[0] = new Point(250, GROUNDLEVEL); 767 obstaclePositions[1] = new Point(350, GROUNDLEVEL); 768 obstaclePositions[2] = new Point(450, GROUNDLEVEL); 769 obstaclePositions[3] = new Point(550, GROUNDLEVEL); 770 obstaclePositions[4] = new Point(800, GROUNDLEVEL); 771 obstaclePositions[5] = new Point(1000, GROUNDLEVEL); 772 obstaclePositions[6] = new Point(1200, GROUNDLEVEL); 773 obstaclePositions[7] = new Point(1400, GROUNDLEVEL); 774 obstaclePositions[8] = new Point(1800, GROUNDLEVEL); 775 obstaclePositions[9] = new Point(2400, GROUNDLEVEL); 776 obstaclePositions[10] = new Point(2550, GROUNDLEVEL); 777 obstaclePositions[11] = new Point(2700, GROUNDLEVEL); 778 obstaclePositions[12] = new Point(3100, GROUNDLEVEL); 779 obstaclePositions[13] = new Point(3600, GROUNDLEVEL); 780 781 enemyType = new int[] { GOOMBA, GOOMBA, GOOMBA, GOOMBA, GOOMBA, WIGGLER }; 782 enemyPositions[0] = new Point(900, GOOMBAHEIGHT); 783 enemyPositions[1] = new Point(1100, GOOMBAHEIGHT); 784 enemyPositions[2] = new Point(1300, GOOMBAHEIGHT); 785 enemyPositions[3] = new Point(1600, GOOMBAHEIGHT); 786 enemyPositions[4] = new Point(2000, GOOMBAHEIGHT); 787 enemyPositions[5] = new Point(3250, WIGGLERHEIGHT); 788 break; 789 // ----------------------------------------------- 790 // LEVEL 8 791 // ----------------------------------------------- 792 case 8: 793 794 for (int i = 0; i < obstacleNumber; i++) { 795 isTall[i] = false; 796 piranhaPopping[i] = false; 797 hasPiranha[i] = false; 798 if (i == 2 || i == 3 || i == 4 || i == 6 || i == 8 || i == 11) { 799 isTall[i] = true; 800 } else { 801 if (i == 0 || i == 1 || i == 10 || i == 12 || i == 13) { 802 piranhaPopping[i] = true; 803 hasPiranha[i] = true; 804 } 805 } 806 } 807 808 obstaclePositions[0] = new Point(100, GROUNDLEVEL); 809 obstaclePositions[1] = new Point(650, GROUNDLEVEL); 810 obstaclePositions[2] = new Point(1000, GROUNDLEVEL); 811 obstaclePositions[3] = new Point(1075, GROUNDLEVEL); 812 obstaclePositions[4] = new Point(1150, GROUNDLEVEL); 813 obstaclePositions[5] = new Point(1500, GROUNDLEVEL); 814 obstaclePositions[6] = new Point(1575, GROUNDLEVEL); 815 obstaclePositions[7] = new Point(1650, GROUNDLEVEL); 816 obstaclePositions[8] = new Point(1725, GROUNDLEVEL); 817 obstaclePositions[9] = new Point(1800, GROUNDLEVEL); 818 obstaclePositions[10] = new Point(2500, GROUNDLEVEL); 819 obstaclePositions[11] = new Point(3400, GROUNDLEVEL); 820 obstaclePositions[12] = new Point(4000, GROUNDLEVEL); 821 obstaclePositions[13] = new Point(4075, GROUNDLEVEL); 822 obstaclePositions[14] = new Point(5275, GROUNDLEVEL); 823 obstaclePositions[15] = new Point(5775, GROUNDLEVEL); 824 825 enemyType = new int[] { BOO, FIREBOO, GOOMBA, BOO, GOOMBA, FIREBOO, GOOMBA, GOOMBA, BOBOMB }; 826 827 enemyPositions[0] = new Point(350, BOOHEIGHT); 828 enemyPositions[1] = new Point(900, FIREBOOHEIGHT); 829 enemyPositions[2] = new Point(1200, GOOMBAHEIGHT); 830 enemyPositions[3] = new Point(1900, BOOHEIGHT); 831 enemyPositions[4] = new Point(2600, GOOMBAHEIGHT); 832 enemyPositions[5] = new Point(3500, FIREBOOHEIGHT); 833 enemyPositions[6] = new Point(4175, GOOMBAHEIGHT); 834 enemyPositions[7] = new Point(4250, GOOMBAHEIGHT); 835 enemyPositions[8] = new Point(5375, BOBOMBHEIGHT); 836 break; 837 case 9: 838 enemyType = new int[] { FLYER, GOOMBA, GOOMBA, KOOPAREDFLYING, KOOPAREDFLYING, KOOPAREDFLYING, 839 KOOPAREDFLYING, KOOPAREDFLYING, CHOMP }; 840 841 enemyPositions[0] = new Point(400, FLYERHEIGHT); 842 enemyPositions[1] = new Point(950, GOOMBAHEIGHT); 843 enemyPositions[2] = new Point(1000, GOOMBAHEIGHT); 844 enemyPositions[3] = new Point(1300, KOOPAREDFLYINGHEIGHT - 10); 845 enemyPositions[4] = new Point(1500, KOOPAREDFLYINGHEIGHT - 10); 846 enemyPositions[5] = new Point(1700, KOOPAREDFLYINGHEIGHT - 10); 847 enemyPositions[6] = new Point(1900, KOOPAREDFLYINGHEIGHT - 10); 848 enemyPositions[7] = new Point(2100, KOOPAREDFLYINGHEIGHT - 10); 849 enemyPositions[8] = new Point(2850, CHOMPHEIGHT); 850 851 for (int i = 0; i < obstacleNumber; i++) { 852 853 piranhaPopping[i] = false; 854 hasPiranha[i] = false; 855 if (i == 0 || i == 3 || i == 5) { 856 isTall[i] = true; 857 } else { 858 if (i == 1 || i == 2 || i == 4) { 859 piranhaPopping[i] = true; 860 hasPiranha[i] = true; 861 } 862 } 863 } 864 865 obstaclePositions[0] = new Point(200, GROUNDLEVEL); 866 obstaclePositions[1] = new Point(900, GROUNDLEVEL); 867 obstaclePositions[2] = new Point(1100, GROUNDLEVEL); 868 obstaclePositions[3] = new Point(2400, GROUNDLEVEL); 869 obstaclePositions[4] = new Point(2550, GROUNDLEVEL); 870 obstaclePositions[5] = new Point(2700, GROUNDLEVEL); 871 872 default: 873 874 } 875 876 for (int j = 0; j < enemyNumber; j++) { 877 enemyFaceRight(j); 878 enemyDead[j] = false; 879 } 880 881 for (int i = 0; i < obstacleNumber; i++) { 882 if (hasPiranha[i]) { // pick a random image number between 0 and 18 (inclusive) 883 obstacleImageNo[i] = (int) (Math.random() * 18) / 1; 884 } else 885 obstacleImageNo[i] = 0; 886 } 887 888 // position the warp zone at the end of the level 889 warpzone = new Point(levellength, GROUNDLEVEL); 890 // *********** END OF STUFF THAT DEPENDS WHAT LEVEL YOU ARE ON ************ 891 892 ingame = true; 893 System.out.println("Started level " + level); 894 } 895 896 boolean isPlayerPosition(Point p) { 897 return (p.x == playerPosition.x && p.y == playerPosition.y); 898 } 899 900 int isEnemyPosition(Point p) { 901 for (int i = 0; i < enemyNumber; i++) { 902 if (isEnemyX(p) != -1 && isEnemyY(p) != -1 && !enemyDead[i]) 903 return (i); 904 } 905 return (-1); 906 } 907 908 boolean isObstaclePosition(Point p, boolean forMario) { 909 int obby; 910 for (int i = 0; i < obstacleNumber; i++) { 911 obby = isObstacleX(p, forMario); 912 if (obby != -1 && isObstacleY(p, obby, forMario) != -1) { 913 return (true); 914 } 915 } 916 return (false); 917 } 918 919 boolean checkIfBlockingObstacle(Point p) { 920 boolean result = false; 921 int obby; 922 obby = isObstacleX(p, true); 923 if (obby != -1 && isBlockingObstacleY(p, obby)) { 924 piranhaPopping[obby] = false; 925 result = true; 926 } 927 for (int i = 0; i < obstacleNumber; i++) { 928 if (i != obby || !result) { 929 if (hasPiranha[i]) 930 piranhaPopping[i] = true; 931 } 932 } 933 if (!result) 934 startPosY = GROUNDLEVEL; 935 return (result); 936 } 937 938 int isObstacleX(Point p, boolean forMario) { 939 int obstaclex; 940 for (int i = 0; i < obstacleNumber; i++) { 941 // if x is >= obstacleposition - (MARIOLEFTOFOBSTACLE) and x <= obstacleposition 942 // + (MARIORIGHTOFOBSTACLE) 943 obstaclex = obstaclePositions[i].x; 944 if (forMario) { 945 if (p.x >= (obstaclex - MARIOLEFTOFOBSTACLE) && p.x <= (obstaclex + MARIORIGHTOFOBSTACLE)) 946 return (i); // return the number of the matching obstacle 947 } else { 948 if (p.x >= (obstaclex - ENEMYLEFTOFOBSTACLE) && p.x <= (obstaclex + ENEMYRIGHTOFOBSTACLE)) 949 return (i); // return the number of the matching obstacle 950 } 951 } 952 return (-1); 953 } 954 955 boolean isBlockingObstacleY(Point p, int obstaclenumber) { 956 if (isTall[obstaclenumber]) { 957 if (p.y <= obstaclePositions[obstaclenumber].y - (OBSTACLEHEIGHT + TALLOBSTACLEDIFF)) { 958 // System.out.println(s+": Yes"); 959 return (true); 960 } 961 } else { 962 if (p.y <= obstaclePositions[obstaclenumber].y - OBSTACLEHEIGHT) { 963 // System.out.println(s+": Yes"); 964 return (true); 965 } 966 } 967 // System.out.println(s+": No"); 968 return (false); 969 } 970 971 int isObstacleY(Point p, int obstaclenumber, boolean forMario) { 972 if (isTall[obstaclenumber]) { 973 if (p.y > obstaclePositions[obstaclenumber].y - (OBSTACLEHEIGHT + TALLOBSTACLEDIFF)) { 974 return (obstaclenumber); 975 } 976 } else { 977 if (p.y > obstaclePositions[obstaclenumber].y - OBSTACLEHEIGHT) { 978 return (obstaclenumber); 979 } 980 } 981 return (-1); 982 } 983 984 int isEnemyX(Point p) { 985 int enemyx; 986 for (int i = 0; i < enemyNumber; i++) { 987 // if x is >= enemyposition - (LEFTOFENEMY) and x <= enemyposition + 988 // (RIGHTOFENEMY) 989 enemyx = enemyPositions[i].x; 990 // System.out.println("Player got by enemy if " + 991 // p.x + " >= " + (enemyx - MARIOLEFTOFENEMY) + " && " + p.x + " <= " + (enemyx 992 // + MARIORIGHTOFENEMY)); 993 if (p.x >= (enemyx - MARIOLEFTOFENEMY) && p.x <= (enemyx + MARIORIGHTOFENEMY) && !enemyDead[i]) 994 return (i); // return the number of the matching enemy 995 } 996 return (-1); 997 } 998 999 int isEnemyY(Point p) { 1000 int offset = herocrouching ? MARIOCROUCHOFFSET : MARIOOFFSET; 1001 for (int i = 0; i < enemyNumber; i++) { 1002 if (!enemyDead[i] && ((p.y + offset <= enemyPositions[i].y + enemySize[enemyType[i]]) 1003 && (p.y + MARIOHEIGHT) >= enemyPositions[i].y)) 1004 return (i); 1005 } 1006 return (-1); 1007 } 1008 1009 public void finished() { 1010 finished = true; 1011 System.exit(0); 1012 } 1013 1014 public String getAppletInfo() { 1015 return ("Mario Game"); 1016 } 1017 1018 int randomMove() { 1019 // return + or - value (randomly) 1020 if (Math.random() >= 0.5) 1021 return (24); 1022 else 1023 return (-24); 1024 } 1025 1026 private synchronized void incKeysDown(int whichone) { 1027 keysdown[whichone] = 1; 1028 } 1029 1030 private synchronized void decKeysDown(int whichone) { 1031 keysdown[whichone] = 0; 1032 } 1033 1034 // this class will use just the key pressed event 1035 public void keyPressed(KeyEvent e) { 1036 if (e.getKeyCode() == KeyEvent.VK_F1) { 1037 displayStatus(); 1038 } 1039 if (ingame) { 1040 if (!(e.getKeyCode() == KeyEvent.VK_LEFT && playerPosition.x <= (LEFTEDGE + XAMOUNT))) { 1041 1042 // valid move: move the player and then move the enemies 1043 if (e.getKeyCode() == KeyEvent.VK_DOWN) { 1044 herocrouching = true; 1045 incKeysDown(DOWNDOWN); 1046 setSomethingChangedSinceRepaint(true); 1047 } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { 1048 incKeysDown(LEFTDOWN); 1049 leftPressed(false); 1050 setSomethingChangedSinceRepaint(true); 1051 } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 1052 incKeysDown(RIGHTDOWN); 1053 rightPressed(false); 1054 setSomethingChangedSinceRepaint(true); 1055 } else if (e.getKeyCode() == KeyEvent.VK_SPACE) { 1056 if (!jumping) { 1057 startPosY = playerPosition.y; 1058 jumping = true; 1059 onTheWayUp = true; 1060 setSomethingChangedSinceRepaint(true); 1061 } 1062 } 1063 if (somethingChangedSinceRepaint) { 1064 area.repaint(); 1065 } 1066 } // if valid key press 1067 } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { 1068 if (level == MAXLEVEL || dead) 1069 doLevel(level); 1070 else 1071 doLevel(++level); 1072 page = 0; 1073 area.repaint(); 1074 } 1075 } 1076 1077 /* synchronized */ void setSomethingChangedSinceRepaint(boolean val) { 1078 somethingChangedSinceRepaint = val; 1079 } 1080 1081 void leftPressed(boolean skid) { 1082 if (!herocrouching) { 1083 // if Hero was facing right, turn him left 1084 if (!heroleft) 1085 faceLeft(); 1086 else { 1087 // if the target position is not occupied by a obstacle... 1088 for (int i = 0; i < obstacleNumber; i++) { 1089 if (isObstaclePosition(new Point(playerPosition.x - XAMOUNT, playerPosition.y), true)) 1090 return; // can't move 1091 } 1092 playerPosition.x -= XAMOUNT; 1093 if (!skid) 1094 incrementHeroImage(); 1095 } 1096 } 1097 } 1098 1099 void rightPressed(boolean skid) { 1100 if (!herocrouching) { 1101 if ((playerPosition.x + SPACE_FROM_X_TO_MARIO) >= (warpzone.x + 4)) { 1102 // level complete! 1103 ingame = false; 1104 } else { 1105 // if Hero was facing left, turn him right 1106 if (heroleft) 1107 faceRight(); 1108 else { 1109 for (int i = 0; i < obstacleNumber; i++) { 1110 if (isObstaclePosition(new Point(playerPosition.x + XAMOUNT, playerPosition.y), true)) 1111 return; // can't move 1112 } 1113 playerPosition.x += XAMOUNT; 1114 // System.out.println("Mario's x position is " + playerPosition.x); 1115 if (!skid) 1116 incrementHeroImage(); 1117 } 1118 } 1119 } 1120 } 1121 1122 boolean anythingVisibleChanged() { 1123 return (somethingChangedSinceRepaint); 1124 } 1125 1126 public void run() { 1127 boolean odd = true; // only change piranha image every other cycle 1128 while (true) { 1129 if (juststarted) { 1130 try { 1131 Thread.sleep(750); 1132 } catch (Exception e) { 1133 } 1134 area.repaint(); 1135 juststarted = false; 1136 } 1137 try { 1138 Thread.sleep(DELAY); 1139 } catch (InterruptedException e) { 1140 } 1141 if (ingame) { 1142 if (keysdown[LEFTDOWN] == 0 && keysdown[RIGHTDOWN] == 0 && keysdown[DOWNDOWN] == 0) 1143 standStill(); 1144 1145 if (keysdown[LEFTDOWN] > 0) { 1146 leftPressed(false); 1147 setSomethingChangedSinceRepaint(true); 1148 } else if (keysdown[RIGHTDOWN] > 0) { 1149 rightPressed(false); 1150 setSomethingChangedSinceRepaint(true); 1151 } 1152 1153 if (!odd) { 1154 // for each obstacle, cycle through the piranha pictures 1155 for (int i = 0; i < obstacleNumber; i++) { 1156 if (piranhaPopping[i]) { 1157 incrementObstacleImage(i); 1158 if (isVisibleObstacle(i)) 1159 setSomethingChangedSinceRepaint(true); 1160 } 1161 } 1162 } 1163 odd = !odd; 1164 1165 // for each enemy, move the enemy in the direction it was going 1166 for (int i = 0; i < enemyNumber; i++) { 1167 // TODO if there is a fatal obstacle at that position, fall into it and 1168 // decrement count of enemies 1169 // and set that enemy's position to -1, -1 1170 /* 1171 * if (isObstaclePosition(enemyPositions[i])) { 1172 * System.out.Println("A enemy fell into a obstacle"); 1173 * 1174 * enemyPositions[i] = new Point(-1, -1); enemiesRemaining--; 1175 * System.out.Println(enemyNumber-enemiesRemaining + " down, " + 1176 * enemiesRemaining + " to go..."); } 1177 */ 1178 // if there is a non-fatal obstacle 1179 if (isObstaclePosition(enemyPositions[i], false) && enemyType[i] != BANZAI) { 1180 // change direction 1181 changeDirection(i); 1182 if (isVisibleEnemy(i)) 1183 setSomethingChangedSinceRepaint(true); 1184 } 1185 if (!enemyDead[i]) { 1186 enemyPositions[i] = move(i, enemyPositions[i], enemyDirection[i], odd); 1187 if (isVisibleEnemy(i)) 1188 setSomethingChangedSinceRepaint(true); 1189 } 1190 1191 // if player is caught by a enemy, end the game 1192 int enemyno = isEnemyPosition(playerPosition); 1193 if (enemyno > -1) { 1194 int NEEDTOBEABOVE = enemyPositions[enemyno].y + enemyTopSpace[enemyno] - MARIOHEIGHT; 1195 if (easymode) 1196 NEEDTOBEABOVE = enemyPositions[enemyno].y - enemyHeight[enemyType[enemyno]]; 1197 if ((!onTheWayUp && (playerPosition.y <= NEEDTOBEABOVE)) && enemyType[enemyno] != BANZAI) { 1198 // player may have squished an enemy 1199 if (enemyType[enemyno] == KOOPAREDFLYING) { 1200 enemyType[enemyno] = KOOPARED; 1201 enemyPositions[enemyno].y = KOOPAREDHEIGHT; 1202 if (enemyDirection[enemyno] == LEFT) 1203 enemyFaceLeft(enemyno); 1204 else 1205 enemyFaceRight(enemyno); 1206 } else { 1207 enemyDead[enemyno] = true; 1208 enemyDie(enemyno); 1209 } 1210 // player bounces 1211 bouncing = true; 1212 startPosY = playerPosition.y; 1213 setSomethingChangedSinceRepaint(true); 1214 } else { 1215 int offset = herocrouching ? MARIOCROUCHOFFSET : MARIOOFFSET; 1216 if (playerPosition.y > NEEDTOBEABOVE && (playerPosition.y 1217 + offset <= enemyPositions[enemyno].y + enemySize[enemyType[enemyno]])) { 1218 die(); 1219 setSomethingChangedSinceRepaint(true); 1220 } 1221 } 1222 } 1223 } 1224 if (!dead) { 1225 if (onTheWayUp) { 1226 if (playerPosition.y > startPosY - JUMPAMOUNT) { 1227 playerPosition = new Point(playerPosition.x, playerPosition.y - RISEAMOUNT); 1228 setSomethingChangedSinceRepaint(true); 1229 } else { 1230 onTheWayUp = false; 1231 } 1232 } else if (bouncing) { 1233 if (playerPosition.y > startPosY - BOUNCEAMOUNT) { 1234 playerPosition = new Point(playerPosition.x, playerPosition.y - RISEAMOUNT); 1235 setSomethingChangedSinceRepaint(true); 1236 } else { 1237 bouncing = false; 1238 wasbouncing = true; 1239 } 1240 } else { 1241 int obstacleno = isObstacleX(playerPosition, true); 1242 if (obstacleno == -1) { // no obstacle at this position 1243 if (!onTheWayUp && !bouncing) { 1244 if (playerPosition.y < startPosY) { 1245 playerPosition = new Point(playerPosition.x, playerPosition.y + FALLAMOUNT); 1246 if (playerPosition.y >= GROUNDLEVEL && floorIsIcy()) { 1247 if (!wasbouncing) { 1248 if (heroleft) 1249 skidLeft(); 1250 else 1251 skidRight(); 1252 } 1253 } 1254 wasbouncing = false; 1255 setSomethingChangedSinceRepaint(true); 1256 } else 1257 jumping = false; 1258 } 1259 } else { 1260 Point obstaclepos = obstaclePositions[obstacleno]; 1261 // if hero's y position <= obstacle's height 1262 int thisObstacleHeight = isTall[obstacleno] ? OBSTACLEHEIGHT + TALLOBSTACLEDIFF 1263 : OBSTACLEHEIGHT; 1264 if (playerPosition.y <= (obstaclepos.y - thisObstacleHeight) && // can't land on the 1265 // obstacle if just < (??!) 1266 (playerPosition.y + FALLAMOUNT >= (obstaclepos.y - thisObstacleHeight))) { 1267 // allow hero to land on the obstacle 1268 jumping = false; 1269 if (playerPosition.y != obstaclepos.y - thisObstacleHeight) 1270 setSomethingChangedSinceRepaint(true); 1271 playerPosition = new Point(playerPosition.x, obstaclepos.y - thisObstacleHeight); 1272 // if the piranha was up, Hero dies 1273 if (obstacleImages[obstacleImageNo[obstacleno]] != area.obstacle) { 1274 die(); 1275 } else { 1276 // otherwise stop this Piranha 1277 piranhaPopping[obstacleno] = false; 1278 } 1279 } else { 1280 if (!onTheWayUp && !bouncing) { 1281 if (playerPosition.y < startPosY) { 1282 setSomethingChangedSinceRepaint(true); 1283 playerPosition = new Point(playerPosition.x, playerPosition.y + FALLAMOUNT); 1284 if (playerPosition.y >= GROUNDLEVEL && floorIsIcy()) { 1285 if (!wasbouncing) { 1286 if (heroleft) 1287 skidLeft(); 1288 else 1289 skidRight(); 1290 } 1291 } 1292 wasbouncing = false; 1293 } else 1294 jumping = false; 1295 } 1296 } 1297 } 1298 } 1299 if (!dead) { 1300 checkIfBlockingObstacle(playerPosition); 1301 if (playerPosition.y > GROUNDLEVEL) 1302 playerPosition.y = GROUNDLEVEL; 1303 } 1304 if (anythingVisibleChanged()) { 1305 area.repaint(); 1306 } 1307 } else { 1308 if (!area.showingMessage) 1309 area.repaint(); 1310 } 1311 } 1312 } 1313 } 1314 1315 boolean isVisibleObstacle(int i) { 1316 // TODO - this probably needs fixing when obstacle is near page boundary 1317 return ((obstaclePositions[i].x >= page * PAGEWIDTH) && (obstaclePositions[i].x < (page + 1) * PAGEWIDTH)); 1318 } 1319 1320 boolean isVisibleEnemy(int i) { 1321 // TODO - this probably needs fixing when enemy is near page boundary 1322 return ((enemyPositions[i].x >= page * PAGEWIDTH) && (enemyPositions[i].x < (page + 1) * PAGEWIDTH) 1323 && !enemyDead[i]); 1324 } 1325 1326 void changeDirection(int enemyno) { 1327 if (enemyDirection[enemyno] == LEFT) { 1328 enemyFaceRight(enemyno); 1329 } else { 1330 enemyFaceLeft(enemyno); 1331 } 1332 } 1333 1334 synchronized void die() { 1335 System.out.println("The Player is dead. Press the Enter key to restart the level"); 1336 ingame = false; 1337 dead = true; 1338 displayStatus(); 1339 } 1340 1341 synchronized void incrementObstacleImage(int i) { 1342 obstacleImageNo[i]++; 1343 if (obstacleImageNo[i] == OBSTACLEIMAGES) 1344 obstacleImageNo[i] = 0; 1345 } 1346 1347 synchronized void incrementHeroImage() { 1348 heroImageNo++; 1349 if (heroImageNo == HEROIMAGES) 1350 heroImageNo = 0; 1351 } 1352 1353 synchronized void incrementEnemyImage(int i) { 1354 enemyImageNo[i]++; 1355 if (enemyType[i] == WIGGLER) { 1356 if (enemyImageNo[i] > (ENEMYIMAGES - 1)) 1357 enemyImageNo[i] = 0; 1358 } else { 1359 if (enemyImageNo[i] > (ENEMYIMAGES - 2)) 1360 enemyImageNo[i] = 0; 1361 } 1362 } 1363 1364 Point move(int enemyNo, Point start, int direction, boolean odd) { 1365 if (odd) 1366 incrementEnemyImage(enemyNo); 1367 if (direction == LEFT) { 1368 return (new Point(start.x - enemyMove[enemyType[enemyNo]], start.y)); 1369 } else { 1370 return (new Point(start.x + enemyMove[enemyType[enemyNo]], start.y)); 1371 } 1372 } 1373 1374 public void keyReleased(KeyEvent e) { 1375 if (e.getKeyCode() == KeyEvent.VK_DOWN) { 1376 herocrouching = false; 1377 decKeysDown(DOWNDOWN); 1378 } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { 1379 if (floorIsIcy()) { 1380 skidLeft(); 1381 } 1382 decKeysDown(LEFTDOWN); 1383 } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 1384 if (floorIsIcy()) { 1385 skidRight(); 1386 } 1387 decKeysDown(RIGHTDOWN); 1388 } 1389 } 1390 1391 public void keyTyped(KeyEvent e) { 1392 } 1393 1394 synchronized Image getHeroImage() { 1395 return (heroImages[heroImageNo]); 1396 } 1397 1398 synchronized Image getObstacleImage(int obstaclenum) { 1399 return (obstacleImages[obstacleImageNo[obstaclenum]]); 1400 } 1401 1402 synchronized Image getEnemyImage(int enemyno) { 1403 return (enemyImage[enemyno][enemyImageNo[enemyno]]); 1404 } 1405 1406 boolean floorIsIcy() { 1407 return (floors[level - 1] == area.icefloor); 1408 } 1409 1410 void skidLeft() { 1411 for (int i = 0; i < 6; i++) { 1412 leftPressed(true); 1413 try { 1414 Thread.sleep(7); 1415 } catch (Exception e) { 1416 } 1417 area.repaint(); 1418 } 1419 } 1420 1421 void skidRight() { 1422 for (int i = 0; i < 6; i++) { 1423 rightPressed(true); 1424 area.repaint(); 1425 try { 1426 Thread.sleep(7); 1427 } catch (Exception e) { 1428 } 1429 } 1430 } 1431 1432 void displayStatus() { 1433 /* 1434 * // when a certain F Key is pressed, display positions of Mario, // all pipes 1435 * and all enemies and the end flag (warp zone) System.out.println("--------"); 1436 * System.out.println("Mario is " + (dead? "dead" : "alive")); if (dead) { int 1437 * enemyno = isEnemyPosition(playerPosition); 1438 * System.out.println("Mario was killed by enemy " + enemyno); } 1439 * System.out.println("In game is " + ingame); System.out.println("Mario is " + 1440 * (onTheWayUp? "on the way up" : "not on the way up")); 1441 * System.out.println("Mario's position is (" + playerPosition.x + ", " + 1442 * playerPosition.y + ")"); 1443 * System.out.println("Mario's visible left, bottom co-ordinates are " + 1444 * (playerPosition.x + 55) + " and " + (playerPosition.y + MARIOHEIGHT)); 1445 * System.out.println("Mario is on page " + page + 1446 * " (which shows x positions from " + (page*PAGEWIDTH) + " to " + 1447 * ((page+1)*PAGEWIDTH) + ")"); System.out.println("Screen bounds are (" + 1448 * getBounds().width + ", " + getBounds().height + ")"); System.out.println(""); 1449 * for (int enemy=0; enemy < enemyNumber; enemy++) { System.out.println("Enemy " 1450 * + enemy + " is " + enemyTypeString(enemyType[enemy]) + " and is " + 1451 * (enemyDead[enemy] ? " " : "not ") + "dead"); System.out.println("Enemy " + 1452 * enemy + " is at position (" + enemyPositions[enemy].x + ", " + 1453 * enemyPositions[enemy].y+") and has size " + enemySize[enemyType[enemy]]); } 1454 * //System.out.println(""); //for (int obstacle=0; obstacle < obstacleNumber; 1455 * obstacle++) { // System.out.println("Obstacle " + obstacle + 1456 * " is at position (" + obstaclePositions[obstacle].x + // ", " + 1457 * obstaclePositions[obstacle].y+")"); //} System.out.println(""); 1458 * System.out.println("The warp zone is positioned at (" + warpzone.x + ", " + 1459 * warpzone.y + ")"); System.out.println("========"); 1460 */ 1461 } 1462 1463 String enemyTypeString(int fortype) { 1464 switch (fortype) { 1465 case GOOMBA: 1466 return ("GOOMBA"); 1467 case KOOPARED: 1468 return ("KOOPA RED"); 1469 case KOOPAGREEN: 1470 return ("KOOPA GREEN"); 1471 case KOOPAREDFLYING: 1472 return ("KOOPA RED FLYING"); 1473 case BANZAI: 1474 return ("BANZAI"); 1475 case WIGGLER: 1476 return ("WIGGLER"); 1477 case BOO: 1478 return ("BOO"); 1479 case FIREBOO: 1480 return ("FOREBOO"); 1481 case BOBOMB: 1482 return ("BOBOMB"); 1483 case BULLET: 1484 return ("BULLET"); 1485 case WARSHIP: 1486 return ("WARSHIP"); 1487 case YETI: 1488 return ("YETI"); 1489 case FLYER: 1490 return ("FLYER"); 1491 default: 1492 return ("Unknown type (" + fortype + ")"); 1493 } 1494 } 1495 1496 void changePageIfNecessary() { 1497 if (playerPosition.x == LEFTEDGE) 1498 return; 1499 if ((playerPosition.x + SPACE_FROM_X_TO_MARIO) > (page * PAGEWIDTH + RIGHTEDGE - XAMOUNT)) { 1500 // System.out.println("Change page up: (" + playerPosition.x+ "+" + 1501 // SPACE_FROM_X_TO_MARIO+ ") > (" + page+ "*" + PAGEWIDTH + "+" + RIGHTEDGE + 1502 // "-" + XAMOUNT + ")"); 1503 page++; 1504 } else if ((playerPosition.x + SPACE_FROM_X_TO_MARIO) - (page * PAGEWIDTH) < (LEFTEDGE + XAMOUNT)) { 1505 // System.out.println("Change page down: (" + playerPosition.x+ "+" + 1506 // SPACE_FROM_X_TO_MARIO+ ")-(" + page+ "*" + PAGEWIDTH + ") < (" + LEFTEDGE+ 1507 // "+" + XAMOUNT+")"); 1508 page--; 1509 } 1510 } 1511 }