old-java-games

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

Link.java (19759B)


      1 import java.awt.Color;
      2 import java.awt.Image;
      3 import java.awt.Point;
      4 import java.awt.event.KeyEvent;
      5 import java.awt.event.KeyListener;
      6 
      7 import javax.swing.JFrame;
      8 
      9 /* Copyright (c) Mary Percival 2003                          */
     10 /* Link game                      Created May 2003          */
     11 
     12 public class Link extends JFrame implements KeyListener, Runnable {
     13     private static final long serialVersionUID = 136423218680421502L;
     14     // all member variables 'static' because shared with the enemy action thread
     15     static LinkArea area;
     16     static boolean finished = false;
     17     static boolean ingame = false;
     18     static boolean juststarted = false;
     19     static int level = 0;
     20     static Point[] enemyPositions;
     21     static Point playerPosition;
     22     static Point[][] obstaclePositions;
     23     static int direction[];
     24     static Thread timer;
     25     static int enemyNumber = 1, enemiesRemaining = 1, obstacleNumber = 1;
     26     static boolean herocrouching = false;
     27     static final int MAXLEVELS = 1;
     28     static final int levellengths[] = new int[MAXLEVELS];
     29     boolean hasWeaponOut = false;
     30 
     31     static int LEFT = -1;
     32     static int RIGHT = 1;
     33 
     34     // the next 2 constants are overridden in init once we know the screen size
     35     static int RIGHTEDGE = 789;
     36     static int BOTTOMEDGE = 800;
     37     //
     38     static Point IMAGESIZE = new Point(152, 107);
     39     static Point HEROPOS = new Point(63, 28);
     40     static final int LEFTEDGE = -15;
     41     static final int TOPEDGE = -10;
     42     static final int FALLAMOUNT = 16; // amount he falls each time interval
     43     static final int RISEAMOUNT = 16; // amount he rises each time interval
     44     static int GROUNDLEVEL = 500;
     45     static int XAMOUNT = 5;
     46     static int YAMOUNT = 5;
     47     static int JUMPAMOUNT = 70;
     48     static final int X = 1;
     49     static final int Y = 2;
     50     static final int NOT = 3;
     51     static final int DELAY = 60;
     52 
     53     static int heroImageNo = 0;
     54     static final int OBSTACLEIMAGES = 1;
     55     static final int HEROIMAGES = 4;
     56     static Image[] heroImages = new Image[HEROIMAGES];
     57     static Image[] obstacleImages = new Image[OBSTACLEIMAGES]; // obstacles don't move
     58     static int obstacleImageNo[];
     59     static boolean heroleft = false;
     60     static boolean jumping = false;
     61     static Point warpzone;
     62     // static boolean superjump = false;
     63     static final int JUMPDURATION = 5;
     64     static final int SUPERJUMPDURATION = 8;
     65     static final int LEFTOFOBSTACLE = 27;
     66     static final int RIGHTOFOBSTACLE = 33;
     67     static int[] keysdown = new int[4];
     68     static final int LEFTDOWN = 0;
     69     static final int RIGHTDOWN = 1;
     70     static final int DOWNDOWN = 2;
     71     static final int SPACEDOWN = 3;
     72 
     73     static final int OBSTACLEHEIGHT = 42;
     74     boolean onTheWayUp = false;
     75     static int startPosY = GROUNDLEVEL;
     76 
     77     public static void main(String[] args) {
     78         Link link = new Link();
     79 
     80         link.setLayout(null);
     81         link.setBackground(Color.white);
     82         link.setSize(RIGHTEDGE, BOTTOMEDGE);
     83         link.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     84         link.setTitle("Link");
     85 
     86         area = new LinkArea(link);
     87         link.add(area);
     88         XAMOUNT = 12;
     89         YAMOUNT = 12;
     90         //RIGHTEDGE = (Link.getBounds().width / XAMOUNT) * XAMOUNT + LEFTEDGE;
     91         //BOTTOMEDGE = Link.getBounds().height - 1;
     92         link.setVisible(true);
     93         //area.setBounds(0, 0, Link.getBounds().width, BOTTOMEDGE);
     94         area.setBounds(0, 0, RIGHTEDGE, BOTTOMEDGE);
     95         area.setVisible(true);
     96 
     97         link.addKeyListener(link);
     98         area.addKeyListener(link);
     99         area.requestFocus();
    100 
    101         levellengths[0] = RIGHTEDGE;
    102         obstacleImages[0] = area.obstacle;
    103 
    104         timer = new Thread(link);
    105         timer.start();
    106     }
    107 
    108     synchronized void faceRight() {
    109         heroImages[0] = area.herostand;
    110         heroImages[1] = area.hero1;
    111         heroImages[2] = area.herostand;
    112         heroImages[3] = area.hero2;
    113         heroImageNo = 0;
    114         heroleft = false;
    115     }
    116 
    117     synchronized void faceLeft() {
    118         heroImages[0] = area.herostandleft;
    119         heroImages[1] = area.hero1left;
    120         heroImages[2] = area.herostandleft;
    121         heroImages[3] = area.hero2left;
    122         heroImageNo = 0;
    123         heroleft = true;
    124     }
    125 
    126     synchronized void getSwordOut() {
    127         hasWeaponOut = true;
    128         if (heroleft) {
    129             heroImages[0] = area.heroswordleft;
    130             heroImages[1] = area.heroswordleft;
    131             heroImages[2] = area.heroswordleft;
    132             heroImages[3] = area.heroswordleft;
    133         } else {
    134             heroImages[0] = area.heroswordright;
    135             heroImages[1] = area.heroswordright;
    136             heroImages[2] = area.heroswordright;
    137             heroImages[3] = area.heroswordright;
    138         }
    139         heroImageNo = 0;
    140     }
    141 
    142     synchronized void getShieldOut() {
    143         hasWeaponOut = true;
    144         if (heroleft) {
    145             heroImages[0] = area.heroshieldleft;
    146             heroImages[1] = area.heroshieldleft;
    147             heroImages[2] = area.heroshieldleft;
    148             heroImages[3] = area.heroshieldleft;
    149         } else {
    150             heroImages[0] = area.heroshieldright;
    151             heroImages[1] = area.heroshieldright;
    152             heroImages[2] = area.heroshieldright;
    153             heroImages[3] = area.heroshieldright;
    154         }
    155         heroImageNo = 0;
    156     }
    157 
    158     synchronized void putWeaponAway() {
    159         hasWeaponOut = false;
    160         if (heroleft)
    161             faceLeft();
    162         else
    163             faceRight();
    164     }
    165 
    166     synchronized void standStill() {
    167         heroImageNo = 0;
    168     }
    169 
    170     public void doLevel(int level) {
    171         // this runs one 'level'
    172         juststarted = true;
    173 
    174         System.out.println("Started level " + level);
    175 
    176         // position Hero at the bottom left
    177         playerPosition = new Point(LEFTEDGE, GROUNDLEVEL);
    178         faceRight();
    179 
    180         // initialise obstacle states
    181         obstacleImageNo = new int[obstacleNumber];
    182         obstacleImageNo[0] = 0;
    183 
    184         // initialise the arrays of enemies, etc
    185         enemyPositions = new Point[enemyNumber];
    186         obstaclePositions = new Point[MAXLEVELS][obstacleNumber];
    187         direction = new int[enemyNumber];
    188         for (int i = 0; i < enemyNumber; i++) {
    189             enemyPositions[i] = new Point(RIGHTEDGE, GROUNDLEVEL);
    190             direction[i] = LEFT;
    191         }
    192         for (int i = 0; i < obstacleNumber; i++) {
    193             switch (level) {
    194             case 1:
    195                 obstaclePositions[level - 1][i] = new Point((RIGHTEDGE + 15) / 2, GROUNDLEVEL);
    196                 System.out.println("Obstacle positioned at (" + (RIGHTEDGE - LEFTEDGE) / 2 + ", " + GROUNDLEVEL + ")");
    197                 break;
    198             default:
    199             }
    200         }
    201 
    202         // position the warp zone at the end of the level
    203         warpzone = new Point(levellengths[level - 1], GROUNDLEVEL);
    204 
    205         // paint the panel here
    206         // area.repaint();
    207         ingame = true;
    208     }
    209 
    210     Point randomPosition() {
    211         return new Point((int) (Math.random() * RIGHTEDGE) / XAMOUNT * XAMOUNT,
    212                 (int) (Math.random() * BOTTOMEDGE) / YAMOUNT * YAMOUNT);
    213     }
    214 
    215     boolean isPlayerPosition(Point p) {
    216         return (p.x == playerPosition.x && p.y == playerPosition.y);
    217     }
    218 
    219     boolean isEnemyPosition(Point p) {
    220         for (int i = 0; i < enemyNumber; i++) {
    221             if (p.x == enemyPositions[i].x && p.y == enemyPositions[i].y)
    222                 return (true);
    223         }
    224         return (false);
    225     }
    226 
    227     boolean isObstaclePosition(Point p) {
    228         for (int i = 0; i < obstacleNumber; i++) {
    229             if (isObstacleX(p) != -1 && isObstacleY(p) != -1) {
    230                 return (true);
    231             }
    232         }
    233         return (false);
    234     }
    235 
    236     boolean checkIfBlockingObstacle(Point p) {
    237         boolean result = false;
    238         for (int i = 0; i < obstacleNumber; i++) {
    239             if (isObstacleX(p) != -1 && isBlockingObstacleY(p) != -1) {
    240                 // piranhaPopping[i] = false;
    241                 result = true;
    242             }
    243             // else piranhaPopping[i] = true;
    244         }
    245         if (!result)
    246             startPosY = GROUNDLEVEL;
    247         return (result);
    248     }
    249 
    250     int isObstacleX(Point p) {
    251         int obstaclex;
    252         for (int i = 0; i < obstacleNumber; i++) {
    253             // if x is >= obstacleposition - (LEFTOFOBSTACLE) and x <= obstacleposition +
    254             // (RIGHTOFOBSTACLE)
    255             obstaclex = obstaclePositions[level - 1][i].x;
    256             if (p.x >= (obstaclex - LEFTOFOBSTACLE) && p.x <= (obstaclex + RIGHTOFOBSTACLE))
    257                 return (i); // return the number of the matching obstacle
    258         }
    259         return (-1);
    260     }
    261 
    262     int isBlockingObstacleY(Point p) {
    263         for (int i = 0; i < obstacleNumber; i++) {
    264             if (p.y <= obstaclePositions[level - 1][i].y - OBSTACLEHEIGHT)
    265                 return (i);
    266         }
    267         return (-1);
    268     }
    269 
    270     int isObstacleY(Point p) {
    271         for (int i = 0; i < obstacleNumber; i++) {
    272             if (p.y > obstaclePositions[level - 1][i].y - OBSTACLEHEIGHT)
    273                 return (i);
    274         }
    275         return (-1);
    276     }
    277 
    278     int randomMove() {
    279         // return + or - value (randomly)
    280         if (Math.random() >= 0.5)
    281             return (24);
    282         else
    283             return (-24);
    284     }
    285 
    286     private synchronized void incKeysDown(int whichone) {
    287         keysdown[whichone] = 1;
    288     }
    289 
    290     private synchronized void decKeysDown(int whichone) {
    291         keysdown[whichone] = 0;
    292     }
    293 
    294     // this class will use just the key pressed event
    295     @Override
    296     public void keyPressed(KeyEvent e) {
    297         if (ingame) {
    298             if (!((e.getKeyCode() == KeyEvent.VK_LEFT && playerPosition.x <= (LEFTEDGE + XAMOUNT))
    299                     || (e.getKeyCode() == KeyEvent.VK_RIGHT && playerPosition.x >= (RIGHTEDGE - XAMOUNT)))) {
    300                 // valid move: move the player and then move the enemies
    301                 if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    302                     herocrouching = true;
    303                     incKeysDown(DOWNDOWN);
    304                 } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    305                     incKeysDown(LEFTDOWN);
    306                     leftPressed();
    307                 } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    308                     incKeysDown(RIGHTDOWN);
    309                     rightPressed();
    310                 } else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
    311                     // System.out.println("Jump when jumping is " + jumping);
    312                     if (!jumping) {
    313                         // incKeysDown(SPACEDOWN);
    314                         startPosY = playerPosition.y;
    315                         jumping = true;
    316                         onTheWayUp = true;
    317                     }
    318                 } else if (e.getKeyCode() == KeyEvent.VK_Z) {
    319                     getSwordOut();
    320                 } else if (e.getKeyCode() == KeyEvent.VK_X) {
    321                     getShieldOut();
    322                 }
    323                 if (isEnemyPosition(playerPosition)) {
    324                     System.out.println("The Player ran into an enemy!! Press the Enter key to restart the level");
    325                     ingame = false;
    326                 }
    327                 // area.repaint();
    328                 // System.out.println("Hero's position = (" + playerPosition.x + ", " +
    329                 // playerPosition.y + ")");
    330                 // System.out.println(" ");
    331             } // if valid key press
    332         } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    333             doLevel(++level);
    334         }
    335     }
    336 
    337     void leftPressed() {
    338         if (!herocrouching) {
    339             // superjump = true; // if jumping
    340             // if Hero was facing right, turn him left
    341             if (!heroleft && !hasWeaponOut)
    342                 faceLeft();
    343             else {
    344                 // if the target position is not occupied by a obstacle...
    345                 for (int i = 0; i < obstacleNumber; i++) {
    346                     if (isObstaclePosition(new Point(playerPosition.x - XAMOUNT, playerPosition.y)))
    347                         return; // can't move
    348                 }
    349                 playerPosition.x -= XAMOUNT;
    350                 incrementHeroImage();
    351             }
    352         }
    353     }
    354 
    355     void rightPressed() {
    356         if (!herocrouching) {
    357             // superjump = true; // if jumping
    358             // if Hero was facing left, turn him right
    359             if (heroleft && !hasWeaponOut)
    360                 faceRight();
    361             else {
    362                 for (int i = 0; i < obstacleNumber; i++) {
    363                     if (isObstaclePosition(new Point(playerPosition.x + XAMOUNT, playerPosition.y)))
    364                         return; // can't move
    365                 }
    366                 playerPosition.x += XAMOUNT;
    367                 incrementHeroImage();
    368             }
    369         }
    370     }
    371 
    372     @Override
    373     public void run() {
    374         while (true) {
    375             if (juststarted) {
    376                 try {
    377                     Thread.sleep(750);
    378                 } catch (Exception e) {
    379                 }
    380                 area.repaint();
    381                 juststarted = false;
    382             }
    383             try {
    384                 Thread.sleep(DELAY);
    385             } catch (InterruptedException e) {
    386             }
    387             if (ingame) {
    388                 // System.out.println("Run: BEFORE: Hero's position = (" + playerPosition.x + ",
    389                 // " + playerPosition.y + ")");
    390                 if (keysdown[LEFTDOWN] == 0 && keysdown[RIGHTDOWN] == 0
    391                         && keysdown[DOWNDOWN] == 0 /*
    392                                                     * && keysdown[SPACEDOWN] == 0
    393                                                     */)
    394                     standStill();
    395 
    396                 if (keysdown[LEFTDOWN] > 0)
    397                     leftPressed();
    398                 else if (keysdown[RIGHTDOWN] > 0)
    399                     rightPressed();
    400 
    401                 // for each obstacle, cycle through the piranha pictures
    402                 for (int i = 0; i < obstacleNumber; i++) {
    403                     incrementObstacleImage(i);
    404                 }
    405 
    406                 /*
    407                  * // for each enemy, move the enemy in the direction it was going for (int i=0;
    408                  * i < enemyPositions.length; i++) { if (!deadHero(enemyPositions[i])) {
    409                  * enemyPositions[i] = move(enemyPositions[i], direction[i]); } // if there is a
    410                  * obstacle at that position, fall into it and decrement count of enemies // and
    411                  * set that enemy's position to -1, -1 if
    412                  * (isObstaclePosition(enemyPositions[i])) {
    413                  * System.out.println("A enemy fell into a obstacle");
    414                  * 
    415                  * enemyPositions[i] = new Point(-1, -1); enemiesRemaining--;
    416                  * System.out.println(enemyNumber-enemiesRemaining + " down, " +
    417                  * enemiesRemaining + " to go..."); } // if player is caught by a enemy or all
    418                  * enemies are gone, end the game if (isPlayerPosition(enemyPositions[i])) {
    419                  * System.out.
    420                  * println(""Mmm! Brains...". The Player is dead. Press the Enter key to restart the level"
    421                  * ); level--; // because it will be incremented in a minute and we want to stay
    422                  * on the same 'level' ingame = false; } } if (enemiesRemaining == 0) {
    423                  * System.out.
    424                  * println("All the enemies are gone -- you won!! Press the Enter key to start the next level"
    425                  * ); enemyNumber++; if (obstacleNumber > 2) obstacleNumber--; ingame = false; }
    426                  */
    427                 if (onTheWayUp) {
    428                     // System.out.println("OnTheWayUp. Start Y Position =" + startPosY);
    429                     if (playerPosition.y > startPosY - JUMPAMOUNT)
    430                         playerPosition = new Point(playerPosition.x, playerPosition.y - RISEAMOUNT);
    431                     else {
    432                         onTheWayUp = false;
    433                     }
    434                 } else {
    435                     int obstacleno = isObstacleX(playerPosition);
    436                     if (obstacleno == -1) { // no obstacle at this position
    437                         if (onTheWayUp == false) {
    438                             if (playerPosition.y < startPosY)
    439                                 playerPosition = new Point(playerPosition.x, playerPosition.y + FALLAMOUNT);
    440                             else
    441                                 jumping = false;
    442                         }
    443                     } else {
    444                         Point obstaclepos = obstaclePositions[level - 1][obstacleno];
    445                         // if hero's y position <= obstacle's height
    446                         if (playerPosition.y <= (obstaclepos.y - OBSTACLEHEIGHT)) { // can't land on the obstacle if
    447                                                                                     // just < (??!)
    448                             // allow hero to land on the obstacle
    449                             // System.out.println("Allow Hero to land (or stay) on obstacle");
    450                             jumping = false;
    451                             playerPosition = new Point(playerPosition.x, obstaclepos.y - OBSTACLEHEIGHT);
    452                             // if the piranha was up, Hero dies
    453                             if (obstacleImages[obstacleImageNo[obstacleno]] != area.obstacle) {
    454                                 System.out.println("Hero dies!!");
    455                                 ingame = false;
    456 
    457                             }
    458                             /*
    459                              * else { // otherwise stop this Piranha piranhaPopping[obstacleno] = false; }
    460                              */
    461                         } else {
    462                             if (onTheWayUp == false) {
    463                                 if (playerPosition.y < startPosY)
    464                                     playerPosition = new Point(playerPosition.x, playerPosition.y + FALLAMOUNT);
    465                                 else
    466                                     jumping = false;
    467                             }
    468                         }
    469                     }
    470                 }
    471                 checkIfBlockingObstacle(playerPosition);
    472                 // System.out.println("Run: AFTER: Hero's position = (" + playerPosition.x + ",
    473                 // " + playerPosition.y + ")");
    474                 area.repaint();
    475             }
    476         }
    477     }
    478 
    479     synchronized void incrementObstacleImage(int i) {
    480         obstacleImageNo[i]++;
    481         if (obstacleImageNo[i] == OBSTACLEIMAGES)
    482             obstacleImageNo[i] = 0;
    483     }
    484 
    485     synchronized void incrementHeroImage() {
    486         heroImageNo++;
    487         if (heroImageNo == HEROIMAGES)
    488             heroImageNo = 0;
    489     }
    490 
    491     Point move(Point start, int direction) {
    492         return (new Point(start.x + direction, start.y));
    493     }
    494 
    495     boolean deadHero(Point p) {
    496         return (p.x == -1 && p.y == -1);
    497     }
    498 
    499     @Override
    500     public void keyReleased(KeyEvent e) {
    501         // boolean needrepaint = false;
    502         if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    503             herocrouching = false;
    504             decKeysDown(DOWNDOWN);
    505             // needrepaint = true;
    506         }
    507         /*
    508          * else if (e.getKeyCode() == KeyEvent.VK_SPACE) { decKeysDown(SPACEDOWN); }
    509          */
    510         else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    511             decKeysDown(LEFTDOWN);
    512             // superjump = false;
    513         } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    514             decKeysDown(RIGHTDOWN);
    515             // superjump = false;
    516         } else
    517             putWeaponAway();
    518         // if (needrepaint) area.repaint();
    519     }
    520 
    521     @Override
    522     public void keyTyped(KeyEvent e) {
    523     }
    524 
    525     synchronized Image getHeroImage() {
    526         return (heroImages[heroImageNo]);
    527     }
    528 
    529     synchronized Image getObstacleImage(int obstaclenum) {
    530         return (obstacleImages[obstacleImageNo[obstaclenum]]);
    531     }
    532 
    533 }