
1 package com.wasu.biz.ao.game;
2 import java.awt.Color;
3 import java.awt.Graphics;
4 import java.awt.event.KeyEvent;
5 import java.awt.event.KeyListener;
6 import java.util.Arrays;
7 import java.util.Random;
8
9 import javax.swing.JFrame;
10 import javax.swing.JPanel;
11 import javax.swing.border.LineBorder;
12
13 public class Snake { //贪吃蛇class类
14
15 /**
16 * 贪吃蛇游戏
17 *
18 * 程序难点:
19 * (1) 蛇的爬行原理: 删除蛇的最有一个节点,然后在蛇头加入一个新节点
20 * (2) 蛇吃到食物时,其自身长度加 1
21 *
22 */
23 public static void main(String[] args) { //1. 程序入口
25 Worm w = new Worm(); //2. 接下来去执行第32行,即执行 Worm类的构造方法
26 }
27 }
28
29 class Worm extends JFrame //Worm类是爬虫类,Worm类集成JFrame类,则自动拥有JFrame类所有的成员变量和方法
30 {
31 // 设置Snake的窗体
32 public Worm() //3. 初始化 爬虫类(初始化:即把这个爬虫类给构造出来的意思)
33 {
34 // 设置 窗体的一些属性
35 setSize(600, 620);
36 setTitle("Worm");
37 setLocationRelativeTo(null);
38
39
40 // 添加 画布
41 CellJPanel cell = new CellJPanel(); //4. 当程序执行到此处,会先跳转到92行去执行(因为此处调用了CellJpanel类的构造方法)
42 cell.setBorder(new LineBorder(Color.BLUE));
43 add(cell);
44
45 // 添加 键盘监听事件
46 addKeyListener(cell);
47 cell.addKeyListener(cell);
48
49 // 添加线程 控制
50 Thread t = new Thread(cell);
51 t.start();
52
53 setVisible(true);
54 setTitle("贪吃蛇游戏 V1.0");
55 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //至此,窗口界面创建完毕
56 }
57 }
58
// 此类表示灰色画布类
59 class CellJPanel extends JPanel implements Runnable, KeyListener
60 {
61 final int WIDTH = 500; // 设置画布大小
62 final int HEIGHT = 500;
63
64 int index = 5; // 定义 蛇的初始长度
65 Cell[] cell = new Cell[index]; // 创建 蛇
66
67 int dx; // 定义 随机 食物 坐标
68 int dy;
69
70
71 int z = 0; // 定义 方块 移动方向
72
73 int x1; // 颜色值
74 int y1;
75 int z1;
76
77 public void getColor() //生成一种颜色(颜色用3个0到255内的数值表示)
78 {
79 Random ran = new Random();
80
81 x1 = ran.nextInt(255);
82 y1 = ran.nextInt(255);
83 z1 = ran.nextInt(255);
84 }
85
86 public void getFood() //获取食物小方块的位置
87 {
88 dx = (int)(Math.random()*48)*10;
89 dy = (int)(Math.random()*48)*10;
90 }
91
92 public CellJPanel()
93 {
94 for(int i=0; i<cell.length; i++)
95 {
96 cell[i] = new Cell();
97 cell[i].x = index*10 - 10*i;
98 cell[i].y = 100;
99 }
100
101 getFood(); //5. 程序执行到此处,接下来去执行第86行,接着执行第87到90行,然后程序返回101行末;接着去执行102行,然后程序返回到第41行的行末,往下去执行第42行的代码
102 }
103
104 public void paint(Graphics g) //窗口画布长度、宽度、前景色、背景色、位置等属性的设置,用来定义游戏窗口的样式
105 {
106 /**
107 * 设置 画布 的一些属性
108 */
109 super.paint(g);
110 setSize(WIDTH, HEIGHT);
111 setLocation(50, 50);
112 setBackground(Color.GRAY);
113
114
115 int a=10;
116 int b=10;
117
118 // 画出 网格
119 for(int i=0; i<50; i++)
120 {
121 g.setColor(Color.cyan);
124 a += 10;
125 b += 10;
126 }
127
128
129 g.setColor(Color.blue);
130 for(int i=0; i<cell.length; i++)
131 {
134 g.fill3DRect(cell[i].x, cell[i].y, 10, 10, true); // 贪吃蛇
135 }
136 g.fillRect(dx, dy, 10, 10); // 食物
137 }
138
139
140 public void run() {
142 while(true)
143 {
144 // 用上下左右键 来控制 蛇头
145 if( z==0 ) { cell[0].x += 10;} // 向右
146 if( z==1 ) { cell[0].x -= 10;} // 向左
147 if( z==2 ) { cell[0].y -= 10;} // 向上
148 if( z==3 ) { cell[0].y += 10;} // 向下
149
150 // 定义蛇的爬行,蛇的爬行原理: 删除蛇的最有一个节点,然后在蛇头加入一个节点
151 for(int i=cell.length-1; i>=1; i--)
152 {
153 cell[i].x = cell[i-1].x;
154 cell[i].y = cell[i-1].y;
155 }
156
157
158 // 蛇碰到食物,则长度加 1
159 if( cell[0].x==dx && cell[0].y==dy )
160 {
161 // 碰到食物时,蛇的长度加 1
162 cell = Arrays.copyOf(cell, cell.length+1);
163
164 cell[cell.length-1] = new Cell();
165 cell[cell.length-1].x = cell[cell.length-2].x ;
166 cell[cell.length-1].y = cell[cell.length-2].y;
167
168 getFood();
169 }
170
171 // 若小球碰到边界,则 游戏结束
172 if(cell[0].x==490 || cell[0].y==490 || cell[0].x==0 || cell[0].y==0)
173 {
174 try {
175 Thread.sleep(1500);
176 } catch (InterruptedException e) {
177 e.printStackTrace();
178 }
179 System.exit(0);
180 }else
181 {
182 try {
183 Thread.sleep(100);
184 } catch (InterruptedException e) {
185 e.printStackTrace();
186 }
187 }
188 repaint();
189 }
190 }
193
199 //释放键盘按键时,程序自动执行此方法,来改变贪吃蛇方向
200 public void keyPressed(KeyEvent e) {
201
202 if( e.getKeyCode() == 37)
203 {
204 if( z!=0 ) z = 1; // 向右
205 }
206
207 if( e.getKeyCode() == 38)
208 {
209 if( z!=3 ) z = 2;
210 }
211
212 if( e.getKeyCode() == 39)
213 {
214 if( z!= 1) z = 0;
215 }
216
217 if( e.getKeyCode() == 40)
218 {
219 if( z!= 2) z = 3; //sysd
220 }
221 repaint();
222 }
22 }
230
231 //小方块类(表示贪吃蛇面板上的小方块)
232 class Cell
233 {
234 int c; //小方块的宽度
235 int x; //小方格的横坐标
236 int y; //消防法的纵坐标
237
238 public Cell()
239 { }
240
241 public Cell(int x, int y)
242 {
243 this.x = x;
244 this.y = y;
245 }
246 }