old-java-games

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

Tank.java (17243B)


      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 2002                          */
     10 /* Tank game                      Created October 2002     */
     11 
     12 public class Tank extends JFrame implements KeyListener, Runnable {
     13     private static final long serialVersionUID = 2750159877444817519L;
     14     // all member variables 'static' because shared with the enemy action thread
     15     private static TankArea area;
     16     private static boolean ingame = false;
     17     private boolean juststarted = false;
     18     private static int level = 1;
     19     private static int enemiesRemaining;
     20     protected static Point[] enemyPositions;
     21     protected static Point playerPosition;
     22     protected static Point[] pitPositions;
     23     private static Thread enemies;
     24 
     25     protected static int pitNumber = 15;
     26     protected static int enemyNumber = 1;
     27     protected static int RIGHTEDGE = 1200;
     28     protected static final int LEFTEDGE = 0;
     29     protected static final int TOPEDGE = 0;
     30     protected static int BOTTOMEDGE = 1000;
     31     protected static int XAMOUNT = 5;
     32     protected static int YAMOUNT = 5;
     33     private static final int X = 1;
     34     private static final int Y = 2;
     35     private static final int NOT = 3;
     36     private static final int DELAY = 125;
     37     protected int explosionx = -1, explosiony = -1;
     38 
     39     // tank game stuff
     40     boolean up = true, down = false, left = false, right = false, shooting = false;
     41     static int NOTSHOOTING = 0;
     42     static int SHOOTING = 1;
     43     static int FIRSTUP = 0;
     44     static int FIRSTDOWN = 2;
     45     static int FIRSTLEFT = 4;
     46     static int FIRSTRIGHT = 6;
     47     int goodImageNo = FIRSTUP; // TODO - randomise
     48     int[] enemyImageNo;
     49     boolean[] enemyShooting;
     50     Image[][] goodImages = new Image[8][2]; // up up2 down down2 left left2 right right2 x SHOOTING and NON_SHOOTING
     51     Image[][] badImages = new Image[8][2]; // up up2 down down2 left left2 right right2 x SHOOTING and NON_SHOOTING
     52 
     53     public static void main(String[] args) {
     54         Tank tank = new Tank();
     55         tank.setLayout(null);
     56         tank.setBackground(Color.gray);
     57         tank.setSize(RIGHTEDGE, BOTTOMEDGE);
     58         tank.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     59         tank.setTitle("Tank");
     60 
     61         area = new TankArea(tank);
     62         tank.add(area);
     63         //RIGHTEDGE = tank.getBounds().width - 1;
     64         //BOTTOMEDGE = tank.getBounds().height - 1;
     65         XAMOUNT = 12;
     66         YAMOUNT = 12;
     67         tank.setVisible(true);
     68         area.setBounds(0, 0, RIGHTEDGE, BOTTOMEDGE);
     69         area.setVisible(true);
     70 
     71         tank.addKeyListener(tank);
     72         area.addKeyListener(tank);
     73         area.requestFocus();
     74 
     75         tank.goodImages[FIRSTUP][NOTSHOOTING] = area.tankup;
     76         tank.goodImages[FIRSTUP + 1][NOTSHOOTING] = area.tankup2;
     77         tank.goodImages[FIRSTUP][SHOOTING] = area.tankupshoot;
     78         tank.goodImages[FIRSTUP + 1][SHOOTING] = area.tankupshoot2;
     79 
     80         tank.goodImages[FIRSTDOWN][NOTSHOOTING] = area.tankdown;
     81         tank.goodImages[FIRSTDOWN + 1][NOTSHOOTING] = area.tankdown2;
     82         tank.goodImages[FIRSTDOWN][SHOOTING] = area.tankdownshoot;
     83         tank.goodImages[FIRSTDOWN + 1][SHOOTING] = area.tankdownshoot2;
     84 
     85         tank.goodImages[FIRSTLEFT][NOTSHOOTING] = area.tankleft;
     86         tank.goodImages[FIRSTLEFT + 1][NOTSHOOTING] = area.tankleft2;
     87         tank.goodImages[FIRSTLEFT][SHOOTING] = area.tankleftshoot;
     88         tank.goodImages[FIRSTLEFT + 1][SHOOTING] = area.tankleftshoot2;
     89         
     90         tank.goodImages[FIRSTRIGHT][NOTSHOOTING] = area.tankright;
     91         tank.goodImages[FIRSTRIGHT + 1][NOTSHOOTING] = area.tankright2;
     92         tank.goodImages[FIRSTRIGHT][SHOOTING] = area.tankrightshoot;
     93         tank.goodImages[FIRSTRIGHT + 1][SHOOTING] = area.tankrightshoot2;
     94 
     95         tank.badImages[FIRSTUP][NOTSHOOTING] = area.badtankup;
     96         tank.badImages[FIRSTUP + 1][NOTSHOOTING] = area.badtankup2;
     97         tank.badImages[FIRSTUP][SHOOTING] = area.badtankupshoot;
     98         tank.badImages[FIRSTUP + 1][SHOOTING] = area.badtankupshoot2;
     99 
    100         tank.badImages[FIRSTDOWN][NOTSHOOTING] = area.badtankdown;
    101         tank.badImages[FIRSTDOWN + 1][NOTSHOOTING] = area.badtankdown2;
    102         tank.badImages[FIRSTDOWN][SHOOTING] = area.badtankdownshoot;
    103         tank.badImages[FIRSTDOWN + 1][SHOOTING] = area.badtankdownshoot2;
    104 
    105         tank.badImages[FIRSTLEFT][NOTSHOOTING] = area.badtankleft;
    106         tank.badImages[FIRSTLEFT + 1][NOTSHOOTING] = area.badtankleft2;
    107         tank.badImages[FIRSTLEFT][SHOOTING] = area.badtankleftshoot;
    108         tank.badImages[FIRSTLEFT + 1][SHOOTING] = area.badtankleftshoot2;
    109 
    110         tank.badImages[FIRSTRIGHT][NOTSHOOTING] = area.badtankright;
    111         tank.badImages[FIRSTRIGHT + 1][NOTSHOOTING] = area.badtankright2;
    112         tank.badImages[FIRSTRIGHT][SHOOTING] = area.badtankrightshoot;
    113         tank.badImages[FIRSTRIGHT + 1][SHOOTING] = area.badtankrightshoot2;
    114 
    115         enemies = new Thread(tank);
    116         enemies.start();
    117     }
    118 
    119     public void doLevel(int level) {
    120         // this runs one 'level'
    121         // create arrays of pits and enemies here.
    122         // Maybe each level will have different numbers?
    123         juststarted = true;
    124         Point temppoint;
    125         pitPositions = new Point[pitNumber];
    126         enemyPositions = new Point[enemyNumber];
    127         for (int i = 0; i < enemyNumber; i++)
    128             enemyPositions[i] = new Point(0, 0);
    129         for (int i = 0; i < pitNumber; i++)
    130             pitPositions[i] = new Point(0, 0);
    131 
    132         enemyImageNo = new int[enemyNumber];
    133         enemyShooting = new boolean[enemyNumber];
    134         for (int i = 0; i < enemyNumber; i++) {
    135             enemyShooting[i] = false;
    136             enemyImageNo[i] = FIRSTUP; // TODO - randomise
    137         }
    138         System.out.println("Started level " + level + ": " + enemyNumber + " enemies and " + pitNumber + " pits");
    139 
    140         // randomly position 1 player, x enemies and y pits
    141         playerPosition = randomPosition();
    142 
    143         for (int i = 0; i < enemyNumber; i++) {
    144             temppoint = randomPosition();
    145             while (isPlayerPosition(temppoint) || isTankPosition(temppoint)) {
    146                 // don't position any enemy on the player or on top of another enemy
    147                 temppoint = randomPosition();
    148             }
    149             enemyPositions[i] = temppoint;
    150         }
    151 
    152         for (int i = 0; i < pitNumber; i++) {
    153             temppoint = randomPosition();
    154             while (isPlayerPosition(temppoint) || isPitPosition(temppoint) || isTankPosition(temppoint)) {
    155                 // don't position any enemy at the player, an enemy or another pit
    156                 temppoint = randomPosition();
    157             }
    158             pitPositions[i] = temppoint;
    159         }
    160 
    161         enemiesRemaining = enemyNumber;
    162         // paint the panel here
    163         area.repaint();
    164         ingame = true;
    165     }
    166 
    167     synchronized void incrementImageNo() {
    168         goodImageNo++;
    169         if ((goodImageNo % 2) == 0)
    170             goodImageNo -= 2;
    171     }
    172 
    173     synchronized void incrementImageNo(int enemyNo) {
    174         enemyImageNo[enemyNo]++;
    175         if ((enemyImageNo[enemyNo] % 2) == 0)
    176             enemyImageNo[enemyNo] -= 2;
    177     }
    178 
    179     void goLeft(int enemyno) {
    180         if (enemyImageNo[enemyno] == FIRSTLEFT || enemyImageNo[enemyno] == FIRSTLEFT + 1) {
    181             incrementImageNo(enemyno);
    182         } else
    183             enemyImageNo[enemyno] = FIRSTLEFT;
    184     }
    185 
    186     void goLeft() {
    187         if (goodImageNo == FIRSTLEFT || goodImageNo == FIRSTLEFT + 1) {
    188             incrementImageNo();
    189         } else
    190             goodImageNo = FIRSTLEFT;
    191     }
    192 
    193     void goRight(int enemyno) {
    194         if (enemyImageNo[enemyno] == FIRSTRIGHT || enemyImageNo[enemyno] == FIRSTRIGHT + 1) {
    195             incrementImageNo(enemyno);
    196         } else
    197             enemyImageNo[enemyno] = FIRSTRIGHT;
    198     }
    199 
    200     void goRight() {
    201         if (goodImageNo == FIRSTRIGHT || goodImageNo == FIRSTRIGHT + 1) {
    202             incrementImageNo();
    203         } else
    204             goodImageNo = FIRSTRIGHT;
    205     }
    206 
    207     void goUp(int enemyno) {
    208         if (enemyImageNo[enemyno] == FIRSTUP || enemyImageNo[enemyno] == FIRSTUP + 1) {
    209             incrementImageNo(enemyno);
    210         } else
    211             enemyImageNo[enemyno] = FIRSTUP;
    212     }
    213 
    214     void goUp() {
    215         if (goodImageNo == FIRSTUP || goodImageNo == FIRSTUP + 1) {
    216             incrementImageNo();
    217         } else
    218             goodImageNo = FIRSTUP;
    219     }
    220 
    221     void goDown(int enemyno) {
    222         if (enemyImageNo[enemyno] == FIRSTDOWN || enemyImageNo[enemyno] == FIRSTDOWN + 1) {
    223             incrementImageNo(enemyno);
    224         } else
    225             enemyImageNo[enemyno] = FIRSTDOWN;
    226     }
    227 
    228     void goDown() {
    229         if (goodImageNo == FIRSTDOWN || goodImageNo == FIRSTDOWN + 1) {
    230             incrementImageNo();
    231         } else
    232             goodImageNo = FIRSTDOWN;
    233     }
    234 
    235     private Point randomPosition() {
    236         return new Point((int) (Math.random() * RIGHTEDGE) / XAMOUNT * XAMOUNT,
    237                 (int) (Math.random() * BOTTOMEDGE) / YAMOUNT * YAMOUNT);
    238     }
    239 
    240     private boolean isPlayerPosition(Point p) {
    241         return (p.x == playerPosition.x && p.y == playerPosition.y);
    242     }
    243 
    244     private boolean isTankPosition(Point p) {
    245         for (int i = 0; i < enemyNumber; i++) {
    246             if (p.x == enemyPositions[i].x && p.y == enemyPositions[i].y)
    247                 return (true);
    248         }
    249         return (false);
    250     }
    251 
    252     private int isInline(Point p) {
    253         // is the new position in the same row as the player?
    254         if (Math.abs(p.x - playerPosition.x) < XAMOUNT) {
    255             // see whether there is another enemy between this position and the player
    256             if (playerPosition.y > p.y) {
    257                 for (int i = 0; i < enemyNumber; i++) {
    258                     if (p.x == enemyPositions[i].x && p.y < enemyPositions[i].y)
    259                         return (X);
    260                 }
    261             } else { // playerPosition y < p.y
    262                 for (int i = 0; i < enemyNumber; i++) {
    263                     if (p.x == enemyPositions[i].x && p.y > enemyPositions[i].y)
    264                         return (X);
    265                 }
    266             }
    267         } else if (Math.abs(p.y - playerPosition.y) < YAMOUNT) {
    268             // see whether there is another enemy between this position and the player
    269             if (playerPosition.x > p.x) {
    270                 for (int i = 0; i < enemyNumber; i++) {
    271                     if (p.y == enemyPositions[i].y && p.x < enemyPositions[i].x)
    272                         return (Y);
    273                 }
    274             } else { // playerPosition x < p.x
    275                 for (int i = 0; i < enemyNumber; i++) {
    276                     if (p.y == enemyPositions[i].y && p.x > enemyPositions[i].x)
    277                         return (Y);
    278                 }
    279             }
    280         }
    281         return (NOT);
    282     }
    283 
    284     private boolean isPitPosition(Point p) {
    285         for (int i = 0; i < pitNumber; i++) {
    286             if (p.x == pitPositions[i].x && p.y == pitPositions[i].y)
    287                 return (true);
    288         }
    289         return (false);
    290     }
    291 
    292     private Point moveCloser(int enemyNo, Point original, Point target) {
    293         Point result = new Point(original);
    294         int inlineType = isInline(original);
    295         // allowed to move EITHER X or Y but not both
    296         if (Math.random() >= 0.5) {
    297             // move in X direction
    298             if (inlineType != X) {
    299                 if (original.x < target.x) {
    300                     result.x = original.x + (XAMOUNT / 2);
    301                     goRight(enemyNo);
    302                 } else if (original.x > target.x) {
    303                     result.x = original.x - (XAMOUNT / 2);
    304                     goLeft(enemyNo);
    305                 }
    306             }
    307         } else {
    308             // move in Y direction
    309             if (inlineType != Y) {
    310                 if (original.y < target.y) {
    311                     result.y = original.y + (YAMOUNT / 2);
    312                     goDown(enemyNo);
    313                 } else if (original.y > target.y) {
    314                     result.y = original.y - (YAMOUNT / 2);
    315                     goUp(enemyNo);
    316                 }
    317             }
    318         }
    319         /*
    320          * if (isTankPosition(result)) { if (isTankPosition(new Point(result.x,
    321          * original.y))) { if (isTankPosition(new Point(original.x, result.y))) result =
    322          * original; else result = new Point(original.x, result.y); } else result = new
    323          * Point(result.x, original.y); }
    324          */
    325         inlineType = isInline(result);
    326         if (inlineType == X) {
    327             // fire along the X axis
    328         } else if (inlineType == Y) {
    329             // fire along the Y axis
    330         }
    331         return (result);
    332     }
    333 
    334     /*
    335      * private int randomMove() { // return + or - value (randomly) if
    336      * (Math.random() >= 0.5) return(24); else return(-24); }
    337      */
    338 
    339     // this class will use just the key pressed event
    340     @Override
    341     public void keyPressed(KeyEvent e) {
    342         if (ingame) {
    343             if (!((e.getKeyCode() == KeyEvent.VK_DOWN && playerPosition.y >= (BOTTOMEDGE - YAMOUNT))
    344                     || (e.getKeyCode() == KeyEvent.VK_UP && playerPosition.y <= (TOPEDGE + YAMOUNT))
    345                     || (e.getKeyCode() == KeyEvent.VK_LEFT && playerPosition.x <= (LEFTEDGE + XAMOUNT))
    346                     || (e.getKeyCode() == KeyEvent.VK_RIGHT && playerPosition.x >= (RIGHTEDGE - XAMOUNT)))) {
    347                 // valid move: move the player and then move the enemies
    348                 if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    349                     playerPosition.y += YAMOUNT;
    350                     goDown();
    351                 } else if (e.getKeyCode() == KeyEvent.VK_UP) {
    352                     playerPosition.y -= YAMOUNT;
    353                     goUp();
    354                 } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    355                     playerPosition.x -= XAMOUNT;
    356                     goLeft();
    357                 } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    358                     playerPosition.x += XAMOUNT;
    359                     goRight();
    360                 }
    361                 if (isTankPosition(playerPosition)) {
    362                     System.out.println("The Player ran into an enemy!! Press the Enter key to restart the level");
    363                     ingame = false;
    364                 }
    365                 if (isPitPosition(playerPosition)) {
    366                     System.out.println("The Player ran into a pit!! Press the Enter key to restart the level");
    367                     ingame = false;
    368                 }
    369                 area.repaint();
    370             } // if valid key press
    371         } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    372             doLevel(level++);
    373         }
    374     }
    375 
    376     @Override
    377     public void run() {
    378         while (true) {
    379             if (juststarted) {
    380                 try {
    381                     Thread.sleep(750);
    382                 } catch (Exception e) {
    383                 }
    384                 juststarted = false;
    385             }
    386             try {
    387                 Thread.sleep(DELAY);
    388             } catch (InterruptedException e) {
    389             }
    390             if (ingame) {
    391                 // for each enemy, move the enemy closer to the player
    392                 for (int i = 0; i < enemyPositions.length; i++) {
    393                     if (!deadTank(enemyPositions[i])) {
    394                         enemyPositions[i] = moveCloser(i, enemyPositions[i], playerPosition);
    395                     }
    396                     // if there is a pit at that position, fall into it and decrement count of
    397                     // enemies
    398                     // and set that enemy's position to -1, -1
    399                     if (isPitPosition(enemyPositions[i])) {
    400                         System.out.println("an enemy fell into a pit");
    401                         explosionx = enemyPositions[i].x;
    402                         explosiony = enemyPositions[i].y;
    403 
    404                         enemyPositions[i] = new Point(-1, -1);
    405                         enemiesRemaining--;
    406                         System.out.println(enemyNumber - enemiesRemaining + " down, " + enemiesRemaining + " to go...");
    407                     }
    408                     // if player is caught by an enemy or all enemies are gone, end the game
    409                     if (isPlayerPosition(enemyPositions[i])) {
    410                         System.out.println(
    411                                 ""Mmm! Brains...". The Player is dead. Press the Enter key to restart the level");
    412                         level--; // because it will be incremented in a minute and we want to stay on the same
    413                                  // 'level'
    414                         ingame = false;
    415                     }
    416                 }
    417                 if (enemiesRemaining == 0) {
    418                     System.out.println(
    419                             "All the enemies are gone -- you won!! Press the Enter key to start the next level");
    420                     enemyNumber++;
    421                     if (pitNumber > 2)
    422                         pitNumber--;
    423                     ingame = false;
    424                 } else
    425                     area.repaint();
    426             }
    427         }
    428     }
    429 
    430     private boolean deadTank(Point p) {
    431         return (p.x == -1 && p.y == -1);
    432     }
    433 
    434     @Override
    435     public void keyReleased(KeyEvent e) {
    436     }
    437 
    438     @Override
    439     public void keyTyped(KeyEvent e) {
    440     }
    441 }