easyx图形库做贪吃蛇游戏

Posted dingruihfut

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 


以上是关于easyx图形库做贪吃蛇游戏的主要内容,如果未能解决你的问题,请参考以下文章

贪吃蛇—C—基于easyx图形库:从画图程序到贪吃蛇自带穿墙术

c语言,Easyx实现贪吃蛇

c语言基于Easyx实现的贪吃蛇

数据结构大作业-贪吃蛇

Linux环境下,基于Ncurse图形库贪吃蛇小游戏(下)

Linux环境下,基于Ncurse图形库贪吃蛇小游戏(下)