天天看點

Win32小遊戲--貪吃蛇

近日裡學習了關于win32程式設計的相關知識,利用這些知識制作了一款貪吃蛇小遊戲,具體細節還是分子產品來叙述

前期準備:在網上找到一些貪吃蛇的遊戲素材圖檔,以及具體的邏輯框圖

Win32小遊戲--貪吃蛇

在正式寫功能之前,先把一系列環境配置好,配置環境總體來說分為以下幾步:

  1. 圖檔轉化為bmp格式( Bitmap )二進制流
  2. 将圖檔加載到記憶體中,在加載記憶體中也分為三步
  • 導入資源
Win32小遊戲--貪吃蛇
  • 将.rc檔案代碼中的絕對路徑修改為相對路徑(可不改,如果打包發給别人的話,不一定能保證對方存儲檔案的路徑和你一緻,我這裡是将素材存儲到 .c 檔案的上一級當中)
Win32小遊戲--貪吃蛇
  • 在.c檔案中利用LoadBitmap() 函數加載位圖進記憶體,其中參數的意義就不贅述了,直接通過vs自帶幫助文檔進行檢視,并且自定義一個 位圖句柄 去接着函數傳回的位址,引用宏的時候别忘了引入頭檔案
1     Hbitmap_BackGroup = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
2     Hbitmap_Apple = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP2));
3     Hbitmap_SnackHead = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP3));
4     Hbitmap_SnackHead_Up = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP5));
5     Hbitmap_SnackHead_Down = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP7));
6     Hbitmap_SnackHead_Left = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP6));
7     Hbitmap_SnackHead_Right = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP4));      

現在就正式進入編寫小遊戲的階段

先來分析一下貪吃蛇遊戲的功能

  1. 顯示背景
  2. 顯示蛇
  3. 顯示蘋果
  4. 移動
  5. 吃蘋果
  6. 生成新蘋果
  7. 蛇長個
  8. 撞牆死亡
  9. 自咬死亡

邏輯上還是很清晰很簡單的,接下來就是按功能實作

第一個,顯示背景,首先一打開遊戲就會有背景,那麼隻有重繪能實作,想要畫圖的話,必須擷取視窗環境句柄(HDC),用完再去釋放, 但是在win32中如何将我的背景位圖,貼到HDC當中呢,查詢後了解,在win32中貼圖是以像素點為機關,一個像素點一個像素點的去傳輸到HDC當中,那麼就得建立一個相容性的HDC,再為相容性DC選擇我的背景位圖,再分像素點進行傳輸

1     HDC hdc_compatible;                                                            
2     hdc_compatible = CreateCompatibleDC(hdc);                                        //建立相容性DC
3     SelectObject(hdc_compatible,Hbitmap_BackGroup);                                    //為相容性DC選擇背景位圖
4     BitBlt(hdc,0,0,600,600,hdc_compatible,0,0,SRCCOPY);                                //按像素點進行傳輸
5     DeleteDC(hdc_compatible);                                                        //删除相容性DC
6     return;      

第二個,顯示蛇,首先以蛇的圖檔大小建構一個虛拟的坐标網(也可以不建,但像素點太小定位太麻煩),以我這個為例背景圖是600*600的大小,蛇頭,蛇身,蘋果大小都是30*30大小,那麼就是長寬都為0~19的坐标網,蛇的長個很容易想到可以用連結清單的添加進行實作,那麼就把蛇身做成一個雙向連結清單(為什麼雙向,在移動的時候就明白了),在添加連結清單後,再進行先蛇頭後蛇身的貼圖,上下左右用枚舉類型

 1 enum FX {UP,DOWN,LEFT,RIGHT};2 enum FX fx = RIGHT; 

1 void AddNode(int x,int y)
 2 {
 3     Snack *pTemp = (Snack *)malloc(sizeof(Snack));
 4     pTemp->x = x;
 5     pTemp->y = y;
 6     pTemp->pLast = NULL;
 7     pTemp->pNext = NULL;
 8 
 9     if(pHead == NULL)
10     {
11         pHead = pTemp;
12     }
13     else
14     {
15         pEnd->pNext = pTemp;
16         pTemp->pLast = pEnd;
17     }
18     pEnd = pTemp;
19 }
20 void ShowSnack(HDC hdc)
21 {
22     Snack *pMark = pHead->pNext;
23     HDC hdc_compatible;
24     hdc_compatible = CreateCompatibleDC(hdc);
25     switch (fx)
26     {
27     case UP:
28         SelectObject(hdc_compatible,Hbitmap_SnackHead_Up);
29         break;
30     case DOWN:
31         SelectObject(hdc_compatible,Hbitmap_SnackHead_Down);
32         break;
33     case LEFT:
34         SelectObject(hdc_compatible,Hbitmap_SnackHead_Left);
35         break;
36     case RIGHT:
37         SelectObject(hdc_compatible,Hbitmap_SnackHead_Right);
38         break;
39     default:
40         break;
41     }
42     BitBlt(hdc,pHead->x*30,pHead->y*30,30,30,hdc_compatible,0,0,SRCCOPY);
43 
44     while(pMark)
45     {
46         SelectObject(hdc_compatible,Hbitmap_SnackHead);
47         BitBlt(hdc,pMark->x*30,pMark->y*30,30,30,hdc_compatible,0,0,SRCCOPY);
48         pMark = pMark->pNext;
49     }
50     DeleteDC(hdc_compatible);
51 }      

第三個,顯示蘋果,直接貼圖即可

1 void ShowApple(HDC hdc)
2 {
3     HDC hdc_compatible;
4     hdc_compatible = CreateCompatibleDC(hdc);
5     SelectObject(hdc_compatible,Hbitmap_Apple);
6     BitBlt(hdc,apple.x*30,apple.y*30,30,30,hdc_compatible,0,0,SRCCOPY);
7     DeleteDC(hdc_compatible);
8 }      

第四個,移動,win32中有個定時器的功能,每隔一段時間就向視窗發送定時器消息,那麼蛇的坐标隻要挨個代替前一個貼圖就會實作移動的效果,但是問題就在于是從蛇頭向蛇尾去周遊坐标變化,還是從蛇尾向蛇頭變化,在幾次嘗試後發現還是蛇尾向蛇頭,因為如果蛇頭向蛇尾的話,蛇頭坐标都改變了,而下一個蛇身就找不到蛇頭的位址,就會出現蛇頭蛇尾分家的情況,這也就是為什麼做成雙向連結清單的原因

1 void Move()
 2 {
 3     Snack *pMark = pEnd;
 4     while(pMark != pHead)
 5     {
 6         pMark->x = pMark->pLast->x;
 7         pMark->y = pMark->pLast->y;
 8         pMark = pMark->pLast;
 9     }
10     switch (fx)
11     {
12     case UP:
13         pHead->y--;
14         break;
15     case DOWN:
16         pHead->y++;
17         break;
18     case LEFT:
19         pHead->x--;
20         break;
21     case RIGHT:
22         pHead->x++;
23         break;
24     }
25 }      

第五個,吃蘋果,也就是當蛇頭坐标和蘋果坐标重合的時候代表吃到蘋果了,一個判斷就搞定了

1 BOOL IfEatApple()
2 {
3     if(pHead->x == apple.x && pHead->y == apple.y)
4         return TRUE;
5     return FALSE;
6 }      

第六個,生成新蘋果,利用随機數給蘋果生成一個新的坐标,但是後期給室友測試的時候發現一個問題,這個蘋果坐标的随機數在蛇長長之後會随到蛇身上,這個是需要改進的地方,是以就得每随機一次就得判斷是否和蛇的所有坐标重合,沒有的話,才把随機的x,y拿出來去貼圖

void NewApple()
{
    Snack *pMark = pHead;
    int x;
    int y;
    do
    {
        x = rand() % 18 + 1;
        y = rand() % 18 + 1;
        pMark = pHead;
        while(pMark)
        {
            if(pMark->x == x && pMark->y == y)
                break;
            pMark = pMark->pNext;
        }
    }while(pMark);
    apple.x = x;
    apple.y = y;
}      

第七個,蛇長個,添加連結清單即可,但是貼圖坐标隻要給到視窗以外,這樣不影響遊戲體驗

 1 AddNode(-10,-10); 

第八個,撞牆死亡,給蛇頭的坐标規定一個界限即可

1 BOOL IfBumpWall()
2 {
3     if(pHead->x == 0 || pHead->x == 19 || pHead->y == 0 || pHead->y == 19)
4         return TRUE;
5     return FALSE;
6 }      

第九個,自咬死亡,判斷蛇頭坐标是否等于自身坐标即可

1 BOOL IfEatSelf()
 2 {
 3     Snack *pMark = pHead->pNext;
 4     while(pMark)
 5     {
 6         if(pMark->x == pHead->x && pMark->y == pHead->y)
 7             return TRUE;
 8         pMark = pMark->pNext;
 9     }
10     return FALSE;
11 }      

至此,功能函數就完成了,接下來就是在回調函數裡進行邏輯連接配接的過程了,在後期給多個朋友進行試玩測試的時候,也發現了不少的bug在此也一并寫出

1.鍵盤上下左右的鍵碼VK_加上對應的大寫英文

2.由于貼圖是連續的,上一次貼圖無法銷毀,那麼就得用一層背景圖,一層蛇圖,一層蘋果圖的方式,實作遊戲的實際效果

3.當蛇向右運作的時候,快速按下向上+向右的按鍵,會顯示遊戲結束,針對這個問題,是這樣分析的,在一個定時器周期内,出現了兩次按鍵回報,也就會變成向左,那麼蛇就出現自咬的情況,處理的辦法就是人為的規定在一個定時器周期内隻允許出現一次鍵盤消息,設定一個标記,沒進定時器的時候為TURE,進過定時器為FALSE,此時鍵盤内的第二次快速按下的消息就無效了

4.暴力玩法,當螢幕内蛇幾乎占滿時,視窗會出現閃爍的問題,在進行查閱後,發現是因為重繪是有一個重新整理周期的,我的所有貼圖沒在一個周期内貼完,螢幕就會出現閃爍的現象,要想處理這個bug,可以用雙緩沖技術,也就是為目前HDC建立一個相容性HDC,再為這個相容性HDC,再建立一個相容性HDC,兩個相容性HDC之間進行多次貼圖操作,那麼在一個重繪周期内,一次就把第一次的相容性DC給貼上就可以了,滿足一個重新整理周期内圖貼完的要求,具體實作的話,在以後深入學習c++的過程中繼續完善。

完整代碼如下(圖檔素材在檔案裡,有興趣的可以自行下載下傳):

1.貪吃蛇.rc

1 // Microsoft Visual C++ generated resource script.
 2 //
 3 #include "resource.h"
 4 
 5 #define APSTUDIO_READONLY_SYMBOLS
 6 /////////////////////////////////////////////////////////////////////////////
 7 //
 8 // Generated from the TEXTINCLUDE 2 resource.
 9 //
10 #include "afxres.h"
11 
12 /////////////////////////////////////////////////////////////////////////////
13 #undef APSTUDIO_READONLY_SYMBOLS
14 
15 /////////////////////////////////////////////////////////////////////////////
16 // 中文(簡體,中國) resources
17 
18 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
19 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
20 
21 #ifdef APSTUDIO_INVOKED
22 /////////////////////////////////////////////////////////////////////////////
23 //
24 // TEXTINCLUDE
25 //
26 
27 1 TEXTINCLUDE 
28 BEGIN
29     "resource.h\0"
30 END
31 
32 2 TEXTINCLUDE 
33 BEGIN
34     "#include ""afxres.h""\r\n"
35     "\0"
36 END
37 
38 3 TEXTINCLUDE 
39 BEGIN
40     "\r\n"
41     "\0"
42 END
43 
44 #endif    // APSTUDIO_INVOKED
45 
46 
47 /////////////////////////////////////////////////////////////////////////////
48 //
49 // Bitmap
50 //
51 
52 IDB_BITMAP1             BITMAP                  "..\\she\\背景.bmp"                //得用相對路徑
53 IDB_BITMAP2             BITMAP                  "..\\she\\蘋果.bmp"
54 IDB_BITMAP3             BITMAP                  "..\\she\\蛇身.bmp"
55 IDB_BITMAP4             BITMAP                  "..\\she\\蛇頭0.bmp"
56 IDB_BITMAP5             BITMAP                  "..\\she\\蛇頭1.bmp"
57 IDB_BITMAP6             BITMAP                  "..\\she\\蛇頭2.bmp"
58 IDB_BITMAP7             BITMAP                  "..\\she\\蛇頭3.bmp"
59 #endif    // 中文(簡體,中國) resources
60 /////////////////////////////////////////////////////////////////////////////
61 
62 
63 
64 #ifndef APSTUDIO_INVOKED
65 /////////////////////////////////////////////////////////////////////////////
66 //
67 // Generated from the TEXTINCLUDE 3 resource.
68 //
69 
70 
71 /////////////////////////////////////////////////////////////////////////////
72 #endif    // not APSTUDIO_INVOKED      

2.resource.h

1 //{{NO_DEPENDENCIES}}
 2 // Microsoft Visual C++ 生成的包含檔案。
 3 // 供 貪吃蛇.rc 使用
 4 //
 5 #define IDB_BITMAP1                     101
 6 #define IDB_BITMAP2                     102
 7 #define IDB_BITMAP3                     103
 8 #define IDB_BITMAP4                     104
 9 #define IDB_BITMAP5                     105
10 #define IDB_BITMAP6                     106
11 #define IDB_BITMAP7                     107
12 
13 // Next default values for new objects
14 // 
15 #ifdef APSTUDIO_INVOKED
16 #ifndef APSTUDIO_READONLY_SYMBOLS
17 #define _APS_NEXT_RESOURCE_VALUE        108
18 #define _APS_NEXT_COMMAND_VALUE         40001
19 #define _APS_NEXT_CONTROL_VALUE         1001
20 #define _APS_NEXT_SYMED_VALUE           101
21 #endif
22 #endif      

3.Snack.c

1 #include <Windows.h>
  2 #include <time.h>
  3 #include "resource.h"
  4 
  5 typedef struct NODE
  6 {
  7     int x;
  8     int y;
  9     struct NODE *pLast;
 10     struct NODE *pNext;
 11 }Snack,Apple;
 12 
 13 Snack *pHead;
 14 Snack *pEnd;
 15 Apple apple = {5,6,NULL,NULL};
 16 enum FX {UP,DOWN,LEFT,RIGHT};
 17 enum FX fx = RIGHT;
 18 BOOL g_flag = TRUE;                                                    //設定标記,避免在一個定時器周期内有兩次動作
 19 
 20 HBITMAP Hbitmap_BackGroup;
 21 HBITMAP Hbitmap_Apple;
 22 HBITMAP Hbitmap_SnackHead;
 23 HBITMAP Hbitmap_SnackHead_Up;
 24 HBITMAP Hbitmap_SnackHead_Down;
 25 HBITMAP Hbitmap_SnackHead_Left;
 26 HBITMAP Hbitmap_SnackHead_Right;
 27 
 28 void ShowBackGround(HDC hdc);                                        //顯示背景
 29 void AddNode(int x,int y);                                            //添加蛇身
 30 void ShowSnack(HDC hdc);                                            //顯示蛇
 31 void Move();                                                        //移動蛇
 32 void ShowApple(HDC hdc);                                            //顯示蘋果
 33 BOOL IfEatApple();                                                    //判斷是否吃到蘋果
 34 void NewApple();                                                    //随機出現新蘋果
 35 BOOL IfBumpWall();                                                    //判斷是否撞牆
 36 BOOL IfEatSelf();                                                    //判斷是否自咬
 37 
 38 LRESULT CALLBACK MyWNDPROC(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
 39 
 40 int CALLBACK WinMain(
 41     HINSTANCE hInstance,
 42     HINSTANCE hPrevInstance,
 43     LPSTR lpCmdLine,
 44     int nCmdShow
 45     )
 46 {
 47     HWND hwnd;
 48     MSG msg;
 49     //1.視窗設計
 50     WNDCLASSEX ex;
 51     ex.style = (UINT)NULL;
 52     ex.cbSize = sizeof(ex);
 53     ex.cbClsExtra = 0;
 54     ex.cbWndExtra = 0;
 55     ex.hInstance = hInstance;
 56     ex.hIcon = NULL;
 57     ex.hCursor = NULL;
 58     ex.hbrBackground = CreateSolidBrush(RGB(0,255,0));
 59     ex.hIconSm = NULL;
 60     ex.lpfnWndProc = &MyWNDPROC;
 61     ex.lpszMenuName = NULL;
 62     ex.lpszClassName = "aa";
 63 
 64     Hbitmap_BackGroup = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
 65     Hbitmap_Apple = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP2));
 66     Hbitmap_SnackHead = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP3));
 67     Hbitmap_SnackHead_Up = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP5));
 68     Hbitmap_SnackHead_Down = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP7));
 69     Hbitmap_SnackHead_Left = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP6));
 70     Hbitmap_SnackHead_Right = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP4));
 71 
 72     AddNode(5,5);
 73     AddNode(4,5);
 74     AddNode(3,5);
 75 
 76     //2.注冊
 77     RegisterClassEx(&ex);
 78     //3.建立
 79     hwnd = CreateWindow(ex.lpszClassName,"貪吃蛇",WS_OVERLAPPEDWINDOW,50,50,615,638,NULL,NULL,hInstance,NULL);
 80     //4.顯示
 81     ShowWindow(hwnd,SW_SHOW);
 82 
 83     SetTimer(hwnd,1,120,NULL);
 84 
 85     srand((unsigned int)time(0));
 86 
 87     //消息循環
 88     while(GetMessage(&msg,NULL,0,0))
 89     {
 90         TranslateMessage(&msg);
 91         DispatchMessage(&msg);
 92     }
 93 
 94     return 0;
 95 }
 96 
 97 LRESULT CALLBACK MyWNDPROC(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
 98 {
 99     HDC hdc;
100     PAINTSTRUCT paintstruct;
101     switch(message)
102     {
103     case WM_CLOSE:
104         PostQuitMessage(0);
105         break;
106     case WM_PAINT:
107         hdc = BeginPaint(hWnd,&paintstruct);
108         ShowBackGround(hdc);
109         ShowSnack(hdc);
110         ShowApple(hdc);
111 
112         EndPaint(hWnd,&paintstruct);
113         break;
114     case WM_TIMER:
115         g_flag = TRUE;
116         Move();
117         if(IfBumpWall() || IfEatSelf())
118         {
119             KillTimer(hWnd,1);
120             MessageBox(hWnd,"GAME OVER","提示",MB_OK);
121         }
122         if(IfEatApple())                                        //判斷是否吃到蘋果
123         {
124             NewApple();                                            //随機一個新蘋果
125             AddNode(-10,-10);                                    //長個
126         }
127         hdc = GetDC(hWnd);
128         ShowBackGround(hdc);                                    //層層覆寫
129         ShowSnack(hdc);
130         ShowApple(hdc);
131         ReleaseDC(hWnd,hdc);
132         break;
133     case WM_KEYDOWN:
134         if(g_flag == TRUE)
135         {
136             switch(wParam)
137             {
138             case VK_UP:
139                 if(fx != DOWN)
140                 {
141                     fx = UP;
142                 }
143                 break;
144             case VK_DOWN:
145                 if(fx != UP)
146                 {
147                     fx = DOWN;
148                 }
149                 break;
150             case VK_LEFT:
151                 if(fx != RIGHT)
152                 {
153                     fx = LEFT;
154                 }
155                 break;
156             case VK_RIGHT:
157                 if(fx != LEFT)
158                 {
159                     fx = RIGHT;
160                 }
161                 break;
162             }
163         }
164         g_flag = FALSE;
165         hdc = GetDC(hWnd);
166         ShowBackGround(hdc);
167         ShowSnack(hdc);
168         ShowApple(hdc);
169         ReleaseDC(hWnd,hdc);
170         break;
171     }
172 
173     return DefWindowProc(hWnd,message,wParam,lParam);
174 }
175 void ShowBackGround(HDC hdc)
176 {
177     HDC hdc_compatible;                                                            
178     hdc_compatible = CreateCompatibleDC(hdc);                                        //建立相容性DC
179     SelectObject(hdc_compatible,Hbitmap_BackGroup);                                    //為相容性DC選擇背景位圖
180     BitBlt(hdc,0,0,600,600,hdc_compatible,0,0,SRCCOPY);                                //按像素點進行傳輸
181     DeleteDC(hdc_compatible);                                                        //删除相容性DC
182     return;
183 }
184 void AddNode(int x,int y)
185 {
186     Snack *pTemp = (Snack *)malloc(sizeof(Snack));
187     pTemp->x = x;
188     pTemp->y = y;
189     pTemp->pLast = NULL;
190     pTemp->pNext = NULL;
191 
192     if(pHead == NULL)
193     {
194         pHead = pTemp;
195     }
196     else
197     {
198         pEnd->pNext = pTemp;
199         pTemp->pLast = pEnd;
200     }
201     pEnd = pTemp;
202 }
203 void ShowSnack(HDC hdc)
204 {
205     Snack *pMark = pHead->pNext;
206     HDC hdc_compatible;
207     hdc_compatible = CreateCompatibleDC(hdc);
208     switch (fx)
209     {
210     case UP:
211         SelectObject(hdc_compatible,Hbitmap_SnackHead_Up);
212         break;
213     case DOWN:
214         SelectObject(hdc_compatible,Hbitmap_SnackHead_Down);
215         break;
216     case LEFT:
217         SelectObject(hdc_compatible,Hbitmap_SnackHead_Left);
218         break;
219     case RIGHT:
220         SelectObject(hdc_compatible,Hbitmap_SnackHead_Right);
221         break;
222     default:
223         break;
224     }
225     BitBlt(hdc,pHead->x*30,pHead->y*30,30,30,hdc_compatible,0,0,SRCCOPY);
226 
227     while(pMark)
228     {
229         SelectObject(hdc_compatible,Hbitmap_SnackHead);
230         BitBlt(hdc,pMark->x*30,pMark->y*30,30,30,hdc_compatible,0,0,SRCCOPY);
231         pMark = pMark->pNext;
232     }
233     DeleteDC(hdc_compatible);
234 }
235 void Move()
236 {
237     Snack *pMark = pEnd;
238     while(pMark != pHead)
239     {
240         pMark->x = pMark->pLast->x;
241         pMark->y = pMark->pLast->y;
242         pMark = pMark->pLast;
243     }
244     switch (fx)
245     {
246     case UP:
247         pHead->y--;
248         break;
249     case DOWN:
250         pHead->y++;
251         break;
252     case LEFT:
253         pHead->x--;
254         break;
255     case RIGHT:
256         pHead->x++;
257         break;
258     }
259 }
260 void ShowApple(HDC hdc)
261 {
262     HDC hdc_compatible;
263     hdc_compatible = CreateCompatibleDC(hdc);
264     SelectObject(hdc_compatible,Hbitmap_Apple);
265     BitBlt(hdc,apple.x*30,apple.y*30,30,30,hdc_compatible,0,0,SRCCOPY);
266     DeleteDC(hdc_compatible);
267 }
268 BOOL IfEatApple()
269 {
270     if(pHead->x == apple.x && pHead->y == apple.y)
271         return TRUE;
272     return FALSE;
273 }
274 void NewApple()
275 {
276     Snack *pMark = pHead;
277     int x;
278     int y;
279     do
280     {
281         x = rand() % 18 + 1;
282         y = rand() % 18 + 1;
283         pMark = pHead;
284         while(pMark)
285         {
286             if(pMark->x == x && pMark->y == y)
287                 break;
288             pMark = pMark->pNext;
289         }
290     }while(pMark);
291     apple.x = x;
292     apple.y = y;
293 }
294 BOOL IfBumpWall()
295 {
296     if(pHead->x == 0 || pHead->x == 19 || pHead->y == 0 || pHead->y == 19)
297         return TRUE;
298     return FALSE;
299 }
300 BOOL IfEatSelf()
301 {
302     Snack *pMark = pHead->pNext;
303     while(pMark)
304     {
305         if(pMark->x == pHead->x && pMark->y == pHead->y)
306             return TRUE;
307         pMark = pMark->pNext;
308     }
309     return FALSE;
310 }      

2019-05-16 11:32:24 程式設計小菜鳥自我檢討,望大佬能多提意見和建議,謝謝!!!