贪吃蛇游戏C程序设计报告.docx
《贪吃蛇游戏C程序设计报告.docx》由会员分享,可在线阅读,更多相关《贪吃蛇游戏C程序设计报告.docx(23页珍藏版)》请在冰豆网上搜索。
![贪吃蛇游戏C程序设计报告.docx](https://file1.bdocx.com/fileroot1/2023-3/29/eb68a7cb-f72c-40a7-a02e-727035dba973/eb68a7cb-f72c-40a7-a02e-727035dba9731.gif)
贪吃蛇游戏C程序设计报告
目录
一.设计要求2
二.设计的作用、目的2
三.课题分析2
1.贪吃蛇游戏功能分析2
2.游戏界面分析3
3.设计思路分析3
四.设计的具体实现3
1.系统组成模块结构及功能3
(1)函数定义3
(2)主函数main()4
(3)画界面函数DrawK()5
(4)游戏具体过程函数GamePlay()6
(5)游戏结束函数GameOver()9
2.系统程序结构及流程图10
3.重要函数介绍12
4.程序代码编写及注释14
5.软件调试问题分析及解决方法20
6.软件运行结果20
五.心得体会及建议22
六.参考文献23
贪吃蛇游戏C程序设计报告
一.设计要求
通过游戏程序设计,提高编程兴趣与编程思路,巩固C语言中所学的知识,合理的运用资料,实现理论与实际相结合。
(1).收集资料,分析课题,分解问题,形成总体设计思路;
(2).深入分析各个小问题,列出大纲,编写各部分程序模块;
(3).对于设计中用到的关键函数,要学会通过查资料,弄懂其用法,要联系问题进行具体介绍;
(4).上机调试,查错,逐步分析不能正常运行的原因,确保所设计的程序正确,并且能正常运行;
(5).完成课程设计报告,并进行答辩。
二.设计的作用、目的
C语言是一种易学易懂的通用程序设计语言,由于它具有功能性强,运用简洁,灵活兼有高级语言与低级语言的优点,以及“目标程序效率高”可移植性和能在各种系统上普遍实现等特点使它成为当今世界上的主流程序设计语言之一,同时被选作目前全世界广泛应用,同时也是大学生必修的科目。
作为当代的大学生要很好的利用它,学好一门设计语言,实现学以至用。
制作C程序报告,是为了巩固和加深对C语言课程的基本知识的理解和掌握,并且能够掌握C语言编程和程序调试的基本技能。
通过游戏程序的设计训练和提高学生的基本技能,掌握字符串的表示方法和字符串函数的功能、TurboC图形操作的基本知识、键盘上特殊键的获取以及图形方式下光标的显示,提高编程兴趣与编程水平,学会如何正确的书写程序设计说明文档,提高运用C语言解决实际问题的能力,巩固C语言语法规则的理解和掌握,学会通过源程序写出流程图,提高自学以及查阅资料的能力。
三.课题分析
1.贪吃蛇游戏功能分析
C语言是一种中性化的语言,用C语言来编写程序实现贪吃蛇游戏,能有效反映本有本游戏的基本特点。
编写C语言程序实现贪吃蛇游戏,贪吃蛇游戏是一个深受人们喜欢的游戏:
一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过键盘上的四个光标键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被吃掉,这时蛇的身体长一节,同时计10分;接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉(蛇头撞到自己的身体)游戏结束。
2.游戏界面分析
程序运行时边框表示围墙,红色矩形块代表蛇,黄色小方块代表食物。
3.设计思路分析
这个程序的关键点是表示蛇的图形以及蛇的移动。
用一个小矩形块表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。
移动从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。
如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头的方向移动,图形的实现是从蛇头的新位置开始画出蛇,这时,由于没有清屏的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来蛇会多一节身体,所以将蛇的最后一节用背景色来覆盖。
食物的出现和消失是以画矩形块和覆盖矩形块来表示的
四.设计的具体实现
1.系统组成模块结构及功能
本贪吃蛇程序包括以下主要的模块:
(1)函数定义
函数定义是对各个基础函数的定义,并且设置需要运用的信息,便于调用
#defineN200
#include/*图形头文件*/
#include/*包含rand等函数*/
#include/*包含bios函数*/
#defineLEFT0x4b00/*光标左键值*/
#defineRIGHT0x4d00/*光标右键值*/
#defineDOWN0x5000/*光标下键值*/
#defineUP0x4800/*光标上键值*/
#defineESC0x011b/*ESC的ASCII码*/
inti,key;/*图形坐标变量及按键变量*/
intscore=0;/*得分*/
intgamespeed=10000;/*游戏速度自己调整*/
structFood
{
intx;/*食物的横坐标*/
inty;/*食物的纵坐标*/
intyes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
structSnake
{
intx[];/*蛇的横坐标*/
inty[];/*蛇的纵坐标*/
intnode;/*蛇的节数*/
intdirection;/*蛇移动方向*/
intlife;/*蛇的生命,0活着,1死亡*/
}snake;
voidInit(void);/*图形驱动*/
voidClose(void);/*图形结束*/
voidDrawK(void);/*画界面函数*/
voidGameOver(void);/*结束游戏*/
voidGamePlay(void);/*玩游戏具体过程*/
voidPrScore(void);/*输出成绩*/
voidmain(void)/*主函数*/
(2)主函数main()
主函数是程序的主流程,首先定义使用到的常数、全局变量及函数原型说明,然后初始化图形系统,调用函数DrawK()画出开始画面,调用函数GamePlay(),即玩游戏的具体过程,游戏结束后调用Close()关闭图形系统,结束程序
voidmain(void)/*主函数*/
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
voidInit(void)/*图形驱动*/
{
intgd=DETECT,gm;
initgraph(&gd,&gm,"c:
\\tc");/*第一个参数表示图形适配器的类型,第二个为在该类型下图形的显示模式,第三个参数指定驱动程序所在目录。
*/
cleardevice();
}
(3)画界面函数DrawK()
主界面是一个封闭的围墙,用两个循环语句分别在水平和垂直方向输出连续的宽度和高度均的矩形方块,表示围墙,为了醒目,设置为白色。
voidDrawK(void)/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
{
setbkcolor(0);/*设置当前背景颜色*/
setcolor(YELLOW);/*设置当前画线颜色*/
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=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(601,i,610,i+10);/*右边*/
}
}
(4)游戏具体过程函数GamePlay()
这是游戏的主要组成部分,他采用将前一节的坐标赋给后一节,用背景颜色将最后节去除,当蛇头的坐标与食物的坐标相等时,表示食物被吃掉了。
voidGamePlay(void)/*玩游戏具体过程*/
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;/*蛇第二节*/
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while
(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!
kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!
=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!
=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(GREEN);/*食物的颜色*/
rectangle(food.x,food.y,food.x+10,food.y-10);
}
for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,贪吃蛇的关键算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
switch(snake.direction)/*定义1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
{
case1:
snake.x[0]+=10;break;
case2:
snake.x[0]-=10;break;
case3:
snake.y[0]-=10;break;
case4:
snake.y[0]+=10;break;
}
for(i=3;i{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();/*显示失败*/
snake.life=1;
break;
}
}
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1;/*蛇死*/
}
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/
{
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;/*-20表示尾巴长一节*/
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/
}
setcolor(4);
for(i=0;irectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);
}/*endwhile(!
kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循环*/
break;
key=bioskey(0);/*接收按键*/
if(key==ESC)/*按ESC键退出*/
break;
else
if(key==UP&&snake.direction!
=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!
=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!
=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!
=3)
snake.direction=4;
}/*endwhile
(1)*/
}
(5)游戏结束函数GameOver()
游戏结束,清除屏幕,输出分数,显示游戏结束信息。
voidGameOver(void)/*游戏结束*/
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"guojian");
getch();
}
voidPrScore(void)/*输出成绩*/
{
charstr[10];
setfillstyle(SOLID_FILL,WHITE);
bar(50,15,200,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:
%d",score);
outtextxy(55,20,str);
}
voidClose(void)/*图形结束*/
{
getch();
closegraph();
}
2.系统程序结构及流程图
3.重要函数介绍
1)主函数main()
初始化图形系统,调用DrawK()画出开始画面,调用函数GamePlay(),即玩游戏过程,游戏结束后调用Close()关闭图形系统,结束程序。
2)画界面函数DrawK();
主界面是一个封闭的围墙,用两个循环语句分别在水平和垂直方向输出连续的宽度和高度均为10个单位的矩形方块,表示围墙,为了醒目,设置为黄色。
3)游戏具体过程函数GamePlay();
这是游戏的主要组成部分,他采用将前一节的坐标赋给后一节,用背景颜色将最后一节去除,当蛇头的坐标与食物的坐标相等时,表示食物被吃掉了。
4)游戏结束函数GameOver()
游戏结束,清除屏幕,输出分数,显示游戏结束信息。
5)PrScore(),输出分数。
6)Close()函数图形结束。
在显示游戏结束信息的画面时,按任意键关闭图形系统,程序结束。
7).Setbkcolor()设置背景颜色函数
起调用格式为:
setbkcolor(color);
该函数用与设置绘图是的背景颜色。
参数color可取表1.1中的符号或数值。
表1.2Color值表
符号常数
数值
含义
字符或背景
Black
0
黑
字符/背景
Bluk
1
蓝
字符/背景
Green
2
绿
字符/背景
Cyan
3
青
字符/背景
Red
4
红
字符/背景
Magenta
5
洋红
字符/背景
Brown
6
棕
字符/背景
Lightggray
7
淡灰
字符/背景
Darkgray
8
深灰
字符
Lightbluk
9
淡蓝
字符
Lightgreen
10
淡绿
字符
Lightcyan
11
淡青
字符
Lightred
12
淡红
字符
Liaghtmagenta
13
淡洋红
字符
Yellow
14
黄
字符
White
15
白
字符
8)setcolor()设置前背景颜色
起调用格式:
setcolor(color);
该函数用于设置前背景颜色(即绘图用的颜色),实际上用当前画笔色设置为参数Color所定的颜色。
参数Color的值应在前图形模式下的有效范围内,一旦用此函数改变了画笔色,随后笔画处的都是此种颜色。
(注意:
所选的颜色为1.2中之一)
9)用到的函数
a.init()图形驱动
其调用格式为:
init()
表1.1图形驱动程序
符号名
数值
DETECT
0
CGA
1
MCGA
2
EGC
3
EGA64
4
EGAMONO
5
IBM8514
6
HERCMONO
7
ATT400
8
VGA
9
PC3270
10
b.getch()
其调用格式为:
intgetch(void);
从控制台无回显地取一个字符
c.outtextxy()
其调用格式为:
outtextxy(x,y,textstring);
该函数在指定位置以当前一字符串。
d.closegraph()关闭图形方式函数
其调用格式为:
closegraph();
该函数释放图形函数所占的内存,关闭图形方式,返回到调用initgraph()前的模式,就可继续运行程序。
e.setfillstyle()
其调用格式为:
setfillstyle();
该函数填充模式和颜色
用法:
voidfarsetfillstyle(intpattern,intcolor);
f.settextstyle()
其调用格式为:
settextstyle(font,direction,charsize);
该函数输出设置当前的文本属性如:
用于设置输出文本的字体、文本显示方式和字符的大小。
g.setbkcolor()
其调用格式为:
setbkcolor();
该函数填充游戏界面的颜色,用调色板设置当前背景颜色。
h.sprintf()
其调用格式为:
sprintf();该函数输送格式化输出到字符串中。
i.kbhit()其调用格式为:
kbhit();该函数检查当前按下的键是否为有效按键。
4.程序代码编写及注释
#defineN200
#include
#include
#include
#defineLEFT0x4b00
#defineRIGHT0x4d00
#defineDOWN0x5000
#defineUP0x4800
#defineESC0x011b
inti,key;
intscore=0;/*得分*/
intgamespeed=50000;/*游戏速度自己调整*/
structFood
{
intx;/*食物的横坐标*/
inty;/*食物的纵坐标*/
intyes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
structSnake
{
intx[N];
inty[N];
intnode;/*蛇的节数*/
intdirection;/*蛇移动方向*/
intlife;/*蛇的生命,0活着,1死亡*/
}snake;
voidInit(void);/*图形驱动*/
voidClose(void);/*图形结束*/
voidDrawK(void);/*开始画面*/
voidGameOver(void);/*结束游戏*/
voidGamePlay(void);/*玩游戏具体过程*/
voidPrScore(void);/*输出成绩*/
/*主函数*/
voidmain(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
voidInit(void)
{
intgd=DETECT,gm;
initgraph(&gd,&gm,"c:
\\tc");
cleardevice();
}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
voidDrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=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(601,i,610,i+10);/*右边*/
}
}
/*玩游戏具体过程*/
voidGamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while
(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!
kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!
=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!
=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(GREEN);