old-java-games

java games my brother and I developed as kids.
Log | Files | Refs | README

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 }