github地址
贪吃蛇游戏的设计步骤:
设计游戏图纸
画出900*700的白色窗口
在窗口上添加画布
在画布上添加标题
在画布上添加黑色游戏区
放置静态的蛇:一个头、两个身体
加上开始提示:按空格键开始游戏
让蛇动起来:监听Timer事件,平移数据
实现游戏暂停
实现转向功能
添加食物
吃掉食物
添加死亡条件
实现“重新开始”功能
添加分数和长度
素材下载 密码:hqze
1 package snake;
2
3 import javax.swing.JFrame;
4 import javax.swing.JPanel;
5
6 public class Snake {
7
8 public static void main(String[] args) {
9
10 JFrame frame = new JFrame(); // 创建一个游戏界面的框架
11 frame.setBounds(10, 10, 900, 720); // 设置框架的大小
12 frame.setResizable(false); // 设置框架大小为不能改变
13 // 点击关闭按钮 关闭游戏界面
14 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15
16 SnakePanel panel = new SnakePanel(); //添加画布
17 frame.add(panel); // 刚添加时画布是空的看不到
18
19 frame.setVisible(true); // 允许显示游戏界面
20 }
21
22 }
1 package snake;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.awt.event.KeyEvent;
9 import java.awt.event.KeyListener;
10 import java.util.Random;
11
12 import javax.swing.ImageIcon;
13 import javax.swing.JPanel;
14 import javax.swing.Timer;
15
16 public class SnakePanel extends JPanel implements KeyListener,ActionListener{
17
18 // 定义七个图片变量,代表七张图片
19 ImageIcon up = new ImageIcon("up.png"); // 向上的蛇头
20 ImageIcon down = new ImageIcon("down.png"); // 向下的蛇头
21 ImageIcon left = new ImageIcon("left.png"); // 向左的蛇头
22 ImageIcon right = new ImageIcon("right.png"); // 向右的蛇头
23 ImageIcon food = new ImageIcon("food.png"); // 食物
24 ImageIcon body = new ImageIcon("body.png"); // 蛇的身体
25 ImageIcon title = new ImageIcon("title.jpg"); // 游戏界面的主题
26
27 // 蛇的每一部分
28 int[] snakex = new int [750];
29 int[] snakey = new int [750];
30
31 // 随机生成食物
32 Random rand = new Random();
33 int foodx = rand.nextInt(34)*25+25; //此处的数值根据自己设计的游戏界面的大小来确定
34 int foody = rand.nextInt(24)*25+75;
35
36 // 设置游戏的默认属性
37 int len = 3;
38 int score = 0;
39 String direction = "R"; // U上 D下 L左 R右
40
41 boolean isStarted = false; // 判断游戏是否开始
42 boolean isFailed = false; // 判断游戏是否结束
43
44 Timer timer = new Timer(100,this); // 每100毫秒调用一次ActionPerformed
45
46
47 public SnakePanel() { // 建造画布的构造函数
48 this.setFocusable(true); // 获取焦点
49 this.addKeyListener(this); // 监听键盘事件
50 setup();
51 timer.start();
52 }
53
54 public void paint(Graphics g) { // Graphics 画笔
55
56 this.setBackground(Color.BLACK); // 设置画布背景颜色
57 title.paintIcon(this, g, 25, 11);// 放置主题图片
58 g.fillRect(25, 75, 850, 650); // 用画笔设置游戏方框
59
60 // 画蛇头(注意判断蛇头的方向)
61 if (direction.equals("R"))
62 right.paintIcon(this, g, snakex[0], snakey[0]);
63 else if (direction.equals("L"))
64 left.paintIcon(this, g, snakex[0], snakey[0]);
65 else if (direction.equals("U"))
66 up.paintIcon(this, g, snakex[0], snakey[0]);
67 else if (direction.equals("D"))
68 down.paintIcon(this, g, snakex[0], snakey[0]);
69
70 // 画蛇的身体
71 for(int i = 1; i < len; i ++)
72 body.paintIcon(this, g, snakex[i], snakey[i]);
73
74 // 判断如果游戏没开始显示。。。
75 if (!isStarted){
76 g.setColor(Color.WHITE);
77 g.setFont(new Font("arial",Font.BOLD, 30));
78 g.drawString("Press Space to start / pause", 200, 300);
79 }
80
81 // 判断如果游戏结束显示。。。
82 if (isFailed){
83 g.setColor(Color.WHITE);
84 g.setFont(new Font("arial",Font.BOLD, 30));
85 g.drawString("Game Over ! Press space to restart", 200, 300);
86 }
87
88 // 显示食物
89 food.paintIcon(this, g, foodx, foody);
90
91 // 设置分数和蛇的长度
92 g.setColor(Color.WHITE);
93 g.setFont(new Font("arial",Font.PLAIN,15));
94 g.drawString("Score : "+score, 650, 37);
95 g.drawString("Len :"+len, 650, 57);
96 }
97
98 public void setup() { // 游戏初始化
99 isStarted = false;
100 isFailed = false;
101 len = 3;
102 score = 0;
103 snakex[0] = 100; snakex[1] = 75; snakex[2] = 50;
104 snakey[0] = 100; snakey[1] = 100; snakey[2] = 100;
105 }
106
107 @Override
108 public void keyPressed(KeyEvent e) {
109
110 //实现键盘响应
111 int KeyCode = e.getKeyCode();
112 if (KeyCode == KeyEvent.VK_SPACE){ // 敲击空格现实/消除提示信息
113 if (isFailed){
114 // isStarted = false; // 可以将这两行放入setup中
115 // isFailed = false;
116 setup();
117 }else
118 isStarted = !isStarted;
119 } else if (KeyCode == KeyEvent.VK_UP && direction != "D")
120 direction = "U";
121 else if (KeyCode == KeyEvent.VK_DOWN && direction != "U" )
122 direction = "D";
123 else if (KeyCode == KeyEvent.VK_RIGHT && direction != "L")
124 direction = "R";
125 else if (KeyCode == KeyEvent.VK_LEFT && direction != "R")
126 direction = "L";
127 }
128
129 @Override
130 public void actionPerformed(ActionEvent e) {
131 // 1. 再定义一个闹钟
132 timer.start();
133
134 // 2. 移动数据
135 if (isStarted && !isFailed){
136 // 移动身体
137 for (int i = len; i>0; i--){
138 snakex[i] = snakex[i-1];
139 snakey[i] = snakey[i-1];
140 }
141 // 移动头
142 if (direction.equals("R")){
143 snakex[0] = snakex[0] + 25;
144 if(snakex[0] > 850) snakex[0] = 25;
145 }else if (direction.equals("L")){
146 snakex[0] = snakex[0] - 25;
147 if(snakex[0] < 25) snakex[0] = 850;
148 }else if (direction.equals("U")){
149 snakey[0] = snakey[0] - 25;
150 if (snakey[0] < 75) snakey[0] = 650;
151 }else if (direction.equals("D")){
152 snakey[0] = snakey[0] + 25;
153 if (snakey[0] > 650) snakey[0] = 75;
154 }
155
156 if (snakex[0] == foodx && snakey[0] == foody){ // 吃食物
157 len ++;
158 score ++;
159 foodx = rand.nextInt(34)*25+25;
160 foody = rand.nextInt(24)*25+75;
161 }
162
163 for (int i = 1; i < len; i ++){ // 如果蛇头碰到自己的身体游戏结束
164 if (snakex[0] == snakex[i] && snakey[0] == snakey[i]){
165 isFailed = true;
166 }
167 }
168
169 }
170 // 3. repaint()
171 repaint();
172 }
173
174 @Override
175 public void keyTyped(KeyEvent e) {
176
177 }
178
179 @Override
180 public void keyReleased(KeyEvent e) {
181
182 }
183 }