《贪吃蛇C语言课程设计.doc》由会员分享,可在线阅读,更多相关《贪吃蛇C语言课程设计.doc(25页珍藏版)》请在三一办公上搜索。
1、本科课程设计论文 题 目 用C语言实现贪吃蛇 系 别 信息科学与技术系专业班级 姓 名 学 号指导教师 年 月 日信息科学与技术系目 录摘 要- 2 -第一章 绪 论- 3 -第二章 需求分析- 4 -2.1 功能需求- 4 -2.2 性能需求-4-第三章 程序设计- 5 -3.1 总体设计- 5 -3.2 详细设计- 5 -第四章 调试与测试- 15 -第五章 总结与心得- 25 -附 录- 26 -摘 要 贪吃蛇游戏是一个深受人们喜爱的游戏,一条在密闭的围墙内,在围墙内随机出现一个食物,通过按键盘上四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节
2、,同时计10分,接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉蛇头撞到自己的身体游戏结束。 经过分析,我使用C语言开发工具,通过TC软件来实现,在掌握C语言的基础知识:数据类型(整型.实型.字符型.指针.数组.结构等);运算类型(算术运算.逻辑运算.自增自减运算.赋值运算等);程序结构(顺序结构.判断选择结构.循环结构);大程序的功能分解方法(即函数的使用)等.进一步掌握各种函数的应用以及文件的读写操作等.关键字:贪吃蛇 光标键 数据类型 运算类型 程序结构 TC软件第一章 绪 论 贪吃蛇游戏是一个深受人们喜爱的游戏,一条在密闭的围墙内,在围墙内随机出现一个食物,通过按键
3、盘上四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时计10分,接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉蛇头撞到自己的身体游戏结束。程序关键在于表示蛇的图形及蛇的移动。用一个小矩形快表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用俩节表示。移动时必须从蛇头开始,所以蛇不能向相反的方向移动,如果不按任意键,蛇自行在当前方向上前移,但按下有效方向键后,蛇头朝着该方向移动,一步移动一节身体,所以按下有效方向键后,先确定蛇头的位置,而后蛇的身体随蛇头移动,图形的实现是从蛇头新位置开始画出蛇,这时,由于未清屏的原因,原来的
4、蛇的位置和新蛇的位置差一个单位,所以看起来蛇多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现与消失也是画矩形块和覆盖矩形块。为了便于理解,定义两个结构体:食物与蛇。表示食物与蛇的矩形块设计为10*10个像素单位,食物的基本数据域为他所出现的位置,用x和y座标表示,则矩形块用函数rectangle(x,y,x+10,y+10)或rectangle(x,y,x+10,y-10)可以画出。由于每次只出现一个食物,所以设定yes表示是否要出现食物。蛇的一节身体为一个矩形块,表示矩形块只需起点座标x,y。身体不断增长,用数组存放每节座标,最大设定为N=200,node表示当前节数。保存蛇的移动方向
5、的变量direction和生命的变量life,一旦life为1,表示蛇死,结束。本系统的主要功能主要有:1. 初始图形系统2. 开始画面3. 玩游戏的具体过程4. 游戏结束后5. 关闭图形系统6. 结束程序 第二章 需求分析2.1 功能需求:根据主界面显示内容进行选择并进一步执行相应操作。一、初始图形: 通过函数Init(),初始画面、二、开始画面: 通过函数DrawK(),主界面是一个封闭的围墙,用两个循环语句分别在水平和垂直方向输出连续的宽度和高度的矩形方块。三、玩游戏的具体过程:通过函数GamePlay(),通过按键盘上四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇
6、吃掉,这时蛇的身体长一节,接着又出现食物,等待被蛇吃掉,小蛇继续运动。四、游戏结束:通过函数GameOver(),蛇碰到墙壁或者碰蛇身,游戏结束,清除屏幕,输出分数显示游戏结束信息。五、关闭图形系统:通过函数Close(),关闭图形界面。六、结束程序七、退出系统2.2 性能需求:具有良好的可靠性和安全性。对于系统要求比较低。使用范围比较广。需在TC下运行。 第三章 程序设计3.1 概要设计将此系统化分为如下模块:1、 初始图形模块:可用函数Init()函数来实现此操作。2、开始画面模块:用DrawK()函数来实现。出现运行界面。3、玩游戏的具体过程模块:可用GamePlay()函数来实现。通过
7、按键盘上四个光标键控制蛇向上下左右四个方向移动,小蛇在移动的过程中吃食。4、游戏结束后模块:用GameOver()函数来实现。5、输出分数模块:用PrScore()函数来实现。输出游戏的得分。6、 关闭图形系统模块:用Close()函数来实现。关闭图形运行界面。7、结束程序模块:用Close()函数来实现。结束程序。8、退出系统:可用一个函数exit()来实现,首先将信息保存到文件中,释放动态创建的内存空间,再退出此程序。数据结构设计:程序设计中用到的结构体类型:int str。 3.2 详细设计1. 主函数 main() 主函数是程序的住流程,首先定义使用到得常数、全局变量及函数原型说明,然
8、后初始图形系统,调用函数DrawK()画出开始画面,调用GamePlay(),即玩游戏的具体过程,游戏结束后调用Close()关闭图形系统,结束程序。编码:void main(void) Init();/*图形驱动*/ DrawK();/*开始画面*/ GamePlay();/*玩游戏具体过程*/ Close();/图形结束对应流程图: 开 始 图形驱动 开始画面 玩游戏具体过程 图形结束 结束 系统流程图1开 始蛇吃到食物?蛇 长 大死 亡?继 续?退出界面初始界面和蛇身游戏者按键选择放置食物蛇开始运动 Y NYyNYYN 系统流程图2 2. 图形驱动函数Init()编码:void Init
9、(void) int gd=DETECT,gm; initgraph(&gd,&gm,c:tc); cleardevice();对应流程图: Int gd=DETECT,gm3. 画界面函数DrawK() 主界面是一个封闭的围墙,用两个循环语句分别在水平和垂直方向输出连续的宽度和高度的矩形方块,表示围墙,为了设计醒目,可设置自己所需颜色。 编码:void DrawK(void) setbkcolor(LIGHTGREEN); /*设置当前背景颜色(为淡绿色)*/*界面的颜色,界面颜色为明亮的绿色。*/ setcolor(11); /*设置当前画线颜色*/ setlinestyle(SOLID_
10、LINE,0,THICK_WIDTH);/*设置线型*/ for(i=50;i=600;i+=10)/*画围墙*/*小蛇每走一步,得10分。*/ rectangle(i,40,i+10,49); /*上边*/ rectangle(i,451,i+10,460);/*下边*/ for(i=40;i=450;i+=10) rectangle(50,i,59,i+10); /*左边*/*运用 rectangle函数求出矩形大小。*/*/ rectangle(601,i,610,i+10);/*右边*/ 对应流程图: i+=10 i=450 rectangle(50,I,59,i+10); i +=1
11、0i=50 i 0;i-)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ snake.xi=snake.xi-1;/*小蛇向左移动一步*/ snake.yi=snake.yi-1;/*小蛇向上移动一步*/ /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/ switch(snake.direction) case 1:snake.x0+=10;break; /*蛇向右移动一步,蛇身长为初值后,x0=x0+10返回*/ case 2: snake.x0-=10;break; /*蛇向左移动一步,蛇身长为初值后,x0=x0+10返回*/ case 3: snake.y0
12、-=10;break; /*蛇向上移动一步,蛇身长为初值后,y0=y0+10返回*/ case 4: snake.y0+=10;break; /*蛇向下移动一步,蛇身长为初值后,y0=y0+10返回*/ for(i=3;isnake.node;i+)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/*若xi和x0的坐标一致且yi和y0的坐标也一致则判断蛇头已撞到自己,结束游戏。*/ if(snake.xi=snake.x0&snake.yi=snake.y0)/*蛇是否撞到墙壁*/ GameOver();/*显示失败*/ snake.life=1;/*蛇死了*/ b
13、reak; if(snake.x0595|snake.y0455)/*蛇是否撞到墙壁(如果蛇的坐标满足横坐标小于55或横坐标大于595或纵坐标小于55或纵坐标大于455)*/ GameOver();/*本次游戏结束*/ snake.life=1; /*蛇死*/ if(snake.life=1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/ break; if(snake.x0=food.x&snake.y0=food.y)/*吃到食物以后*/ setcolor(0);/*把画面上的食物东西去掉(即画面中的食物为背景颜色,即黑色)*/ rectangle(food.x,food.y,f
14、ood.x+10,food.y-10);/*运用rectangle函数画出一个食物矩形边框线*/ snake.xsnake.node=-20;snake.ysnake.node=-20; /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/ snake.node+;/*蛇的身体长一节*/ food.yes=1;/*画面上需要出现新的食物*/ score+=10;/*(吃到食物后)分数加10分*/ PrScore();/*输出新得分*/ setcolor(4);/*画出蛇*/ for(i=0;isnake.node;i+) rectangle(snake.xi,snake.yi,snak
15、e.xi+10, snake.yi-10);/*运用rectangle函数画出一个食物矩形边框线*/ delay(gamespeed);/*延迟游戏速度*/ setcolor(0);/*用黑色去除蛇的的最后一节*/ rectangle(snake.xsnake.node-1,snake.ysnake.node-1, /*运用rectangle函数来计算小蛇尾部的位置 */ snake.xsnake.node-1+10,snake.ysnake.node-1-10);/*小蛇尾部的横坐标就等于小蛇头部的横坐标减去一再加上10,小蛇我尾部的纵坐标就等于小蛇头部的纵坐标减去加上10(即表示尾巴长一节
16、)*/ if(snake.life=1)/*如果蛇死就跳出循环*/ break; key=bioskey(0);/*接收按键*/ if(key=ESC)/*按ESC键退出*/ break; else if(key=UP&snake.direction!=4)/*如果小蛇的接收按键为向上且小蛇所指向的方向不是4(即小蛇不指向下)*/*判断是否往相反的方向移动*/ snake.direction=3;/*小蛇向上转*/ else if(key=RIGHT&snake.direction!=2)/*如果小蛇的接收按键为向右且小蛇所指向的方向不是向2(即小蛇不指向左)*/ snake.directio
17、n=1; /*小蛇向右转*/ else if(key=LEFT&snake.direction!=1)/*如果小蛇的接收按键为向左且小蛇的所指向的 方向不是1(即小蛇不指向下)*/ snake.direction=2;/*小蛇向左转*/ else if(key=DOWN&snake.direction!=3)/*如果小蛇的接收按键为向下且小蛇所指向的方向不是3(即小蛇不指向上)*/ snake.direction=4;/*小蛇向下转*/ /*endwhile(1)*/流程图:break;key=bioskey(0);snake.life=1!kbhit()Multiplex 1Multiple
18、xclearderice();charstr10;geth(); 结束5. 游戏结束函数GameOver() 游戏结束,清除屏幕,输出分数显示游戏结束信息。编码:void GameOver(void) cleardevice(); PrScore(); setcolor(RED); settextstyle(0,0,4); outtextxy(200,200,GAME OVER); getch();/*输出成绩*/ cleardevice()对应流程图:6. 输出成绩函数PrScore()编码:void PrScore(void) char str10;/*char类型的字符串变量str,长度
19、为10个char*/ setfillstyle(SOLID_FILL,BLUE);/*设置线型*/ bar(50,15,220,35);/*画一个二维条形图*/ setcolor(6); settextstyle(0,0,2);/*为图形输出设置当前的文本属性*/ sprintf(str,score:%d,score);/*输出score为多少(即输出分数)*/ outtextxy(55,20,str);/*进行输出一个整型数据(定下输出分数的位置为x=55,y=20)*/对应流程图: char str107. 图形结束函数Close()编码:void Close(void) getch();
20、 closegraph();对应流程图: getch() 第四章 程序代码#define N 200#include /*图形头文件*/#include /*包含rand等函数*/#include /*包含bios函数*/#define LEFT 0x4b00/*光标左键值*/#define RIGHT 0x4d00/*光标右键值*/#define DOWN 0x5000/*光标下键值*/#define UP 0x4800/*光标上键值*/#define ESC 0x011b/*ESC的ASCLL码*/#define N 200 /*定义全局变量*/int i,key;int score=0;
21、/*得分*/int gamespeed=50000;/*游戏速度自己调整*/struct Food int x;/*食物的横坐标*/ int y;/*食物的纵坐标*/ int yes;/*判断是否要出现食物的变量*/food;/*食物的结构体*/struct Snake int xN; int yN; int node;/*蛇的节数*/ int direction;/*蛇移动方向*/ int life;/* 蛇的生命,0活着,1死亡*/snake;void Init(void);/*图形驱动*/void Close(void);/*图形结束*/void DrawK(void);/*开始画面*/
22、void GameOver(void);/*结束游戏*/void GamePlay(void);/*玩游戏具体过程*/void PrScore(void);/*输出成绩*/*主函数*/void main(void) Init();/*图形驱动*/ DrawK();/*开始画面*/ GamePlay();/*玩游戏具体过程*/ Close();/*图形结束*/*图形驱动*/void Init(void) int gd=DETECT,gm; initgraph(&gd,&gm,c:tc); cleardevice();/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*
23、/*游戏画面的大小区域在左上角坐标为(50,40),右下角坐标为(610,460)内。*/*/*开始画面时,小蛇的初始运动点(即小蛇的运动起点)在左上角坐标为(50,40),右下角坐标为(610,460)的围墙内。同时在本游戏中小蛇都是在左上角坐标为(50,40),右下角坐标为(610,460)的围墙内运动。*/*/void DrawK(void) setbkcolor(LIGHTGREEN); /*设置当前背景颜色(为淡绿色)*/ setcolor(11); /*设置当前画线颜色*/ setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/ for(i=
24、50;i=600;i+=10)/*画围墙*/*小蛇每走一步,得10分。*/ rectangle(i,40,i+10,49); /*上边*/ rectangle(i,451,i+10,460);/*下边*/ for(i=40;i0;i-)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ snake.xi=snake.xi-1;/*小蛇向左移动一步*/ snake.yi=snake.yi-1;/*小蛇向上移动一步*/ /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/ switch(snake.direction) case 1:snake.x0+=10;break; /
25、*蛇向右移动一步,返回*/ case 2: snake.x0-=10;break; /*蛇向左移动一步,返回*/ case 3: snake.y0-=10;break; /*蛇向上移动一步,返回*/ case 4: snake.y0+=10;break; /*蛇向下移动一步,返回*/ for(i=3;isnake.node;i+)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/ if(snake.xi=snake.x0&snake.yi=snake.y0)/*如果蛇的坐标为x=0,y=0*/ GameOver();/*显示失败*/ snake.life=1;/*蛇
26、死了*/ break; if(snake.x0595|snake.y0455)/*蛇是否撞到墙壁(如果蛇的坐标满足横坐标小于55或横坐标大于595或纵坐标小于55或纵坐标大于455)*/ GameOver();/*本次游戏结束*/ snake.life=1; /*蛇死*/ if(snake.life=1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/ break; if(snake.x0=food.x&snake.y0=food.y)/*吃到食物以后*/ setcolor(0);/*把画面上的食物东西去掉(即画面中的食物为背景颜色,即黑色)*/ rectangle(food.x,fo
27、od.y,food.x+10,food.y-10);/*运用rectangle函数计算食物的坐标位置*/ snake.xsnake.node=-20;snake.ysnake.node=-20; /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/ snake.node+;/*蛇的身体长一节*/ food.yes=1;/*画面上需要出现新的食物*/ score+=10;/*(吃到食物后)分数加10分*/ PrScore();/*输出新得分*/ setcolor(4);/*画出蛇*/ for(i=0;isnake.node;i+) rectangle(snake.xi,snake.yi,
28、snake.xi+10, snake.yi-10); delay(gamespeed); setcolor(0);/*用黑色去除蛇的的最后一节*/ rectangle(snake.xsnake.node-1,snake.ysnake.node-1, /*运用rectangle函数来计算小蛇尾部的位置 */ snake.xsnake.node-1+10,snake.ysnake.node-1-10);/*小蛇尾部的横坐标就等于小蛇头部的横坐标减去一再加上10,小蛇我尾部的纵坐标就等于小蛇头部的纵坐标减去加上10(即表示尾巴长一节)*/ if(snake.life=1)/*如果蛇死就跳出循环*/
29、break; key=bioskey(0);/*接收按键*/ if(key=ESC)/*按ESC键退出*/ break; else if(key=UP&snake.direction!=4)/*如果小蛇的接收按键为向上且小蛇所指向的方向不是4(即小蛇不指向下)*/*判断是否往相反的方向移动*/ snake.direction=3;/*小蛇向上转*/ else if(key=RIGHT&snake.direction!=2)/*如果小蛇的接收按键为向右且小蛇所指向的方向不是向2(即小蛇不指向左)*/ snake.direction=1; /*小蛇向右转*/ else if(key=LEFT&sn
30、ake.direction!=1)/*如果小蛇的接收按键为向左且小蛇的所指向的 方向不是1(即小蛇不指向下)*/ snake.direction=2;/*小蛇向左转*/ else if(key=DOWN&snake.direction!=3)/*如果小蛇的接收按键为向下且小蛇所指向的方向不是3(即小蛇不指向上)*/ snake.direction=4;/*小蛇向下转*/ /*endwhile(1)*/*游戏结束*/void GameOver(void) cleardevice(); PrScore();/*输出新的得分*/ setcolor(RED);/*/ settextstyle(0,0,
31、4); outtextxy(200,200,GAME OVER); getch();/*输出成绩*/void PrScore(void) char str10;/*char类型的字符串变量str,长度为10个char*/ setfillstyle(SOLID_FILL,BLUE);/*设置线型*/ bar(50,15,220,35);/*画一个二维条形图*/ setcolor(6); settextstyle(0,0,2);/*为图形输出设置当前的文本属性*/ sprintf(str,score:%d,score);/*输出score为多少(即输出分数)*/ outtextxy(55,20,s
32、tr);/*进行输出一个整型数据(定下输出分数的位置为x=55,y=20)*/*图形结束*/void Close(void) getch(); closegraph();第五章 调试与测试4.1调试 在TC中选中文件,打开所需运行的程序,及贪吃蛇程序。开始出现界面。 游戏具体运行过程,小蛇运动。4. 游戏结束,输出分数。4.2测试 在TC中选中文件,打开所需运行的程序,及贪吃蛇程序。开始出现界面。 游戏具体运行过程,小蛇运动,吃到食物。5. 游戏结束,输出分数。 第六章 总结与心得 此次课程设计,使我仍感慨颇多,的确,从确定题目到完成整个编程,从理论到实践,在短短两周时间里,可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,