Pong.java (8375B)
1 2 /* Copyright (c) Mike Percival 2004 */ 3 /* Pong game Created April 2004 */ 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 Pong extends JFrame implements KeyListener, Runnable { 13 private static final long serialVersionUID = 1018529427970832700L; 14 // all member variables 'static' because shared with the ball action thread 15 private static PongArea area; 16 private static boolean ingame = false; 17 private boolean juststarted = false; 18 private static int level = 1; 19 protected static Point[] ballPositions; 20 protected static Point playerPosition; 21 private static Thread balls; 22 23 protected static int ballNumber = 1; 24 protected static int RIGHTEDGE = 800; 25 protected static final int LEFTEDGE = 0; 26 protected static final int TOPEDGE = 0; 27 protected static int BOTTOMEDGE = 800; 28 protected static int BALL_XAMOUNT = 3; 29 protected static int BALL_YAMOUNT = 3; 30 protected static int PLAYER_XAMOUNT = 12; 31 protected static int PLAYER_YAMOUNT = 12; 32 private static final int DELAY = 15; 33 boolean[] goingLeft, goingRight, goingUp, goingDown; 34 boolean deadball = false; 35 int timeSinceLastBall = 0; 36 37 public static void main(String[] args) { 38 Pong pong = new Pong(); 39 40 pong.setLayout(null); 41 pong.setBackground(Color.black); 42 pong.setSize(RIGHTEDGE, BOTTOMEDGE); 43 pong.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 44 pong.setTitle("Pong"); 45 Pong.area = new PongArea(pong); 46 pong.add(area); 47 //RIGHTEDGE = Pong.getBounds().width - 1; 48 //BOTTOMEDGE = Pong.getBounds().height - 1; 49 pong.setVisible(true); 50 area.setBounds(0, 0, RIGHTEDGE, BOTTOMEDGE); 51 area.setVisible(true); 52 53 pong.addKeyListener(pong); 54 area.addKeyListener(pong); 55 area.requestFocus(); 56 57 balls = new Thread(pong); 58 balls.start(); 59 } 60 61 public void doLevel(int level) { 62 // this runs one 'level' 63 // create arrays of ball balls here. 64 // Maybe each level will have different numbers? 65 juststarted = true; 66 deadball = false; 67 ballNumber = 1; 68 ballPositions = new Point[ballNumber]; 69 goingLeft = new boolean[ballNumber]; 70 goingRight = new boolean[ballNumber]; 71 goingUp = new boolean[ballNumber]; 72 goingDown = new boolean[ballNumber]; 73 74 for (int i = 0; i < ballNumber; i++) { 75 ballPositions[i] = new Point(0, 0); 76 goingLeft[i] = true; 77 goingRight[i] = false; 78 goingUp[i] = false; 79 goingDown[i] = true; 80 } 81 82 // System.out.println("Started level " + level); 83 84 // randomly position 1 player, x balls 85 playerPosition = new Point(RIGHTEDGE - 20, 0); 86 87 for (int i = 0; i < ballNumber; i++) { 88 ballPositions[i] = randomPosition(); 89 } 90 91 // paint the panel here 92 area.repaint(); 93 ingame = true; 94 } 95 96 private Point randomPosition() { 97 Point p = new Point((int) (Math.random() * RIGHTEDGE) / BALL_XAMOUNT * BALL_XAMOUNT, (int) 0); 98 if (p.x >= RIGHTEDGE * 2 / 3) 99 p.x = p.x - RIGHTEDGE / 3; 100 101 return (p); 102 } 103 104 synchronized void addABall() { 105 System.out.println("ADD A BALL!"); 106 Point[] newBallPos = new Point[ballNumber + 1]; 107 boolean[] newgl = new boolean[ballNumber + 1], newgr = new boolean[ballNumber + 1], 108 newgu = new boolean[ballNumber + 1], newgd = new boolean[ballNumber + 1]; 109 110 for (int i = 0; i < ballNumber; i++) { 111 newBallPos[i] = new Point(ballPositions[i]); 112 newgl[i] = goingLeft[i]; 113 newgr[i] = goingRight[i]; 114 newgu[i] = goingUp[i]; 115 newgd[i] = goingDown[i]; 116 } 117 118 newBallPos[ballNumber] = randomPosition(); 119 newgl[ballNumber] = true; 120 newgr[ballNumber] = false; 121 newgu[ballNumber] = false; 122 newgu[ballNumber] = true; 123 ballPositions = newBallPos; 124 goingLeft = newgl; 125 goingRight = newgr; 126 goingUp = newgu; 127 goingDown = newgd; 128 ballNumber++; 129 } 130 131 void seeIfBallHitWallFloorOrCeiling(int ballno) { 132 if (ballPositions[ballno].x <= 0) { // ball hit the left wall 133 goingRight[ballno] = true; 134 goingLeft[ballno] = false; 135 } else if (ballPositions[ballno].y <= 0) {// ball hit the ceiling 136 goingUp[ballno] = false; 137 goingDown[ballno] = true; 138 } else if (ballPositions[ballno].y >= BOTTOMEDGE - BALL_YAMOUNT) {// ball hit the floor 139 goingDown[ballno] = false; 140 goingUp[ballno] = true; 141 } else if (ballPositions[ballno].x >= RIGHTEDGE) { // ball reached the right edge 142 deadball = true; 143 level--; // because it will be incremented in a minute and we want to stay on the same 144 // 'level' 145 ingame = false; 146 System.out.println("LOZER!"); 147 } 148 } 149 150 private boolean isPlayerPosition(Point p) { 151 return (p.x >= playerPosition.x && p.y >= playerPosition.y && p.y <= playerPosition.y + 154); 152 } 153 154 private Point moveBall(int ballno, Point original) { 155 Point result = new Point(original); 156 if (goingLeft[ballno]) 157 result.x = result.x - BALL_XAMOUNT; 158 else if (goingRight[ballno]) 159 result.x = result.x + BALL_XAMOUNT; 160 161 if (goingUp[ballno]) 162 result.y = result.y - BALL_YAMOUNT; 163 else if (goingDown[ballno]) 164 result.y = result.y + BALL_YAMOUNT; 165 if (isPlayerPosition(result)) { 166 goingRight[ballno] = false; 167 goingLeft[ballno] = true; 168 } else 169 seeIfBallHitWallFloorOrCeiling(ballno); 170 171 return (result); 172 } 173 174 // this class will use just the key pressed event 175 @Override 176 public void keyPressed(KeyEvent e) { 177 if (ingame) { 178 if (!((e.getKeyCode() == KeyEvent.VK_DOWN && playerPosition.y >= (BOTTOMEDGE - PLAYER_YAMOUNT)) 179 || (e.getKeyCode() == KeyEvent.VK_UP && playerPosition.y <= (TOPEDGE + PLAYER_YAMOUNT)))) { 180 // valid move: move the player and then move the balls 181 if (e.getKeyCode() == KeyEvent.VK_DOWN) { 182 playerPosition.y += PLAYER_YAMOUNT; 183 } else if (e.getKeyCode() == KeyEvent.VK_UP) { 184 playerPosition.y -= PLAYER_YAMOUNT; 185 } 186 187 for (int i = 0; i < ballNumber; i++) { 188 if (isPlayerPosition(ballPositions[i])) { 189 goingRight[i] = false; 190 goingLeft[i] = true; 191 } 192 } 193 area.repaint(); 194 } // if valid key press 195 } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { 196 doLevel(level++); 197 } 198 } 199 200 @Override 201 public void run() { 202 while (true) { 203 if (juststarted) { 204 try { 205 Thread.sleep(750); 206 } catch (Exception e) { 207 } 208 juststarted = false; 209 } 210 211 try { 212 Thread.sleep(DELAY); 213 } catch (InterruptedException e) { 214 } 215 216 if (ingame) { 217 timeSinceLastBall += DELAY; 218 // System.out.println(String.valueOf(timeSinceLastBall)); 219 if (timeSinceLastBall >= 10000) { 220 addABall(); 221 timeSinceLastBall = 0; 222 } 223 224 // for each ball, move the ball closer to the player 225 for (int i = 0; i < ballPositions.length; i++) { 226 if (!deadball) { 227 ballPositions[i] = moveBall(i, ballPositions[i]); 228 } 229 if (isPlayerPosition(ballPositions[i])) { 230 goingRight[i] = false; 231 goingLeft[i] = true; 232 } 233 } 234 area.repaint(); 235 } 236 } 237 } 238 239 @Override 240 public void keyReleased(KeyEvent e) { 241 } 242 243 @Override 244 public void keyTyped(KeyEvent e) { 245 } 246 }