1. import java.awt.*;
2. import java.awt.event.*;
3. import javax.swing.*;
4.
5. public class SnakeGame extends JFrame implements ActionListener {
6.
7. private static final long serialVersionUID = 1L;
8.
9. // 定义游戏区域的大小
10. private final int WIDTH = 640;
11. private final int HEIGHT = 640;
12.
13. // 定义贪吃蛇的初始位置和大小
14. private final int DOT_SIZE = 10;
15. private final int ALL_DOTS = 900;
16. private final int RAND_POS = 40;
17. private int[] x = new int[ALL_DOTS];
18. private int[] y = new int[ALL_DOTS];
19. private int dots;
20. private int apple_x;
21. private int apple_y;
22.
23. // 定义贪吃蛇的移动方向
24. private boolean leftDirection = false;
25. private boolean rightDirection = true;
26. private boolean upDirection = false;
27. private boolean downDirection = false;
28.
29. // 定义游戏是否结束
30. private boolean inGame = true;
31.
32. // 定义计时器
33. private Timer timer;
34.
35. public SnakeGame() {
36. initGame();
37. addKeyListener(new KeyAdapter() {
38. @Override
39. public void keyPressed(KeyEvent e) {
40. int key = e.getKeyCode();
41. if (key == KeyEvent.VK_LEFT && !rightDirection) {
42. leftDirection = true;
43. upDirection = false;
44. downDirection = false;
45. } else if (key == KeyEvent.VK_RIGHT && !leftDirection) {
46. rightDirection = true;
47. upDirection = false;
48. downDirection = false;
49. } else if (key == KeyEvent.VK_UP && !downDirection) {
50. upDirection = true;
51. leftDirection = false;
52. rightDirection = false;
53. } else if (key == KeyEvent.VK_DOWN && !upDirection) {
54. downDirection = true;
55. leftDirection = false;
56. rightDirection = false;
57. }
58. }
59. });
60. setFocusable(true);
61. }
62.
63. public void initGame() {
64. // 初始化游戏区域
65. setTitle("SnakeGame");
66. setSize(WIDTH, HEIGHT);
67. setResizable(false);
68. setDefaultCloseOperation(EXIT_ON_CLOSE);
69. setVisible(true);
70. getContentPane().setBackground(Color.black);
71. // 初始化贪吃蛇的位置和大小
72. dots = 3;
73. for (int i = 0; i < dots; i++) {
74. x[i] = 50 - i * DOT_SIZE;
75. y[i] = 50;
76. }
77.
78. // 初始化苹果的位置
79. locateApple();
80.
81. // 初始化计时器
82. timer = new Timer(140, this);
83. timer.start();
84. }
85.
86. public void locateApple() {
87. // 随机生成苹果的位置
88. int r = (int) (Math.random() * RAND_POS);
89. apple_x = r * DOT_SIZE;
90.
91. r = (int) (Math.random() * RAND_POS);
92. apple_y = r * DOT_SIZE;
93. }
94.
95. public void checkApple() {
96. // 检查贪吃蛇是否吃到了苹果
97. if ((x[0] == apple_x) && (y[0] == apple_y)) {
98. dots++;
99. locateApple();
100. }
101. }
102.
103. public void checkCollision() {
104. // 检查贪吃蛇是否碰到了边界或自己的身体
105. for (int i = dots; i > 0; i--) {
106. if ((i > 4) && (x[0] == x[i]) && (y[0] == y[i])) {
107. inGame = false;
108. }
109. }
110.
111. if (y[0] >= HEIGHT) {
112. inGame = false;
113. }
114.
115. if (y[0] < 0) {
116. inGame = false;
117. }
118.
119. if (x[0] >= WIDTH) {
120. inGame = false;
121. }
122.
123. if (x[0] < 0) {
124. inGame = false;
125. }
126.
127. if (!inGame) {
128. timer.stop();
129. }
130. }
131.
132. public void move() {
133. // 移动贪吃蛇
134. for (int i = dots; i > 0; i--) {
135. x[i] = x[(i - 1)];
136. y[i] = y[(i - 1)];
137. }
138.
139. if (leftDirection) {
140. x[0] -= DOT_SIZE;
141. }
142.
143. if (rightDirection) {
144. x[0] += DOT_SIZE;
145. }
146.
147. if (upDirection) {
148. y[0] -= DOT_SIZE;
149. }
150.
151. if (downDirection) {
152. y[0] += DOT_SIZE;
153. }
154. }
155.
156. public void actionPerformed(ActionEvent e) {
157. // 计时器触发事件
158. if (inGame) {
159. checkApple();
160. checkCollision();
161. move();
162. repaint(); // 重绘游戏区域
163. }
164. }
165.
166. public void paint(Graphics g) {
167.
168. // 绘制游戏区域
169. super.paint(g);
170. g.setColor(Color.black);
171.
172. if (inGame) {
173. g.setColor(Color.red);
174. g.fillOval(apple_x, apple_y, DOT_SIZE, DOT_SIZE);
175.
176. for (int i = 0; i < dots; i++) {
177. g.setColor(Color.green);
178. g.fillRect(x[i], y[i], DOT_SIZE, DOT_SIZE);
179. }
180.
181. Toolkit.getDefaultToolkit().sync();
182. } else {
183. gameOver(g);
184. }
185. }
186.
187. public void gameOver(Graphics g) {
188. // 游戏结束
189. String msg = "GAME OVER";
190. Font small = new Font("Helvetica", Font.BOLD, 40);
191. FontMetrics metr = getFontMetrics(small);
192.
193. g.setColor(Color.white);
194. g.setFont(small);
195. g.drawString(msg, (WIDTH - metr.stringWidth(msg)) / 2, HEIGHT / 2);
196. }
197.
198.
199. public static void main(String[] args) {
200. new SnakeGame();
201. }
202. }