贪吃蛇设计思路

上传人:回**** 文档编号:123467748 上传时间:2022-07-22 格式:DOCX 页数:19 大小:61.67KB
收藏 版权申诉 举报 下载
贪吃蛇设计思路_第1页
第1页 / 共19页
贪吃蛇设计思路_第2页
第2页 / 共19页
贪吃蛇设计思路_第3页
第3页 / 共19页
资源描述:

《贪吃蛇设计思路》由会员分享,可在线阅读,更多相关《贪吃蛇设计思路(19页珍藏版)》请在装配图网上搜索。

1、贪吃蛇游戏设计思路我前一段时间写了个贪吃蛇,有位吧友求思路,而网上也没有类似的教程帖子(至少我当时没找到(-_-),我只找到了现成的代码),于是乎,我就整顿了一下自己的设计思路,写下了这篇东西,如果你是老鸟,有什么说错的地方还但愿您具体指出来,毕竟我的功力还不深。如果你是新手,人们一起交流探讨吧,我也算是刚入门的新手。在本帖最后,我会附上自己写的完整的程序代码,里面也有某些注释,以供人们参照。一方面,看看我的贪吃蛇的程序框图。从图中可以看出,整个游戏就是一种大的循环,当判断蛇的生命值为0时就跳出循环游戏结束,否则继续游戏。常用的构造是:While (1)./游戏内容.If ()break;/满

2、足游戏结束的条件时跳出循环结束游戏解决了游戏的主体构造,接下来就是游戏的具体内容了。先来看看我们需要哪些变量;蛇的身体(链表,涉及了蛇每一节的坐标,和生命值);食物(数组,两个元素,涉及了食物的坐标);蛇的运动方向(整型,共四个值);一方面,蛇的身体应当选用什么数据类型来存储呢?数组组是肯定不行的,由于数组的大小是固定的,你不懂得你的蛇最后能达到多长(或许有高手能让蛇长到占满屏幕?),并且在数组的头部插入数据是很麻烦的一件事,你必须把所有的数据都往后移动一种元素才行。因此,此处我选用了链表来储存蛇的身体信息,(有的小伙伴要问了:什么是链表啊?这个请自行百度,我的个人见解是,链表就是对构造体的一

3、种应用。话说我们学了一学期的C语言,教师也没讲链表之类的东西,不懂得很正常,它应当属于数据构造这一门学科的内容吧。如果你不懂链表也没关系,数组完全可以替代它,只是在资源的运用上要挥霍一点,在数据的插入与删除上要麻烦一点而已)。链表的一种节点应当涉及哪些内容呢?一方面是蛇的坐标x和y,然后是生命值(其实只有第一种节点能用上它,你也可以去掉它,然后此外单独定义一种全局变量如life来判断蛇的生死),最后是指向下一种节点的构造体指针。定义如下:struct snk/蛇身体 int x;int y;int life;struct snk *link;然后是食物:int food2;/食物,用food0

4、表达x坐标,用food1表达y坐标固然,食物必须定义为全局的。固然如果你有需要,还可以定义一种全局整型变量来保存积分:int fen=0;/积分需要的重要数据已经定义好,接下来是初始化。那么,就先来初始化蛇的身体,创立一种链表;struct snk *snake;/指向蛇链表头(第一种节点)的构造体指针 /声明两个个链表节点,初始化最开始的几节蛇身体snake=(struct snk *)malloc(sizeof(struct snk);snake-x=10;snake-y=10;snake-life=1;snake-link=(struct snk *)malloc(sizeof(stru

5、ct snk);snake-link-x=10;snake-link-y=9;snake-link-x=10;snake-link-link=NULL;这里我只初始化了两节,你也可以多加几节,但是,最后别忘了把最后一种节点的link指针设为空,它标志着蛇的结尾,至于life,只需把第一种节点初始化为非零值即可。接下来是初始化食物,为了可以随机生成食物,我们需要用到time.h为我们提供的随机函数,rand()和srand();为了以便背面的食物生成,我们把食物生成单独做成一种函数mkfood(),想一想,它需要哪些参数,它的返回值是什么?为了避免生成的食物的坐标与蛇的身体重叠,因此mkfood

6、函数需要懂得蛇的状态,食物是全局变量,因此函数不需要返回值,因此mkfood函数的函数首部应当是void mkfood(struct snk *p);/产生食物每次调用它都需要用srand函数重设随机数种子,然后用rand函数产生随机数,分别赋值给food0和food1作为食物的x坐标和y坐标。在这之后,需要遍历一次蛇的每一种节点,并把它们与食物的坐标比较,如有相似的,既产生的食物和蛇的身体反复了,就必须重新设定食物的坐标,这里我用的是递归调用mkfood函数来重新设定食物坐标。如果你用递归措施来重设食物坐标,不得不提的是当你在设定随机数种子时不要使用time()函数,由于time函数只能精确

7、到秒,一旦食物与蛇身体反复,就会递归调用mkfood函数,此时时间还远远局限性一秒,因此导致随机数种子还是和本来的同样,产生的随机数也和本来同样,还是和蛇身体反复,如此循环往复的递归调用,以目前的CPU运算能力,一秒钟之内可以进行的运算次数是相称惊人的,最后导致栈的溢出,程序崩溃。因此应当选用更加精确的函数,例如clock()它返回从程序启动,到调用它时通过的时间,单位是毫秒,或者干脆手动设定一种变量来做种子,每次调用之前更新这个变量。接下来就是制作一种函数,可以按照蛇身体和食物的信息,把蛇的身体和食物打印(绘制)到屏幕的相应位置。这个函数需要懂得蛇和食物的坐标,食物是全局变量可以直接获取坐标

8、,因此它接受一种构造体指针类型的参数,就是蛇身体的第一种节点,而它不需要返回值。因此她的函数首部应当是:void drawmap(struct snk *p,int *fd);/画出食物和蛇至于函数内部,我们可以通过p-x或者p-y来访问蛇的头部的坐标,然后令p=p-link;来继续访问接下来一节蛇的坐标,直到p-link=NULL,这阐明蛇到了结尾了。食物是全局变量可以直接获取坐标。获得坐标之后,你可以调用图形库来绘制,也可以在字符界面打印。总之就是遍历一次蛇的身体,根据每一种节点的坐标,分别把它们和食物一起打印在屏幕上就是了。接下来是蛇的移动问题,如何让蛇自动的移动呢?这个只需要主循环wh

9、ile(1)每循环一次就变化一次蛇的位置即可,那么如何变化呢?这就体现出我们为什么要用链表来储存蛇的坐标了。我们并不需要变化蛇每一节的坐标,只需要“添头去尾”即可移动蛇,我们只需要在蛇的头部,根据蛇的运动方向添加一种节点,把它设为蛇头,判断此节点的坐标与否超过地图范畴,如果超过这修改生命值为死亡,如果没有超过,则继续把它与食物的坐标进行比较,如果不同,则删除蛇的最后一种节点,蛇就向前移动一格了,如果相似,则蛇吃到了食物,此时不删除最后一节蛇的身体,蛇就增长了一节,然后再调用mkfood函数重新生成食物覆盖掉本来食物的坐标。此处最重要的就是链表的添头去尾操作,添头其实就是新分派一块内存,把它的l

10、ink指针指向本来的第一种节点,再把目前的第一种节点的地址返回给代表蛇头的构造体指针变量(把新添加的节点设为蛇头),去尾就是把最后一种节点用free()释放掉,把倒数第二个节点的link设为NULL即可。尚有就是如何拟定添加的头的坐标的问题,你需要根据之前的头的坐标和代表方向的变量的值来做,例如用1234分别代表上下左右方向,当方向为1时,蛇向上运动,那么在本来的蛇头的基本上把x减1,y不变来作为新头的坐标。其她方向同理。然后是蛇的控制问题,我们,可以用一种函数来获取输入,变化蛇的迈进方向;它需要接受目前的运动方向(整型值),用来判断顾客按下的方向与否与其相反(蛇不能向与目前方向相反的方向迈进

11、),然后返回一种运动方向,因此她的函数首部应当是:int keydown(int z)/获取输入这个函数里,我们可以使用conio.h里的getch来获取键盘输入,为什么不用getchar或者scanf呢?由于getch与getchar()虽然基本功能差不多,差别是getch()直接从键盘获取键值,不等待顾客按回车,只要顾客按一种键,getch就立即返回,而getchar则是从输入缓冲区获取键值, getch返回值是顾客输入的ASCII码,出错返回-1.输入的字符不会回显在屏幕上。但是尚有一种问题,那就是当程序执行到getch时会暂停,等待顾客输入。这样如果我们不按键盘,游戏就无法继续。这个可

12、以用conio.h里提供的kbhit()函数来检测与否有键盘被按下,函数名:kbhit()(VC+6.0下为_kbhit())功 能及返回值: 检查目前与否有键盘输入,若有则返回一种非0值,否则返回0用 法:int kbhit(void);涉及头文献: include 于是我们可以这样写:char ch;if(kbhit()ch=getch();switch(ch)case a:。;break;case d:。;break;case w:。;break;case s:。;break;default :break;根据按的键的不同来修改蛇的运动方向。注意哦!在变化运动方向时不要忘掉判断方向与否与

13、目前的方向冲突!我们还可以用它来判断按下的与否是Esc键,如果是,则结束游戏。至此,我们已经完毕了贪吃蛇的最重要两个数据:Food2和snakeInt x;Int y;Int life ;Struct snake *link ;几种重要的功能函数,void drawmap(struct snk *p,struct food *fd);/画地图食物和蛇 int keydown(int z);/获取输入 struct snk * mvsnk(struct snk *p,int z,struct food *fd);/移动并更新蛇的坐标 struct food * mkfood(struct snk

14、 *p);/产生食物接下来就是将它们按照开始的程序框图组合起来,一条新鲜的贪吃蛇就出炉了!固然,你还可以在最外面再套一种大循环以实现多次游戏。如果你没有ege图形库,只需要稍微更改几种绘制图形的函数,就可以在控制台的字符界面实现了。你也可如下载这里的编译完毕的exe,和我修改的字符界面版:Exe文献:字符版:Ege图形库版:(相比下面的代码,增长了菜单,即exe的源代码)如下是完整代码,其中使用了ege图形库,除了文中提到的,我还增长了保存最高纪录的功能。/|-|#include #include #include #include void msgbox(int x,int y,int l,

15、int h,char *c,char *c2,char *c3);void drd(int x,int y);/画点 void drl(int x1,int y1,int x2,int y2);/画线 void drawmap(struct snk *p);/里用上面两个函数画地图食物和蛇 int keydown(int z);/获取输入 struct snk * mvsnk(struct snk *p,int z);/更新蛇的坐标 void mkfood(struct snk *p);/产生食物 int food2=20,15;struct snk/蛇身体 int x;int y;int l

16、ife;struct snk *link;int speed=100; int fen=0;/积分 int jilu;/最高分记录 char jiluzhe20;int main()/初始化,FILE *fp;/从文献载入最高记录 if(fp=fopen(jiulu.txt,r)=NULL)jilu=0;else fgets(jiluzhe,20,fp);fscanf(fp,%d,&jilu);fclose (fp);initgraph(600,600);/定义屏幕为600*600像素setcaption(贪吃蛇); setcolor(WHITE);setfont(20,0,宋体);int z

17、=4;struct snk *snake;/指向蛇链表头的构造体指针 struct snk *snakelink;/用于游戏结束后释放内存时的临时存储 struct food *fd;/指向食物的构造体指针 /声明四个链表节点为初始的四节蛇身体snake=(struct snk *)malloc(sizeof(struct snk);snake-x=10;snake-y=10;snake-life=1;snake-link=(struct snk *)malloc(sizeof(struct snk);snake-link-x=10;snake-link-y=9; snake-link-lin

18、k=(struct snk *)malloc(sizeof(struct snk);snake-link-link-x=10;snake-link-link-y=8;snake-link-link-link=(struct snk *)malloc(sizeof(struct snk);snake-link-link-link-x=10;snake-link-link-link-y=7;snake-link-link-link-link=NULL;setfontbkcolor(BLUE);setfont(30,0,宋体);xyprintf(0,300,W:上 S:下 A:左 D:右 Esc:结

19、束游戏退出);setfont(20,0,宋体);Sleep(2300);/游戏主循环 -|while(1)int temp_z;temp_z=z; z=keydown(z);if(z=27)break;if(z=5)outtextxy(300,300,暂停);getch();z=temp_z;/*|*/snake=mvsnk(snake,z);if (snake-life=0)break;drawmap(snake);Sleep(300-speed);setfont(50,0,宋体);setcolor(YELLOW);setfontbkcolor(BLUE);outtextxy(175,250

20、,GAME OVER!);setcolor(WHITE);Sleep(1500);if (fenjilu)inputbox_getline(恭喜!打破纪录了!,您打破了最高记录!n留下您的大名吧!n按回车确认输入,jiluzhe,20);fp=fopen(jiulu.txt,w); fprintf(fp,%sn%d,jiluzhe,fen);fclose (fp);Sleep(1500);while(snake!=NULL)snakelink=snake-link;free(snake);snake=snakelink; fen=0;speed=100;closegraph();return

21、0;/-|int keydown(int z)/获取输入 char ch;if(kbhit()ch=getch();switch(ch)case A:case a:if(z!=2)z=1;break;case D:case d:if(z!=1)z=2;break;case W:case w:if(z!=4)z=3;break;case S:case s:if(z!=3)z=4;break;case E:case e:z=5;break;default :break;if(ch=27)z=27;return z;void msgbox(int x,int y,int l,int h,char *

22、c,char *c2,char *c3)setfillcolor(LIGHTGRAY);bar(x,y,x+l,y+h);setfillcolor(WHITE);bar(x+3,y+3,x+l-3,y+h-3);setfillcolor(BLUE);bar(x+3,y+3,x+l-3,y+30);setfontbkcolor(WHITE);setcolor(BLACK);rectprintf(x+5,y+3,l-5,h-3,%s%s%s,c,c2,c3);setfontbkcolor(BLUE);setcolor(WHITE);struct snk * mvsnk(struct snk *p,

23、int z)/更新蛇的坐标 struct snk *p2;struct snk *p3;int x,y;x=p-x;y=p-y;switch(z)case 1:x-;break;case 2:x+;break;case 3:y-;break;case 4:y+;break;/在蛇的头部添加一种节点 p2=(struct snk *)malloc(sizeof(struct snk);p2-x=x;p2-y=y;p2-link=p;p2-life=1;/判断蛇头与否遇到身体 p3=p;while(p3!=NULL)if (p2-x=p3-x&p2-y=p3-y)p2-life=0;p3=p3-l

24、ink; /判断蛇头与否遇到墙壁 if (p2-x28|p2-y28|p2-xylife=0;if (p2-x=food0&p2-y=food1)p2-life=2;fen+;speedlink-link!=NULL)p=p-link;p3=p-link;p-link=NULL;free(p3);/如果没有吃到食物则删除最后一种节点 return p2;void mkfood(struct snk *p)struct snk *p2;p2=p;srand(unsigned)clock();/设定随机数种子 food1=rand()%26+3;/随机产生食物坐标 food0=rand()%27+

25、1;/检测食物的坐标与否与蛇身体反复,如果是,则重新生成食物 doif (food0=p-x&food1=p-y)mkfood(p2); p=p-link; while(p!=NULL);void drd(int x,int y)/画点 setfillcolor(GREEN);x=x*20;y=y*20;bar(x+1,y+1,x+19,y+19);void drl(int x1,int y1,int x2,int y2)/画线 int x,y;setfillcolor(GREEN);dox=x1*20;y=y1*20;bar(x+1,y+1,x+19,y+19);x1x2?x1+:x2;y1x,p-y);drd(food0,food1);p=p-link;while(p!=NULL)drd(p-x,p-y);p=p-link;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!