Zombie.java (11859B)
1 2 /* Copyright (c) M Percival 2002 */ 3 /* Zombie game Created October 2002 */ 4 5 import java.awt.Color; 6 import java.awt.Point; 7 import java.awt.event.KeyEvent; 8 import java.awt.event.KeyListener; 9 10 import javax.swing.JFrame; 11 12 public class Zombie extends JFrame implements KeyListener, Runnable { 13 private static final long serialVersionUID = 8654912377879331966L; 14 // all member variables 'static' because shared with the zombie action thread 15 private static ZombieArea area; 16 private static boolean ingame = false; 17 private boolean juststarted = false; 18 private static int level = 1; 19 private static int zombiesRemaining; 20 protected static Point[] zombiePositions; 21 protected static Point playerPosition; 22 protected static Point[] pitPositions; 23 private static Thread zombies; 24 25 protected static int pitNumber = 15; 26 protected static int zombieNumber = 10; 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 public static void main(String[] args) { 40 Zombie zombie = new Zombie(); 41 zombie.setLayout(null); 42 zombie.setBackground(Color.gray); 43 zombie.setSize(RIGHTEDGE, BOTTOMEDGE); 44 zombie.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 45 zombie.setTitle("Zombie"); 46 47 area = new ZombieArea(zombie); 48 zombie.add(area); 49 // RIGHTEDGE = getBounds().width - 1; 50 // BOTTOMEDGE = getBounds().height - 1; 51 XAMOUNT = 12; 52 YAMOUNT = 12; 53 zombie.setVisible(true); 54 area.setBounds(0, 0, RIGHTEDGE, BOTTOMEDGE); 55 area.setVisible(true); 56 57 zombie.addKeyListener(zombie); 58 area.addKeyListener(zombie); 59 area.requestFocus(); 60 61 zombies = new Thread(zombie); 62 zombies.start(); 63 } 64 65 public void doLevel(int level) { 66 // this runs one 'level' 67 // create arrays of pits and zombies here. 68 // Maybe each level will have different numbers? 69 juststarted = true; 70 Point temppoint; 71 pitPositions = new Point[pitNumber]; 72 zombiePositions = new Point[zombieNumber]; 73 for (int i = 0; i < zombieNumber; i++) 74 zombiePositions[i] = new Point(0, 0); 75 for (int i = 0; i < pitNumber; i++) 76 pitPositions[i] = new Point(0, 0); 77 78 System.out.println("Started level " + level + ": " + zombieNumber + " zombies and " + pitNumber + " pits"); 79 80 // randomly position 1 player, x zombies and y pits 81 playerPosition = randomPosition(); 82 83 for (int i = 0; i < zombieNumber; i++) { 84 temppoint = randomPosition(); 85 while (isPlayerPosition(temppoint) || isZombiePosition(temppoint)) { 86 // don't position any zombie on the player or on top of another zombie 87 temppoint = randomPosition(); 88 } 89 zombiePositions[i] = temppoint; 90 } 91 92 for (int i = 0; i < pitNumber; i++) { 93 temppoint = randomPosition(); 94 while (isPlayerPosition(temppoint) || isPitPosition(temppoint) || isZombiePosition(temppoint)) { 95 // don't position any zombie at the player, a zombie or another pit 96 temppoint = randomPosition(); 97 } 98 99 pitPositions[i] = temppoint; 100 } 101 102 zombiesRemaining = zombieNumber; 103 // paint the panel here 104 area.repaint(); 105 ingame = true; 106 } 107 108 private Point randomPosition() { 109 return new Point((int) (Math.random() * RIGHTEDGE) / XAMOUNT * XAMOUNT, 110 (int) (Math.random() * BOTTOMEDGE) / YAMOUNT * YAMOUNT); 111 } 112 113 private boolean isPlayerPosition(Point p) { 114 return (p.x == playerPosition.x && p.y == playerPosition.y); 115 } 116 117 private boolean isZombiePosition(Point p) { 118 for (int i = 0; i < zombieNumber; i++) { 119 if (p.x == zombiePositions[i].x && p.y == zombiePositions[i].y) 120 return (true); 121 } 122 return (false); 123 } 124 125 private int isInline(Point p) { 126 // is the new position in the same row as the player? 127 if (Math.abs(p.x - playerPosition.x) < XAMOUNT) { 128 // see whether there is another zombie between this position and the player 129 if (playerPosition.y > p.y) { 130 for (int i = 0; i < zombieNumber; i++) { 131 if (p.x == zombiePositions[i].x && p.y < zombiePositions[i].y) 132 return (X); 133 } 134 } else { // playerPosition y < p.y 135 for (int i = 0; i < zombieNumber; i++) { 136 if (p.x == zombiePositions[i].x && p.y > zombiePositions[i].y) 137 return (X); 138 } 139 } 140 } else if (Math.abs(p.y - playerPosition.y) < YAMOUNT) { 141 // see whether there is another zombie between this position and the player 142 if (playerPosition.x > p.x) { 143 for (int i = 0; i < zombieNumber; i++) { 144 if (p.y == zombiePositions[i].y && p.x < zombiePositions[i].x) 145 return (Y); 146 } 147 } else { // playerPosition x < p.x 148 for (int i = 0; i < zombieNumber; i++) { 149 if (p.y == zombiePositions[i].y && p.x > zombiePositions[i].x) 150 return (Y); 151 } 152 } 153 } 154 return (NOT); 155 } 156 157 private boolean isPitPosition(Point p) { 158 for (int i = 0; i < pitNumber; i++) { 159 if (p.x == pitPositions[i].x && p.y == pitPositions[i].y) 160 return (true); 161 } 162 163 return (false); 164 } 165 166 private Point moveCloser(Point original, Point target) { 167 Point result = new Point(original); 168 int inlineType = isInline(original); 169 if (inlineType != X) { 170 if (original.x < target.x) 171 result.x = original.x + (XAMOUNT / 2); 172 else if (original.x > target.x) 173 result.x = original.x - (XAMOUNT / 2); 174 } else { 175 // move out of the Y alignment - randomly left or right 176 result.x += randomMove(); 177 } 178 if (inlineType != Y) { 179 if (original.y < target.y) 180 result.y = original.y + (YAMOUNT / 2); 181 else if (original.y > target.y) 182 result.y = original.y - (YAMOUNT / 2); 183 } else { 184 // move out of the Y alignment - randomly up or down 185 result.y += randomMove(); 186 } 187 if (isZombiePosition(result)) { 188 if (isZombiePosition(new Point(result.x, original.y))) { 189 if (isZombiePosition(new Point(original.x, result.y))) 190 result = original; 191 else 192 result = new Point(original.x, result.y); 193 } else 194 result = new Point(result.x, original.y); 195 } 196 return (result); 197 } 198 199 private int randomMove() { 200 // return + or - value (randomly) 201 if (Math.random() >= 0.5) 202 return (24); 203 else 204 return (-24); 205 } 206 207 // this class will use just the key pressed event 208 @Override 209 public void keyPressed(KeyEvent e) { 210 if (ingame) { 211 if (!((e.getKeyCode() == KeyEvent.VK_DOWN && playerPosition.y >= (BOTTOMEDGE - YAMOUNT)) 212 || (e.getKeyCode() == KeyEvent.VK_UP && playerPosition.y <= (TOPEDGE + YAMOUNT)) 213 || (e.getKeyCode() == KeyEvent.VK_LEFT && playerPosition.x <= (LEFTEDGE + XAMOUNT)) 214 || (e.getKeyCode() == KeyEvent.VK_RIGHT && playerPosition.x >= (RIGHTEDGE - XAMOUNT)))) { 215 // valid move: move the player and then move the zombies 216 if (e.getKeyCode() == KeyEvent.VK_DOWN) { 217 playerPosition.y += YAMOUNT; 218 } else if (e.getKeyCode() == KeyEvent.VK_UP) { 219 playerPosition.y -= YAMOUNT; 220 } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { 221 playerPosition.x -= XAMOUNT; 222 } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 223 playerPosition.x += XAMOUNT; 224 } 225 if (isZombiePosition(playerPosition)) { 226 System.out.println("The Player ran into a zombie!! Press the Enter key to restart the level"); 227 ingame = false; 228 } 229 if (isPitPosition(playerPosition)) { 230 System.out.println("The Player ran into a pit!! Press the Enter key to restart the level"); 231 ingame = false; 232 } 233 area.repaint(); 234 } // if valid key press 235 } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { 236 doLevel(level++); 237 } 238 } 239 240 @Override 241 public void run() { 242 while (true) { 243 if (juststarted) { 244 try { 245 Thread.sleep(750); 246 } catch (Exception e) { 247 } 248 juststarted = false; 249 } 250 try { 251 Thread.sleep(DELAY); 252 } catch (InterruptedException e) { 253 } 254 if (ingame) { 255 // for each zombie, move the zombie closer to the player 256 for (int i = 0; i < zombiePositions.length; i++) { 257 if (!deadZombie(zombiePositions[i])) { 258 zombiePositions[i] = moveCloser(zombiePositions[i], playerPosition); 259 } 260 // if there is a pit at that position, fall into it and decrement count of 261 // zombies 262 // and set that zombie's position to -1, -1 263 if (isPitPosition(zombiePositions[i])) { 264 System.out.println("A zombie fell into a pit"); 265 explosionx = zombiePositions[i].x; 266 explosiony = zombiePositions[i].y; 267 268 zombiePositions[i] = new Point(-1, -1); 269 zombiesRemaining--; 270 System.out 271 .println(zombieNumber - zombiesRemaining + " down, " + zombiesRemaining + " to go..."); 272 } 273 // if player is caught by a zombie or all zombies are gone, end the game 274 if (isPlayerPosition(zombiePositions[i])) { 275 System.out.println( 276 ""Mmm! Brains...". The Player is dead. Press the Enter key to restart the level"); 277 level--; // because it will be incremented in a minute and we want to stay on the same 278 // 'level' 279 ingame = false; 280 } 281 } 282 if (zombiesRemaining == 0) { 283 System.out.println( 284 "All the zombies are gone -- you won!! Press the Enter key to start the next level"); 285 zombieNumber++; 286 if (pitNumber > 2) 287 pitNumber--; 288 ingame = false; 289 } else 290 area.repaint(); 291 } 292 } 293 } 294 295 private boolean deadZombie(Point p) { 296 return (p.x == -1 && p.y == -1); 297 } 298 299 @Override 300 public void keyReleased(KeyEvent e) { 301 } 302 303 @Override 304 public void keyTyped(KeyEvent e) { 305 } 306 }