前言
该游戏可支持本地两人游戏
Player1采用W和S键控制球拍移动
Player2采用UP和DOWN键控制球拍移动
进程开始后按Space键即可开始游戏
在任意玩家得分后游戏会暂停,按下Space键后即可继续游戏
在达到设定的Score-to-win便会弹出GameOver窗口
代码实现
GameOverPanel类
1. import java.awt.Graphics; 2. import java.awt.image.BufferedImage; 3. import java.io.File; 4. import javax.imageio.ImageIO; 5. import javax.swing.JPanel; 6. import javax.swing.*; 7. import java.awt.*; 8. 9. class GameOverPanel extends JPanel { 10. private static final long serialVersionUID = 1L; 11. private BufferedImage image; 12. 13. public GameOverPanel(int player1Score, int player2Score) { 14. this.player1Score = player1Score; 15. this.player2Score = player2Score; 16. try { 17. // Load the image file 18. image = ImageIO.read(new File("C:/Users/timberman/Desktop/JianRan.jpg")); 19. } catch (Exception e) { 20. e.printStackTrace(); 21. } 22. } 23. 24. public void paintComponent(Graphics g) { 25. super.paintComponent(g); 26. // Draw the image in the center of the panel 27. int x = (getWidth() - image.getWidth()) / 2; 28. int y = (getHeight() - image.getHeight()) / 2; 29. g.drawImage(image, x, y, null); 30. } 31. private int player1Score; 32. private int player2Score; 33. 34. 35. public void paint(Graphics g) { 36. super.paint(g); 37. Font font = new Font("Arial", Font.BOLD, 20); 38. g.setFont(font); 39. g.drawString("Game Over", 30, 30); 40. if(player1Score>player2Score){ 41. g.drawString("player1 Win",30,50); 42. } 43. else{ 44. g.drawString("player2 Win",30,50); 45. } 46. } 47. }
PingPong类
1. import java.awt.*; 2. import java.awt.font.FontRenderContext; 3. import java.awt.image.BufferedImage; 4. import java.io.File; 5. import java.util.Set; 6. import java.util.HashSet; 7. import java.awt.event.KeyEvent; 8. import java.awt.event.KeyListener; 9. import java.util.Random; 10. import javax.imageio.ImageIO; 11. import javax.swing.*; 12. 13. public class PingPong extends JPanel implements KeyListener, Runnable { 14. private static final long serialVersionUID = 1L; 15. private Set<Integer> keysPressed = new HashSet<>(); 16. private int paddle1Y = 0; 17. private int paddle2Y = 0; 18. private int ballXDirection = 1; 19. private int ballYDirection = -1; 20. private int player1Score = 0; 21. private int player2Score = 0; 22. private boolean gameRunning = true; 23. private final int BALL_SIZE = 20; 24. private final int PADDLE_WIDTH = 10; 25. private final int PADDLE_HEIGHT = 100; 26. private final int PADDLE_SPEED = 10; 27. private final int SCORE_TO_WIN = 11; 28. private final int FRAME_WIDTH = 600; 29. private final int FRAME_HEIGHT = 600; 30. private final int PADDING = 10; 31. private final int BALL_SPEED = 1; 32. private final int DELAY = 10; 33. private int ballX = FRAME_WIDTH / 2 - BALL_SIZE / 2;; 34. private int ballY = FRAME_HEIGHT / 2 - BALL_SIZE / 2; 35. public boolean startScreen=true; 36. 37. public PingPong() { 38. JFrame frame = new JFrame("Ping Pong"); 39. frame.setSize(FRAME_WIDTH+15, FRAME_HEIGHT+35); 40. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 41. frame.addKeyListener(this); 42. frame.add(this); 43. frame.setVisible(true); 44. frame.setLocation(500,100); 45. new Thread(this).start(); 46. } 47. 48. public void paint(Graphics g) { 49. super.paint(g); 50. g.setColor(Color.BLACK); 51. g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT); 52. 53. 54. if (startScreen) { 55. // Draw start screen message 56. g.setColor(Color.white); 57. Font font = new Font("Arial", Font.BOLD, 36); 58. g.setFont(font); 59. g.drawString("Press SPACE to start", FRAME_WIDTH/2 -190, FRAME_HEIGHT/2); 60. } 61. else{ 62. g.setColor(Color.WHITE); 63. g.fillRect(PADDING, paddle1Y, PADDLE_WIDTH, PADDLE_HEIGHT); 64. g.fillRect(FRAME_WIDTH - PADDING - PADDLE_WIDTH, paddle2Y, PADDLE_WIDTH, PADDLE_HEIGHT); 65. g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE); 66. Font font = new Font("Arial", Font.BOLD, 20); 67. g.setFont(font); 68. g.drawString("Player 1: " + player1Score, PADDING, PADDING+10); 69. g.drawString("Player 2: " + player2Score, FRAME_WIDTH - PADDING - 100, PADDING+10); 70. } 71. } 72. 73. public void run() { 74. while (gameRunning) { 75. if (startScreen) { 76. // Draw start screen message 77. Graphics g = getGraphics(); 78. g.setColor(Color.white); 79. g.drawString("Press SPACE to start", FRAME_WIDTH/2 - 70, FRAME_HEIGHT/2); 80. g.dispose(); 81. 82. // Wait for spacebar to be pressed 83. while (startScreen) { 84. try { 85. Thread.sleep(10); 86. } catch (InterruptedException e) { 87. e.printStackTrace(); 88. } 89. } 90. } 91. moveBall(); 92. movePaddles(); 93. checkCollisions(); 94. checkWin(); 95. repaint(); 96. try { 97. Thread.sleep(DELAY); 98. } catch (InterruptedException e) { 99. e.printStackTrace(); 100. } 101. } 102. } 103. 104. private void moveBall() { 105. ballX += ballXDirection * BALL_SPEED; 106. ballY += ballYDirection * BALL_SPEED; 107. } 108. 109. @Override 110. public void keyTyped(KeyEvent e) { 111. 112. } 113. public void keyPressed(KeyEvent e) { 114. int keyCode = e.getKeyCode(); 115. keysPressed.add(keyCode); 116. if (keysPressed.contains(KeyEvent.VK_SPACE)) { 117. startScreen = false; 118. } 119. } 120. 121. public void keyReleased(KeyEvent e) { 122. int keyCode = e.getKeyCode(); 123. keysPressed.remove(keyCode); 124. } 125. private void movePaddles() { 126. if (keysPressed.contains(KeyEvent.VK_W)) { 127. paddle1Y -= PADDLE_SPEED; 128. } 129. if (keysPressed.contains(KeyEvent.VK_S)) { 130. paddle1Y += PADDLE_SPEED; 131. } 132. if (keysPressed.contains(KeyEvent.VK_UP)) { 133. paddle2Y -= PADDLE_SPEED; 134. } 135. if (keysPressed.contains(KeyEvent.VK_DOWN)) { 136. paddle2Y += PADDLE_SPEED; 137. } 138. 139. // Clamp paddle positions to screen bounds 140. paddle1Y = Math.max(PADDING, Math.min(paddle1Y, FRAME_HEIGHT - PADDLE_HEIGHT - PADDING)); 141. paddle2Y = Math.max(PADDING, Math.min(paddle2Y, FRAME_HEIGHT - PADDLE_HEIGHT - PADDING)); 142. } 143. 144. private void checkCollisions() { 145. if (ballY <= 0 || ballY >= FRAME_HEIGHT - BALL_SIZE) { 146. ballYDirection *= -1; 147. } 148. if (ballX <= PADDING + PADDLE_WIDTH && ballY >= paddle1Y && ballY <= paddle1Y + PADDLE_HEIGHT) { 149. ballXDirection *= -1; 150. ballXDirection += ballXDirection > 0 ? 1 : -1; 151. ballYDirection += ballYDirection > 0 ? 1 : -1; 152. } 153. if (ballX >= FRAME_WIDTH - PADDING - PADDLE_WIDTH - BALL_SIZE && ballY >= paddle2Y && ballY <= paddle2Y + PADDLE_HEIGHT) { 154. ballXDirection *= -1; 155. ballXDirection += ballXDirection > 0 ? 1 : -1; 156. ballYDirection += ballYDirection > 0 ? 1 : -1; 157. } 158. if (ballX <= 0) { 159. player2Score++; 160. resetBall(); 161. gameRunning = false; 162. } 163. if (ballX >= FRAME_WIDTH - BALL_SIZE) { 164. player1Score++; 165. resetBall(); 166. gameRunning = false; 167. } 168. if (player1Score >= SCORE_TO_WIN || player2Score >= SCORE_TO_WIN) { 169. gameRunning = false; 170. } 171. if (!gameRunning) { 172. 173. // Draw scores 174. Graphics g = getGraphics(); 175. g.setColor(Color.white); 176. Font font = new Font("Arial", Font.BOLD, 36); 177. g.setFont(font); 178. String scoreString = "Player 1: " + player1Score + " Player 2: " + player2Score; 179. int stringWidth = g.getFontMetrics().stringWidth(scoreString); 180. g.drawString(scoreString, FRAME_WIDTH/2 - stringWidth/2, FRAME_HEIGHT/2); 181. g.drawString("Press SPACE to continue",FRAME_WIDTH/2 - stringWidth/2-10, FRAME_HEIGHT/2-100); 182. // Wait for space bar to be pressed 183. while (!keysPressed.contains(KeyEvent.VK_SPACE)) { 184. try { 185. Thread.sleep(10); 186. } catch (InterruptedException e) { 187. e.printStackTrace(); 188. } 189. } 190. // Reset game and continue 191. keysPressed.remove(KeyEvent.VK_SPACE); 192. gameRunning = true; 193. } 194. } 195. 196. private void checkWin() { 197. if (player1Score >= SCORE_TO_WIN || player2Score >= SCORE_TO_WIN) { 198. gameRunning = false; 199. JFrame frame = new JFrame("Game Over"); 200. frame.setSize(300, 300); 201. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 202. frame.add(new GameOverPanel(player1Score, player2Score)); 203. frame.setVisible(true); 204. frame.setLocation(400,300); 205. } 206. } 207. 208. private void resetBall() { 209. ballX = FRAME_WIDTH / 2 - BALL_SIZE / 2; 210. ballY = FRAME_HEIGHT / 2 - BALL_SIZE / 2; 211. ballXDirection = new Random().nextInt(2) == 0 ? -1 : 1; 212. ballYDirection = new Random().nextInt(2) == 0 ? -1 : 1; 213. } 214. 215. public static void main(String[] args) { 216. new PingPong(); 217. } 218. }
实机演示