easyx圖形庫做貪吃蛇游戲


編程總是對着一個黑窗口,可以說是非常乏味了,於是喵喵就翻出來了以前用easyx圖形庫做圖形界面的貪吃蛇游戲。

不過大家只是當做提高編程的樂趣來學習吧,想進一步做的話可以學習QT,還有其他的框架。

這是一個easyx圖形庫的學習教程,建議大家學完再看本文:

https://www.easyx.cn/skills/List.aspx?id=7

首先看一下效果圖:


實現的功能:

基本的吃食物長大,撞牆死亡,特殊食物,游戲暫停,重開游戲,記分數的功能。

游戲最高分的記錄。

游戲關卡的選擇。

加了游戲的音效,具體的音效,可以在下面下載:

鏈接:https://pan.baidu.com/s/1NFn19J7gcXmG45jAuYe4Ig 密碼:x5kz

一些說明:

這個程序用的基本是C,當時對C++類的理解實在太差,現在也懶的改了。

這個程序是萬惡的VC寫的,當時還沒發現codeblocks啥的。

關於程序的功能實現,並不太難,有詳細的注釋,可以隨意復制粘貼。

下面看貪吃蛇的代碼:

#include "node.h"
class Food  
{
public:
    Food();
    virtual ~Food();
    int food;//0為無食物,1為有食物
    node foodxy;
    int c;//累計出現食物個數
};

Food::Food()
{
 c=0;
}

Food::~Food()
{

}

class node  
{
public:
    int x,y;
    node();
    virtual ~node();

};
#include "node.h"
class snake  
{
public:
    snake();
    virtual ~snake();
    node jie[200];//蛇每個節點坐標
    int n;//蛇當前節點數
    char dry;//蛇當前前進方向
};
class wall  
{
public:
    node dry[30];//障礙物的坐標
    int n;//障礙物的個數
    wall();
    virtual ~wall();

};

 

  1 #include<graphics.h>
  2 #include<conio.h>
  3 #include<time.h>
  4 #include "snake.h"
  5 #include "Food.h"
  6 #include<stdio.h>
  7 #include<fstream.h>
  8 #include "mmsystem.h"//導入聲音頭文件 
  9 #pragma comment(lib,"winmm.lib")//導入聲音頭文件庫 
 10 #include "wall.h"
 11 int wallnum,speed;
 12 
 13 void zero();
 14 void first();//操作頁面初始化
 15 int second( Food &, snake&);//數據初始化
 16 void foodstyle(Food&,wall);//食物狀態
 17 void gameover(snake,int);//游戲結束
 18 void judge( Food&,snake&,int,wall);//判斷游戲是否結束
 19 void judge2(Food &,snake&);//判斷蛇是否吃到食物
 20 void snakemove(Food&,snake&,wall);
 21 void snakeshow(Food &,snake &,wall);
 22 void change(Food &,snake &,int);//改變方向
 23 void score(snake );//記錄分數
 24 void wallstyle(wall&);//障礙物的狀態
 25 
 26 
 27 int main()
 28 {
 29     initgraph(640,560);
 30     int o;
 31     Food F;
 32     snake Snake;
 33     wall Wall;
 34     first();
 35     zero();    
 36   o= second(F,Snake);
 37    wallstyle(Wall);
 38 PlaySound("kaichang.wav",NULL,SND_FILENAME|SND_ASYNC);//載入聲音特效
 39     while(1)
 40     {
 41         while(!kbhit())//沒有鍵盤輸入時
 42         {
 43     
 44     if(!F.food )
 45     {
 46     foodstyle(F,Wall);
 47     }
 48     judge(F,Snake,o,Wall);
 49     judge2(F,Snake);
 50     snakemove(F,Snake,Wall);
 51     Sleep(speed);//控制速度
 52     score(Snake);
 53         }
 54         change(F,Snake,o);
 55         
 56     }
 57     return 0;
 58 }
 59 
 60 void zero()
 61 {
 62     char p[1];
 63     outtextxy(490,30,_T("關卡:"));
 64     for(int i=0;i<3;i++)
 65     {
 66     RECT r= {520+40*i,35,560+40*i,45};//使數字顯示在矩形區域中央
 67     sprintf(p, "%d", i+1);
 68     drawtext(p, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
 69     }
 70     settextstyle(40, 15, _T("黑體"));
 71     outtextxy(50,200,_T("請輸入 1 or 2 or 3  確定關卡"));
 72     char c=getch();//控制選擇關卡
 73     switch (c)
 74     {
 75     case '1':
 76         wallnum=10;
 77         speed=300;
 78         i=1;
 79         break; 
 80     case '2':
 81         wallnum=15;
 82         speed=200;
 83         i=2;
 84         break; 
 85     case '3':
 86         wallnum=15;
 87         speed=100;    
 88         i=3;
 89         break;
 90     default:
 91         settextcolor(BLACK);//擦除
 92         outtextxy(50,200,_T("請輸入 1 or 2 or 3  確定關卡"));
 93         settextcolor(RED);
 94         outtextxy(200,200,_T("請正確輸入"));
 95         Sleep(1000);//確保顯示時間
 96         main();
 97 }
 98     setfillcolor(GREEN);
 99     RECT v= {530+40*(i-1),20,550+40*(i-1),60};
100     sprintf(p, "%d", i);
101     drawtext(p, &v, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
102     settextcolor(BLACK);
103     outtextxy(50,200,_T("請輸入 1 or 2 or 3  確定關卡"));
104     settextcolor(RED);//確保以后的字體顏色
105 }
106 void first()
107 {
108     srand((unsigned)time(NULL));//播種子
109     setlinestyle(PS_DASH);//實線
110     settextcolor(RED);
111     setlinecolor(BLUE);
112     line(480,0,480,480);//分界線
113     line(0,480,640,480);
114     outtextxy(490,90,_T("分數:"));//操作說明
115     outtextxy(490,150,_T("最高分:"));
116     outtextxy(490,210,_T("操作方式:"));
117     outtextxy(490,260,_T(" W/w:上移  S/s:下移"));
118     outtextxy(490,310,_T(" A/a:左移   D/d:右移"));
119     outtextxy(490,360,_T("    空格:暫停/開始"));
120     outtextxy(490,410,_T("         Esc:退出"));
121     outtextxy(490,450,_T("       作者:丁喵喵"));
122     setlinecolor(BLUE);//示例圖形
123     setfillcolor(GREEN);
124     fillcircle(310,495,10);
125     fillcircle(30,535,5);
126     setfillcolor(RED);
127     fillrectangle(20,505,40,525);
128     fillrectangle(300,510,320,530);
129     setfillcolor(BLACK);
130     fillcircle(310,520,10);
131     outtextxy(20,490,_T("溫馨提示:"));
132     outtextxy(50,510,_T("一.障礙物,撞擊死亡"));
133     outtextxy(320,510,_T("四.被破壞障礙物,非無敵狀態撞擊仍會死亡"));
134     outtextxy(50,530,_T("二.特殊食物,吃掉沖撞障礙物不死亡"));
135     outtextxy(320,490,_T("三.蛇吃完特殊食物后的無敵狀態"));
136     outtextxy(320,530,_T("五.只有蛇頭時沖撞障礙物不死亡"));
137 }
138 
139 int second(Food & F,snake & Snake)
140 {
141     F.food=0;//食物有無、蛇結束、位置、前進方向初始化
142     Snake.n=1;
143     Snake.jie[0].x=40;
144     Snake.jie[0].y=40;
145     setfillcolor(RED);
146     fillcircle( Snake.jie[0].x,Snake.jie[0].y,10);
147     Snake.dry='d';
148     ifstream inFile("scoremax.txt",ios::in);//讀入文件
149     int o;
150     inFile>>o;
151     char p[1];
152     sprintf(p, "%d", o);
153     settextstyle(10, 10, _T("黑體"));
154     outtextxy(550,150,p);//最高分
155     sprintf(p, "%d", (Snake.n-1)*10);
156     outtextxy(550,90,p);//分數
157     return o;
158 }
159 
160 void foodstyle(Food & F,wall Wall)
161 {
162 if(!F.food)
163    {
164     F.foodxy.x=(rand()%22)*20+20;//食物出現地點
165     F.foodxy.y=(rand()%22)*20+20;
166     //確保食物不出現在障礙物及蛇初始位置
167     while((F.foodxy.x==40&&F.foodxy.y==40)||(F.foodxy.x==60&&F.foodxy.y==40))
168     {
169     F.foodxy.x=(rand()%22)*20+20;
170     F.foodxy.y=(rand()%22)*20+20;
171     }
172     for(int i=0;i<Wall.n;i++)
173     {
174         if(F.foodxy.x==Wall.dry[i].x&&F.foodxy.y==Wall.dry[i].y)
175         {
176             foodstyle(F,Wall);
177         }
178     }
179 setlinestyle(PS_SOLID);
180 if((F.c+1)%5==0&&(F.c+1)!=0)//判斷是否為特殊食物
181     {
182     setfillcolor(GREEN);
183     }
184     else
185     {
186     setfillcolor(YELLOW);
187     }
188 fillcircle(F.foodxy.x,F.foodxy.y,5);
189     F.food=1;//食物狀態為有
190     F.c++;//累計出現食物個數
191 }
192 }
193 void judge(Food & F,snake & Snake,int o,wall Wall)
194 {
195     if(Snake.jie[0].x<=0||Snake.jie[0].x>=480||Snake.jie[0].y<=0||Snake.jie[0].y>=480)
196     {//判斷是否撞牆
197         PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC);
198         Sleep(3000);
199         gameover(Snake,o);
200     }
201     for(int i=1;i<=Snake.n;i++)
202     {//判斷是否咬到自己
203     if(Snake.jie[0].x==Snake.jie[i].x&&Snake.jie[0].y==Snake.jie[i].y)
204     {
205         PlaySound("yao.wav",NULL,SND_FILENAME|SND_ASYNC);
206         Sleep(3000);
207         gameover(Snake,o);
208     }
209     }
210     for(i=0;i<Wall.n;i++)
211     {//判斷是否撞到障礙物
212       if(Snake.jie[0].x<Wall.dry[i].x+20&&Snake.jie[0].y<Wall.dry[i].y+20&&
213           Snake.jie[0].x>Wall.dry[i].x-20&&Snake.jie[0].y>Wall.dry[i].y-20)
214       {
215           if((F.c-1)%5!=0&&F.c!=1)//非無敵狀態
216           {
217           PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC);
218           Sleep(3000);
219           gameover(Snake,o);
220           }
221       }
222     }
223     
224 }
225 
226 void judge2(Food & F,snake & Snake)
227 {
228     if(Snake.jie[0].x==F.foodxy.x&&Snake.jie[0].y==F.foodxy.y)//判斷是否吃到食物
229     {
230     PlaySound("shiwu.wav",NULL,SND_FILENAME|SND_ASYNC);
231     setfillcolor(BLACK);//擦除
232     fillcircle(F.foodxy.x,F.foodxy.y,5);
233     Snake.n++;//蛇結數增加
234     setfillcolor(BLUE);
235     fillcircle( F.foodxy.x,F.foodxy.y,10);
236     F.food=0;//食物被吃掉
237     }
238 }
239 void gameover(snake  Snake,int o)
240 {
241     if(o<=(Snake.n-1)*10)//判斷是否需要更改最高分
242     {
243     PlaySound("zhangsheng.wav",NULL,SND_FILENAME|SND_ASYNC);
244     ofstream outFile("scoremax.txt",ios::out);//寫入文件
245     outFile<<(Snake.n-1)*10;
246     outFile.close();
247     } 
248     else
249     {
250      PlaySound("Game_over.wav",NULL,SND_FILENAME|SND_ASYNC);
251     }
252     settextcolor(RED);
253     settextstyle(180, 40, _T("黑體"));
254     outtextxy(100,100,_T("GAME OVER"));
255     settextstyle(40, 15, _T("黑體"));
256     outtextxy(200,300,_T("是否重新開始"));
257     outtextxy(150,350,_T("YES(Y/y)"));
258     outtextxy(350,350,_T("NO(N/n)"));
259     char c=getch();//判斷是否重新開始
260     if(c=='n'||c=='N')
261     {
262     closegraph();//關閉畫布    
263     }
264     else if(c=='y'||c=='Y')
265     {
266       main();
267     }
268     else//避免輸入移動指令破壞畫面
269     {
270         gameover(Snake,o);
271     }
272 
273 }
274 
275 void snakemove(Food & F,snake & Snake,wall Wall)
276 {
277   int i; 
278   for (i=Snake.n ; i>0; i--)//蛇身每一節移到前一節位置
279     {
280         Snake.jie[i].x = Snake.jie[i-1].x;
281         Snake.jie[i].y = Snake.jie[i-1].y;
282     } 
283     switch (Snake.dry)//判斷之前的移動方向 蛇頭並按該方向移到
284     {
285     case 'W':
286     case 'w':
287         Snake.jie[0].y-=20;
288         break; 
289     case 's':
290     case 'S':
291         Snake.jie[0].y +=20;
292         break;
293     case 'A':
294     case 'a':
295         Snake.jie[0].x -=20;
296         break;
297     case 'D':
298     case 'd':
299         Snake.jie[0].x +=20;
300         break;
301     };
302     snakeshow(F,Snake,Wall);//將結果顯示
303 }
304 
305 void change(Food & F,snake & Snake,int o)
306 {
307     char key,p[1];
308     IMAGE tmp;
309     int i;
310     key = getch();
311     switch (key)
312     {
313         case 'w':
314         case 'W':
315             if (Snake.dry !='s'&&Snake.dry !='S')//確保不反向移動
316             {
317                 Snake.dry ='w';
318             }
319             break;
320         case 's':
321         case 'S':
322             if (Snake.dry !='w'&&Snake.dry !='W')
323             {
324                 Snake.dry = 's';
325             }
326             break;
327         case 'a':
328         case 'A':
329             if (Snake.dry !='D'&&Snake.dry !='d')
330             {
331                 Snake.dry = 'a';
332             }
333             break;
334         case 'd':
335         case 'D':
336             if (Snake.dry !='a'&&Snake.dry !='A')
337             {
338                 Snake.dry = 'd';
339             }
340             break;
341         case' '://暫停
342            
343             getimage(&tmp,150,200,150,40);//將該區域圖像保存
344             settextstyle(40, 15, _T("黑體"));
345             outtextxy(150, 200, _T("任意鍵繼續")); 
346             PlaySound("stop.wav",NULL,SND_FILENAME|SND_ASYNC);
347             getch();
348             putimage(150,200,&tmp);//將保存圖像返回,確保不破壞背景
349             for(i=3;i>=1;i--)//倒計時
350             {
351             settextstyle(40, 15, _T("黑體"));
352             sprintf(p, "%d", i);
353             outtextxy(200, 200, p);
354             Sleep(1000);
355             putimage(150,200,&tmp);
356             }
357             PlaySound("start.wav",NULL,SND_FILENAME|SND_ASYNC);
358             break;
359         case 27:
360             gameover(Snake,o);//退出
361             break;
362     }
363 }
364 
365 void snakeshow(Food & F,snake & Snake,wall Wall)
366 {
367 int i; 
368     for (i=Snake.n-1; i>0; i--)//蛇身
369     {
370         setfillcolor(BLUE); 
371         fillcircle( Snake.jie[i].x,Snake.jie[i].y,10);
372     } 
373     if((F.c-1)%5==0&&F.c!=1)//特殊食物
374     {
375         setfillcolor(GREEN);
376     }
377     else
378     {
379         setfillcolor(RED);
380     }
381         fillcircle( Snake.jie[0].x,Snake.jie[0].y,10);
382         setlinecolor(BLACK);
383         setfillcolor(BLACK);//擦除之前最后一節蛇身
384         fillcircle( Snake.jie[Snake.n].x,Snake.jie[Snake.n].y,10);
385         if(Snake.n>1)
386         {
387             setfillcolor(BLUE);
388         }
389         else
390         {
391             setfillcolor(RED);
392         }
393     fillcircle( Snake.jie[Snake.n-1].x,Snake.jie[Snake.n-1].y,10);
394 } 
395 
396 
397 void score(snake  Snake)
398 {
399     char p[1];
400     sprintf(p, "%d", (Snake.n-2)*10);
401     settextcolor(BLACK);
402     outtextxy(550,90,p);
403     sprintf(p, "%d", (Snake.n-1)*10);
404     settextcolor(RED);
405     settextstyle(10, 10, _T("黑體"));
406     outtextxy(550,90,p);
407 
408 }
409 
410 void wallstyle(wall & Wall)
411 {
412     Wall.n =wallnum;
413     for(int i=0;i<Wall.n;i++)
414     {
415     Wall.dry[i].x=(rand()%22)*20+20;//障礙物出現地點
416     Wall.dry[i].y=(rand()%22)*20+20;
417     while((Wall.dry[i].x==40&&Wall.dry[i].y==40)||(Wall.dry[i].x==60&&Wall.dry[i].y==40)
418         ||(Wall.dry[i].x==80&&Wall.dry[i].y==40))
419     {
420         Wall.dry[i].x=(rand()%22)*20+20;//障礙物出現地點
421         Wall.dry[i].y=(rand()%22)*20+20;
422     }
423     setfillcolor(RED);
424     fillrectangle(Wall.dry[i].x-10,Wall.dry[i].y-10,Wall.dry[i].x+10,Wall.dry[i].y+10);
425     for(int j=0;j<i;j++)//確保障礙物不重疊
426     {
427         if(Wall.dry[i].x==Wall.dry[j].x&&Wall.dry[i].y==Wall.dry[j].y)
428         {
429             i--;
430         }
431     }
432     }   
433 }

 


免責聲明!

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



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