貪吃蛇程序(全文注釋)


  前兩天在網上下載一個貪吃蛇的程序(感謝寫程序的那個人),用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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM