贪吃蛇程序(全文注释)

  前两天在网上下载一个贪吃蛇的程序(感谢写程序的那个人),用Java写的,但是没有注释,在网上查了查,只是有其中一小部分的注释,作为一名刚入门的新手,这个程序拿到手有些看不懂,我知道这个贪吃蛇的程序对我们新手来说是一个很好的学习程序,经过两天的查询JDK文档后,我用个人的理解方式把程序几乎全文注释一遍,希望自己能加深印象,我知道这个程序文档注释有不对和不全面的地方,所以发到园子,期望能有老师多多指点,呵呵!

我下载的贪吃蛇程序中有6个文档分别如下:
Data.java---定义程序中的各种数据
Food.java---定义程序中的食物
Snake.java---定义程序中贪吃蛇的身体与移动方法等
SnakeFrame.java---定义程序中的窗口
SnakePanel.java---定义程序中各种组件与模块
SnakeGame.java---开始调用程序的主方法

Data.java
 1 package snakegame;
 2 
 3 public interface Data
 4 {
 5     public final int LONG = 15;//定义蛇头与身体的边长
 6     public final int LEFT = 0;
 7     public final int RIGHT = 19;
 8     public final int UP = 0;
 9     public final int DOWN = 19;
10     
11     public final int RIGHTFLAG = 1;
12     public final int DOWNFLAG = 2;
13     public final int LEFTFLAG = 3;
14     public final int UPFLAG = 4;
15     
16     public final int ACTUALLEFT = 15;//定义黄色矩形线条距离窗口左边参数
17     public final int ACTUALUP = 10;//定义黄色矩形线条距离窗口上边参数
18 }
Food.java
 1 package snakegame;
 2 
 3 import java.awt.Color;
 4 import java.awt.Graphics2D;
 5 import java.awt.Point;
 6 import java.awt.geom.Rectangle2D;
 7 
 8 public class Food implements Data   //构造创建食物类,实现Date接口
 9 {
10     public Food()//构造创建食物的Food()方法
11     {
12         x = (int)(Math.random() * RIGHT);//返回值是一个伪随机选择的数,使之成为食物的RIGHT在x坐标上的值
13         y = (int)(Math.random() * DOWN);//返回值是一个伪随机选择的数,使之成为食物的DOWN在y坐标上的值
14         isLife = true;//定义食物为真(存在)
15     }
16     
17     public void draw(Graphics2D g2)//构造绘制图形的draw()方法
18     {
19         Point point = clientPoint(x, y);
20         //构造一个Rectangle2D对象rect,并将其初始化其位置(x,y),食物边长(LONG,LONG)
21         Rectangle2D.Double rect = new Rectangle2D.Double(point.x, point.y, LONG, LONG);
22         g2.setColor(Color.YELLOW);
23         g2.fill(rect);//使用上面设置的颜色填充图形
24         g2.setColor(Color.BLACK);
25         g2.draw(rect);//使用上面设置的颜色绘制图形轮廓
26     }
27     
28     public Point clientPoint(int x, int y)//构造设置食物在界面中绝对的坐标的clientPoint()方法
29     {
30         int clientX = ACTUALLEFT + x * LONG;
31         int clientY = ACTUALUP + y * LONG;
32         
33         return new Point(clientX, clientY);
34     }
35     
36     public Point clientPoint(Point point)
37     {
38         return clientPoint(point.x, point.y);
39     }
40     
41     public int x;
42     public int y;
43     public boolean isLife;
44 }
Snake.java
  1 package snakegame;
  2 
  3 import java.awt.Color;
  4 import java.awt.Graphics2D;
  5 import java.awt.Point;
  6 import java.awt.Polygon;
  7 import java.awt.geom.Rectangle2D;
  8 import java.util.ArrayList;
  9 
 10 public class Snake implements Data //构造Snake类,实现Data接口
 11 {
 12     public Snake()//创建Snake()方法,蛇的身体坐标
 13     {
 14         //将一个指向指定的(x,y)坐标空间中的位置添加到array数组
 15         array.add(new Point(10, 10));//蛇头
 16         array.add(new Point(10, 11));
 17         array.add(new Point(10, 12));
 18         array.add(new Point(10, 13));
 19         array.add(new Point(10, 14));//蛇尾
 20         
 21         currentFlag =UPFLAG;//定义蛇的前进方向为UPFLAG向上
 22         lifeFlag = true;//定义蛇的生命为活
 23     }
 24     
 25     public void move()//创建move()方法,用作蛇身体的移动
 26     {
 27         tair = (Point)array.get(array.size() - 1);//获取蛇尾的坐标
 28         
 29         int len = array.size() - 2;
 30         for(int i = len; i >= 0; i--)//移动array数组的元素,移动蛇的身体
 31         {
 32             Point leftPoint = (Point)array.get(i);
 33             Point rightPoint = (Point)array.get(i + 1);
 34             rightPoint.x = leftPoint.x;
 35             rightPoint.y = leftPoint.y;
 36             
 37         }
 38     }
 39     
 40     public void moveHeadLeft()//蛇方向向左移动
 41     {
 42         
 43         if(currentFlag == RIGHTFLAG || currentFlag == LEFTFLAG)//此时排除向左或者向右移动方向
 44         {
 45             return;
 46         }
 47         
 48         move();
 49         
 50         Point point = (Point)(array.get(0));//取得蛇头坐标    
 51         
 52         point.x = point.x - 1;//将蛇头的坐标x减1
 53         point.y = point.y;    
 54         
 55         if(point.x < LEFT)//判断x-1后的蛇头有没有超出边界
 56         {
 57             lifeFlag = false;//蛇头有超出边界即死亡
 58         }
 59         
 60         
 61         currentFlag = LEFTFLAG;//设置方向向左
 62     }
 63     
 64     public void moveHeadRight()//蛇方向向右移动
 65     {
 66         if(currentFlag == LEFTFLAG || currentFlag == RIGHTFLAG)//此时排除向左或者向右移动方向
 67         {
 68             return;
 69         }
 70         
 71         move();
 72         
 73         Point point = (Point)(array.get(0));
 74         
 75         point.x = point.x + 1;
 76         point.y = point.y;    
 77         
 78         if(point.x > RIGHT)
 79         {
 80             lifeFlag = false;
 81         }
 82         
 83         currentFlag = RIGHTFLAG;
 84     }
 85     
 86     public void moveHeadUp()//蛇方向向上移动
 87     {
 88         if(currentFlag == DOWNFLAG || currentFlag == UPFLAG)//此时排除向上或者向下移动方向
 89         {
 90             return;
 91         }
 92         
 93         move();
 94         
 95         Point point = (Point)(array.get(0));
 96         
 97         point.x = point.x;
 98         point.y = point.y - 1;
 99         
100         if(point.y < UP)
101         {
102             lifeFlag = false;
103         }
104         
105         currentFlag = UPFLAG;
106     }
107     
108     public void moveHeadDown()//蛇方向向下移动
109     {
110         if(currentFlag == UPFLAG || currentFlag == DOWNFLAG)//此时排除向上或者向下移动方向
111         {
112             return;
113         }
114         
115         move();
116         
117         Point point = (Point)(array.get(0));
118         
119         point.x = point.x;
120         point.y = point.y + 1;
121         
122         if(point.x > DOWN)
123         {
124             lifeFlag = false;
125         }
126 
127         currentFlag = DOWNFLAG;
128     }
129     
130     public void draw(Graphics2D g2)
131     {
132         drawHead(g2);//调用绘制蛇头方法
133         drawBody(g2);//调用绘制蛇身方法
134         //drawtair(g2);
135     }
136     
137     private void drawHead(Graphics2D g2)//构造绘制蛇头方法
138     {
139         int x = 0;
140         int y = 0;
141         Point point = (Point)array.get(0);//获取蛇头的坐标
142     
143         point = clientPoint(point);
144         x = point.x;
145         y = point.y;
146         
147         int clientX[] = new int[3];//定义三个元素的X,Y的坐标数组
148         int clientY[] = new int[3];//蛇头由三个顶点的坐标构成一个等腰三角形
149         
150         
151         switch(currentFlag)
152         {
153             case RIGHTFLAG: //当头朝向右时蛇头的三个顶点坐标如下
154                 clientX[0] = x;//x=0
155                 clientY[0] = y;//y=0
156                 clientX[1] = x + LONG;//x=0+15,15为蛇头的边长
157                 clientY[1] = y + LONG / 2;//y=0+(15/2),蛇头的顶点在边长的中点
158                 clientX[2] = x;//x=0
159                 clientY[2] = y + LONG; //y=15
160                 break;
161                 
162             case DOWNFLAG:
163                 clientX[0] = x;
164                 clientY[0] = y;
165                 clientX[1] = x + LONG;
166                 clientY[1] = y;
167                 clientX[2] = x + LONG / 2;
168                 clientY[2] = y + LONG; 
169                 break;
170                 
171             case LEFTFLAG:
172                 clientX[0] = x;
173                 clientY[0] = y + LONG / 2;
174                 clientX[1] = x + LONG;
175                 clientY[1] = y;
176                 clientX[2] = x + LONG;
177                 clientY[2] = y + LONG; 
178                 break;
179                 
180             case UPFLAG:
181                 clientX[0] = x + LONG / 2;
182                 clientY[0] = y;
183                 clientX[1] = x + LONG;
184                 clientY[1] = y + LONG;
185                 clientX[2] = x;
186                 clientY[2] = y + LONG; 
187                 break;
188                 
189             default:
190                 break;
191         }
192         //根据上面指定的参数构造并初始化新的 Polygon对象polygo,clientx.length指图形中的顶点数,此处为3
193         //clientX参数指Y坐标的数组,clientY参数指Y坐标的数组
194         Polygon polygon = new Polygon(clientX, clientY, clientX.length);
195         g2.setColor(Color.RED);//设置填充图形颜色为红色
196         g2.fill(polygon);//填充此图形
197         g2.setColor(Color.BLACK);//设置图形边框颜色为黑色
198         g2.draw(polygon);//绘制边框
199     }
200     
201     private void drawBody(Graphics2D g2)//构造绘制蛇身方法
202     {
203         for(int i = 1; i < array.size(); i++)
204         {
205             Point point = (Point)(array.get(i));
206             point = clientPoint(point); 
207             //根据上面指定的参数构造并初始化新的Rectangle2D.Double对象rect
208             //point.x,point.y指二维图形中的x,y坐标,LONG参数指该二维图形的长与宽
209             Rectangle2D.Double rect = new Rectangle2D.Double(point.x, point.y, LONG, LONG);
210             g2.setColor(Color.GREEN);//设置填充图形颜色为绿色
211             g2.fill(rect);//填充此图形
212             g2.setColor(Color.BLACK);//设置图形边框颜色为黑色
213             g2.draw(rect);//绘制边框
214         }
215     }
216     
217     private void drawtair(Graphics2D g2)
218     {
219         
220     }
221     
222     public boolean isLife()//构造蛇生命的封装方法
223     {
224         return lifeFlag;//返回蛇当前的生命迹象
225     }
226     
227     public void addNode()//构造蛇在吃到食物后,添加蛇身体长度的方法
228     {
229         array.add(new Point(tair.x, tair.y));//添加当前坐标到数组array
230     }
231     
232     public Point clientPoint(int x, int y)//构造蛇在界面中的绝对位置坐标方法
233     {
234         int clientX = ACTUALLEFT + x * LONG;
235         int clientY = ACTUALUP + y * LONG;
236         
237         return new Point(clientX, clientY);
238     }
239     
240     public Point clientPoint(Point point)//构造返回蛇头在界面中的坐标方法
241     {
242         return clientPoint(point.x, point.y);
243     }
244     
245     public void moveRight()//构造蛇在向右移动时的方法
246     {
247         tair = (Point)array.get(array.size() - 1);
248         Point point = (Point)array.get(0);
249         int tempX = point.x + 1;
250         int tempY = point.y;
251         boolean flag = false;
252         
253         for(int i = 1; i < array.size(); i++)//循环蛇的身体坐标,判断蛇头坐标是否有触碰到蛇的身体
254         {
255             Point tempPoint = (Point)array.get(i);
256             if(tempX == tempPoint.x && tempY == tempPoint.y)
257             {
258                 flag = true;//蛇头坐标是有触碰到蛇的身体flag值是true
259                 break;
260             }
261             
262         }
263         //判断蛇头坐标tempX是否超出窗口右边的坐标RIGHT,且蛇头坐标是否有触碰到蛇的身体,flag值是true或者false
264         if(tempX <= RIGHT && !flag)//如果没有就移动蛇
265         {
266             for(int i = array.size() - 1; i > 0; i--)
267             {
268                 Point point1 = (Point)(array.get(i - 1));
269                 Point point2 = (Point)(array.get(i));
270                 point2.x = point1.x;
271                 point2.y = point1.y;
272             }
273             
274             point.x = tempX;
275         }
276         else
277         {
278             lifeFlag = false;//当上面判断条件不成立时,说明蛇已经死亡,赋false给判断蛇生命是否存活的lifeFlag变量
279         }
280     }
281     
282     public void moveDown()//构造蛇在向下移动时的方法
283     {
284         tair = (Point)array.get(array.size() - 1);
285         Point point = (Point)array.get(0);
286         int tempX = point.x;
287         int tempY = point.y + 1;
288         boolean flag = false;
289         
290         for(int i = 1; i < array.size(); i++)//循环蛇的身体坐标,判断蛇头坐标是否有触碰到蛇的身体
291         {
292             Point tempPoint = (Point)array.get(i);
293             if(tempX == tempPoint.x && tempY == tempPoint.y)
294             {
295                 flag = true;//蛇头坐标是有触碰到蛇的身体flag值是true
296                 break;
297             }
298             
299         }
300         //判断蛇头坐标tempY是否超出窗口下边的坐标DOWN,且蛇头坐标是否有触碰到蛇的身体flag值是true或者false
301         if(tempY <= DOWN && !flag)//如果没有就移动蛇
302         {
303             for(int i = array.size() - 1; i > 0; i--)
304             {
305                 Point point1 = (Point)(array.get(i - 1));
306                 Point point2 = (Point)(array.get(i));
307                 point2.x = point1.x;
308                 point2.y = point1.y;
309             }
310             
311             point.y = tempY;
312         }
313         else
314         {
315             lifeFlag = false;//当上面判断条件不成立时,说明蛇已经死亡,赋false给判断蛇生命是否存活的lifeFlag变量
316         }
317     }
318     
319     public void moveLeft()//构造蛇在向左移动时的方法
320     {
321         tair = (Point)array.get(array.size() - 1);
322         Point point = (Point)array.get(0);
323         int tempX = point.x - 1;
324         int tempY = point.y;
325         boolean flag = false;
326         
327         for(int i = 1; i < array.size(); i++)//循环蛇的身体坐标,判断蛇头坐标是否有触碰到蛇的身体
328         {
329             Point tempPoint = (Point)array.get(i);
330             if(tempX == tempPoint.x && tempY == tempPoint.y)
331             {
332                 flag = true;//蛇头坐标是有触碰到蛇的身体flag值是true
333                 break;
334             }
335             
336         }
337         //判断蛇头坐标tempX是否超出窗口左边的坐标LEFT,且蛇头坐标是否有触碰到蛇的身体flag值是true或者false
338         if(tempX >= LEFT && !flag)//如果没有就移动蛇
339         {
340             
341             for(int i = array.size() - 1; i > 0; i--)
342             {
343                 Point point1 = (Point)(array.get(i - 1));
344                 Point point2 = (Point)(array.get(i));
345                 point2.x = point1.x;
346                 point2.y = point1.y;
347             }
348             
349             point.x = tempX;
350         }
351         else
352         {
353             lifeFlag = false;//当上面判断条件不成立时,说明蛇已经死亡,赋false给判断蛇生命是否存活的lifeFlag变量
354         }
355     }
356     
357     public void moveUp()//构造蛇在向上移动时的方法
358     {
359         tair = (Point)array.get(array.size() - 1);
360         Point point = (Point)array.get(0);
361         int tempX = point.x;
362         int tempY = point.y - 1;
363         boolean flag = false;
364         
365         for(int i = 1; i < array.size(); i++)//循环蛇的身体坐标,判断蛇头坐标是否有触碰到蛇的身体
366         {
367             Point tempPoint = (Point)array.get(i);
368             if(tempX == tempPoint.x && tempY == tempPoint.y)
369             {
370                 flag = true;//蛇头坐标是有触碰到蛇的身体flag值是true
371                 break;
372             }
373             
374         }
375         
376         //判断蛇头坐标tempY是否超出窗口上边的坐标UP,且蛇头坐标是否有触碰到蛇的身体flag值是true或者false
377         if(tempY >= UP && !flag)//如果没有就移动蛇
378         {
379             
380             for(int i = array.size() - 1; i > 0; i--)
381             {
382                 Point point1 = (Point)(array.get(i - 1));
383                 Point point2 = (Point)(array.get(i));
384                 point2.x = point1.x;
385                 point2.y = point1.y;
386             }
387             
388             point.y = tempY;
389         }
390         else
391         {
392             lifeFlag = false;//当上面判断条件不成立时,说明蛇已经死亡,赋false给判断蛇生命是否存活的lifeFlag变量
393         }
394     }
395     public ArrayList array = new ArrayList(); //实例化一个可随意增大或减少元素个数数组存储蛇的身体坐标
396     public int currentFlag =UPFLAG;//定义蛇的前进方向
397     public Point tair;//声明一个Point类型的对象tair
398     public boolean lifeFlag;//用boolean类型定义蛇的生命是否存活或者死亡
399 }
SnakeFrame.java
  1 package snakegame;
  2 
  3 import java.awt.Container;
  4 import java.awt.event.ActionEvent;
  5 import java.awt.event.ActionListener;
  6 
  7 import javax.swing.ButtonGroup;
  8 import javax.swing.JFrame;
  9 import javax.swing.JMenu;
 10 import javax.swing.JMenuBar;
 11 import javax.swing.JMenuItem;
 12 import javax.swing.JRadioButtonMenuItem;
 13 
 14 public class SnakeFrame extends JFrame //构造一个窗口类SnakeFrame,继承JFrame类
 15 {
 16     public SnakeFrame()
 17     {
 18         setTitle("我的贪吃蛇");//设置窗口标题
 19         setSize(WIDTH, HEIGHT);//设置窗口大小
 20         setResizable(false);//设置此窗体不可由用户调整大小
 21         
 22         setJMenuBar(menuBar);
 23         
 24         setMenu.setMnemonic('s');
 25         helpMenu.setMnemonic('h');
 26         restMenu.setMnemonic('r');
 27         
 28         menuBar.add(setMenu);
 29         menuBar.add(helpMenu);
 30         //menuBar.add(restMenu);
 31         
 32         setMenu.add(startMI);
 33         setMenu.add(pauseMI);
 34         setMenu.addSeparator();
 35         setMenu.add(speedMenu);
 36         setMenu.addSeparator();
 37         setMenu.add(exitMI);
 38         
 39         ButtonGroup group = new ButtonGroup();
 40         group.add(speedMI1);
 41         group.add(speedMI2);
 42         group.add(speedMI3);
 43         group.add(speedMI4);
 44         group.add(speedMI5);
 45         
 46         speedMenu.add(speedMI1);
 47         speedMenu.add(speedMI2);
 48         speedMenu.add(speedMI3);
 49         speedMenu.add(speedMI4);
 50         speedMenu.add(speedMI5);
 51         
 52         helpMenu.add(aboutMI);
 53         restMenu.add(restMI);
 54         
 55         startMI.addActionListener(new StartAction());
 56         pauseMI.addActionListener(new PauseAction());
 57         speedMI1.addActionListener(new SpeedAction());
 58         speedMI2.addActionListener(new SpeedAction());
 59         speedMI3.addActionListener(new SpeedAction());
 60         speedMI4.addActionListener(new SpeedAction());
 61         speedMI5.addActionListener(new SpeedAction());
 62         exitMI.addActionListener(new ExitAction());
 63         aboutMI.addActionListener(new AboutAction());
 64         restMI.addActionListener(new RestAction());
 65         
 66         Container contentPane = getContentPane();//初始化一个容器
 67         panel = new SnakePanel(this); //实例化SnakePanel并传递本方法定义的所有参数
 68         contentPane.add(panel);//在容器上添加控件
 69         
 70         startMI.setEnabled(true);
 71         pauseMI.setEnabled(false);
 72         runFlag = true;
 73     }
 74     
 75     private class StartAction implements ActionListener
 76     {
 77         public void actionPerformed(ActionEvent event)
 78         {
 79             startMI.setEnabled(false);
 80             pauseMI.setEnabled(true);
 81             runFlag = true;
 82         }
 83     }
 84     
 85     private class PauseAction implements ActionListener
 86     {
 87         public void actionPerformed(ActionEvent event)
 88         {
 89             startMI.setEnabled(true);
 90             pauseMI.setEnabled(false);
 91             runFlag = false;
 92         }
 93     }
 94     
 95     private class SpeedAction implements ActionListener
 96     {
 97         public void actionPerformed(ActionEvent event)
 98         {
 99             if(event.getSource() == speedMI1)
100             {
101                 speedFlag = 1;
102             }
103             else if(event.getSource() == speedMI2)
104             {
105                 speedFlag = 2;
106             }
107             else if(event.getSource() == speedMI3)
108             {
109                 speedFlag = 3;
110             }
111             else if(event.getSource() == speedMI4)
112             {
113                 speedFlag = 4;
114             }
115             else if(event.getSource() == speedMI5)
116             {
117                 speedFlag = 5;
118             }
119         }
120     }
121     
122         
123     private class ExitAction implements ActionListener
124     {
125         public void actionPerformed(ActionEvent event)
126         {
127             System.exit(0);
128         }
129     }
130     
131     private class AboutAction implements ActionListener
132     {
133         public void actionPerformed(ActionEvent event)
134         {
135             
136         }
137     }
138         
139     
140     private final int WIDTH = 338;
141     private final int HEIGHT = 380;
142     private JMenuBar menuBar = new JMenuBar();
143     private JMenu setMenu = new JMenu("Set");
144     private JMenu helpMenu = new JMenu("Help");
145     //private JMenu restMenu = new JMenu("Rest");
146     private JMenuItem startMI = new JMenuItem("Start");
147     private JMenuItem pauseMI = new JMenuItem("Pause");
148     private JMenu speedMenu = new JMenu("Speed");
149     private JMenuItem exitMI = new JMenuItem("Exit");
150     private JMenuItem aboutMI = new JMenuItem("About");
151     private JMenuItem restMI = new JMenuItem("rest");
152     private JRadioButtonMenuItem speedMI1 = new JRadioButtonMenuItem("Speed1", true);
153     private JRadioButtonMenuItem speedMI2 = new JRadioButtonMenuItem("Speed2", false);
154     private JRadioButtonMenuItem speedMI3 = new JRadioButtonMenuItem("Speed3", false);
155     private JRadioButtonMenuItem speedMI4 = new JRadioButtonMenuItem("Speed4", false);
156     private JRadioButtonMenuItem speedMI5 = new JRadioButtonMenuItem("Speed5", false);
157     public int speedFlag = 1;
158     public boolean runFlag = false;
159     public SnakePanel panel;
160     
161 }
SnakePanel.java
  1 package snakegame;
  2 
  3 import java.awt.Color;
  4 import java.awt.Graphics;
  5 import java.awt.Graphics2D;
  6 import java.awt.Point;
  7 import java.awt.event.ActionEvent;
  8 import java.awt.event.ActionListener;
  9 import java.awt.event.KeyEvent;
 10 import java.awt.event.KeyListener;
 11 import java.awt.geom.Rectangle2D;
 12 
 13 import javax.swing.JOptionPane;
 14 import javax.swing.JPanel;
 15 import javax.swing.Timer;
 16 
 17 public class SnakePanel extends JPanel implements Data //继承JPanel(轻量级窗口),实现Data接口
 18 {
 19     public SnakePanel(SnakeFrame frame)//创建SankePanel方法
 20     {
 21         this.frame = frame;//将其它方法传递过来的frame参数赋予本类中定义的frame
 22         init();//调用init()方法
 23         addKeyListener(new KeyHandler());//添加侦听键盘敲击事件
 24         setFocusable(true);//设置允许获得焦点
 25         timer = new Timer(1000, new TimerAction());//创建一个timer并将初始延和事件时间延迟初始化为1秒
 26         timer.start();//启动计时器
 27         this.setBackground(Color.CYAN);//调用setBackground()方法,并设置窗口背景颜色为CYAN青绿色
 28         
 29         
 30     }
 31     
 32     public void init()//创建init方法
 33     {
 34         snake = new Snake();//创建snake对象
 35         food = new Food();//创建food对象
 36         endFlag = false;//设置endFlag值为false
 37     }
 38     
 39     public void paintComponent(Graphics g)//重写JPanel父类的paintComponent()方法,来实现自己绘制方案
 40     {
 41         super.paintComponent(g);//使用超类,调用了父类的paintComponent()方法先绘制界面
 42         Graphics2D g2 = (Graphics2D)g;//创建实例
 43         drawFrame(g2);//调用drawFrame()方法,传递参数为g2
 44         
 45         if(snake.isLife())//判断当前蛇是否存活
 46         {
 47             snake.draw(g2);//如果存活执行绘制蛇新的图像
 48             food.draw(g2);//如果存活执行绘制新的食物
 49         }
 50         
 51         
 52     }
 53     
 54     public void drawFrame(Graphics2D g2)//创建绘制窗口方法
 55     {
 56         Rectangle2D.Double frame = new Rectangle2D.Double(15, 10, 300, 300);//构造一个Rectangle2D对象frame,并将其初始化其位置(15,15),大小(600,600)
 57         g2.setColor(Color.ORANGE);//设置窗口线条颜色为ORANGE黄色
 58         g2.draw(frame);//绘制窗口线条
 59     }
 60     
 61     public void eatFood()//创建食物方法
 62     {
 63         Point point = (Point)snake.array.get(0);//获取蛇的头位置坐标
 64         if(point.x == food.x && point.y == food.y)//判断蛇的头位置坐标与食物坐标是否相等
 65         {
 66             food = new Food();//如果相等重新实例化一个食物
 67             snake.addNode();//调用snake.addNode()方法,记录此坐标
 68         }
 69     }
 70     
 71     private class KeyHandler implements KeyListener  //创建监听键盘事件类keyHandler,实现KeyListener接口
 72     {
 73         public void keyPressed(KeyEvent event) //构造获取键击的事件
 74         {
 75             if(!frame.runFlag)
 76             {
 77                 return;
 78             }
 79             
 80             int keyCode = event.getKeyCode();//获得键盘上键入的方向事件
 81             switch(keyCode)
 82             {
 83                 case KeyEvent.VK_LEFT:
 84                     snake.moveHeadLeft();//如果是键入左键调用snake.moveHeadLeft()方法
 85                     break;
 86                     
 87                 case KeyEvent.VK_RIGHT:
 88                     snake.moveHeadRight();//如果是键入右键调用snake.moveHeadLeft()方法
 89                     break;
 90                     
 91                 case KeyEvent.VK_UP:
 92                     snake.moveHeadUp();//如果是键入上键调用snake.moveHeadLeft()方法
 93                     break;
 94                     
 95                 case KeyEvent.VK_DOWN:
 96                     snake.moveHeadDown();//如果是键入下键调用snake.moveHeadLeft()方法
 97                     break;
 98                     
 99                 default:
100                     break;
101             }
102             
103             eatFood();//重绘食物图形
104             
105             repaint();//重绘此组件
106         }
107         
108         public void keyReleased(KeyEvent event)
109         {
110         }
111         
112         public void keyTyped(KeyEvent event)
113         {
114         }
115     }
116     
117     private class TimerAction implements ActionListener
118     {
119         public void actionPerformed(ActionEvent event)
120         {
121             if(!frame.runFlag)
122             {
123                 return;
124             }
125             
126             if(!endFlag && !snake.isLife())
127             {
128                 endFlag = true;
129                 int result =JOptionPane.showConfirmDialog(null, 
130                         "Game over! Continue?", "贪吃蛇游戏", JOptionPane.YES_NO_OPTION);
131                 if(result == JOptionPane.YES_OPTION)
132                 {
133                     init();
134                 }
135                 else
136                 {
137                     System.exit(0);
138                 }
139             }
140             timer.setDelay(1000 - 200 * (frame.speedFlag - 1));
141             switch(snake.currentFlag)
142             {
143             case RIGHTFLAG:
144                 snake.moveRight();
145                 break;
146             case LEFTFLAG:
147                 snake.moveLeft();
148                 break;
149             case UPFLAG:
150                 snake.moveUp();
151                 break;
152             case DOWNFLAG:
153                 snake.moveDown();
154                 break;
155             default:
156                 break;
157             }
158             
159             eatFood();
160             
161             repaint();
162         }
163         
164     }
165     
166     private Snake snake;//创建Snake对象
167     private Timer timer;//创建T对象
168     private Food food;//创建F对象
169     private SnakeFrame frame; //创建SnakeFrame对象
170     private boolean endFlag = false; 
171     //public boolean endFlag = false;
172 }
SnakeGame.java
 1 package snakegame;
 2 
 3 import javax.swing.JFrame;
 4 
 5 public class SnakeGame
 6 {
 7     public static void main(String[] args)
 8     {
 9         
10         SnakeFrame frame = new SnakeFrame();
11         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12         frame.show(); 
13     }
14 }

该游戏中使用的类与接口及方法的JDK文档连接如下:
中文CJSDN文档:
http://www.cjsdn.net/Doc/JDK60/java/awt/Component.html#repaint()
http://www.cjsdn.net/Doc/JDK60/java/awt/geom/package-summary.html
http://www.cjsdn.net/Doc/JDK60/java/awt/geom/Rectangle2D.Double.html
http://www.cjsdn.net/Doc/JDK60/java/awt/color/package-summary.html
http://www.cjsdn.net/Doc/JDK60/javax/swing/package-summary.html
http://www.cjsdn.net/Doc/JDK60/javax/swing/Timer.html
http://www.cjsdn.net/Doc/JDK60/javax/swing/JPanel.html
http://www.cjsdn.net/Doc/JDK60/javax/swing/JOptionPane.html
http://www.cjsdn.net/Doc/JDK60/java/awt/event/package-summary.html
http://www.cjsdn.net/Doc/JDK60/java/awt/event/KeyEvent.html
http://www.cjsdn.net/Doc/JDK60/java/awt/event/KeyListener.html
http://www.cjsdn.net/Doc/JDK60/java/awt/event/ActionEvent.html
http://www.cjsdn.net/Doc/JDK60/java/awt/event/ActionListener.html
英文官方文档:
http://docs.oracle.com/javase/7/docs/api/java/awt/Point.html
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html 

posted @ 2013-02-25 01:32  小虎也行  阅读(5034)  评论(17编辑  收藏  举报