程序设计实践
题
目
贪吃蛇
学生姓名 教学院系 专业年级
学 号
计算机科学学院 软件工程2015级
完成日期
2016 年 6 月
摘 要
智能设备诞生以来,各种APP 游戏层出不穷伴随着科学技术的发展,人们都渴望在不工作的时候有一些娱乐活动,而贪吃蛇这一款游戏正好符合大众的心理。所以,为了迎合许多用户的需求,才开发了这款叫做贪吃蛇的小游戏,并且这款小游戏适合各阶层人士,此外它还具有很强的娱乐性和交互性。
尽管现在市面上存在的游戏版本很多,可是贪吃蛇的市场还是很大的。原因就在与它能引人入深,爱不释手。随着游戏速度的逐渐加快,其刺激性也更强。可以说该游戏的优势不仅在于它的简单易行,而且在于它很快顺利的运行。对于那些在外忙忙碌碌的人们,想让他们花费大量的时间在大型游戏上显然是不可能的,但是小游戏却刚好能够迎合他们的需求。
关键词: C 语言 Easy X photoshop 函数 游戏
目录
1绪论................................................................................................................................................ 5
1.1设计背景 . ............................................................................................................................ 5 1.2设计的目的和意义 . ............................................................................................................ 5 2游戏设计 . ....................................................................................................................................... 6
2.1 游戏需求分析 . .................................................................................................................... 6 2.2系统总体流程 . .................................................................................................................... 6 2.3系统主要模块函数设计 . .................................................................................................... 7
2.3.1思路的分析 . ............................................................................................................. 7 2.3.2地图绘制 . ................................................................................................................. 9 2. 3.3加入背景音乐 . ...................................................................................................... 11 2. 3.4绘制贪吃蛇本体 . .................................................................................................. 12 2.3.5贪吃蛇的移动和控制 . ........................................................................................... 13 2. 3.6绘制苹果 . .............................................................................................................. 14 2. 3.7蛇吃苹果 . .............................................................................................................. 15 2. 3.8判断贪吃蛇咬到自己 . .......................................................................................... 15 2. 3.9判断撞到墙 . .......................................................................................................... 16 2. 3.10结束游戏函数 . .................................................................................................... 16 2. 3.11更改UI 界面和backmusic 背景音乐 ................................................................ 16
3游戏测试 . ..................................................................................................................................... 17 4结论.............................................................................................................................................. 19
4.1设计完成任务 . .................................................................................................................. 19 4.2设计中遇到的困难 . .......................................................................................................... 19 4.3展望................................................................................................................................... 20 5. 源代码.......................................................................................................................................... 21
1绪论
1.1设计背景
信息化时代,智能设备已经做到人手一部,大家通过智能设备玩游戏已经成
为一个必不可少的手段打发时间和放松自己的手段。本游戏可以很方便的移植到IOS 安卓等便携设备和平台上。
1.2设计的目的和意义
本游戏利用VC++6.0,Easy X插件库,Visual Studio 2015,VA 番茄助手,Photoshop cs6.0,格式工厂等技术软件设计的一款人尽皆知老少皆宜的益智类游戏,搞笑的风格和有节奏的背景音乐能让人在紧张工作学习之余得到放松。
2游戏设计
2.1 游戏需求分析
本游戏是基于C 语言和Easy X环境库编译运行的小游戏,主要几个模块为地图搭建,贪吃蛇本体搭建,随机产生食物,蛇吃食物会变长,蛇咬到自己判定死亡,撞墙判定死亡,最后设计UI 界面,加入背景音乐。
2.2系统总体流程
2.3系统主要模块函数设计
从上到下的函数: 地图函数 背景音乐函数 创建贪吃蛇函数 移动贪吃蛇函数 创建食物函数 吃食物变长的函数 吃到自己函数 碰到墙的函数 暂停函数 结束游戏函数 游戏控制函数 主函数
2.3.1思路的分析
首先我收到了一个很详细的PDF ,里面有所有的搭建环境的教程还有大部分代码,首先搭建环境,要安装Easy X环境库,用VC++6.0作为编译器。测试是否安装成功。
然后看PDF 文件的设计思路,发现蛇本体用一个数组表示更方便,绘制时使用遍历数组可以,但是数组是固定的长度,不能随吃苹果数量,蛇身体边长,怎么办?所以最后决定用链表表示。
每个蛇身体就是一个节点,每个节点有左右上下坐标。确定为20,每吃一个苹果,增加一个链表节点。这个表示方法可行。
场景分析:
分析一下游戏场景(地图),发现可以用0来表示地图可以移动的区域,用1来表示墙。二维数组即可表示整个平面地图。
场景建立结果见3-1。
2.3.2地图绘制
规定游戏地图的区域25X30()包括边界:
初始化数组的值,中间的23X28为0,边界为1:
这里直接加载图片,设置上下左右边界的草坪(墙),方便接下来绘制地图边界,注意一定要是20X20的分辨率的图片:
学生资源提供的草边界为jpg 格式的图片:
绘制上下边界:
绘制左右边界:
:
:这段代码,规定背景色为绿色,在第一排中间位置显示“LHR 超级贪吃蛇”。
现在地图搭建完毕,运行结果图见3-1。
2. 3.3加入背景音乐
接下来加入背景音乐: 需要引用这个声音库:
第一行代码是打开backmusic.wma 文件 第二份代码设置音量大小为300 第三行代码设置重复播放 注意一下:为了防止编译时文件拷贝到其他文件盘的根目录下导致使用绝对位置而打不开文件,所以贴图和背景音乐都使用的是相对位置。
学生资源提供了一个 backmusic.wma 的文件:
2. 3.4绘制贪吃蛇本体
将蛇身体转化为行列坐标,每个节点为20X20:
遍历输出蛇身体,默认为红色,蛇头居中加一个黄色的圆圈作为眼睛:
绘制效果如图3-2:。
2.3.5贪吃蛇的移动和控制
遍历输出蛇身体,蛇身体随着蛇头移动到后一个位置。 控制蛇身体的移动:
根据键盘映射,上下左右按键移动。
2. 3.6绘制苹果
创建一个随机苹果,判断蛇身体是否与苹果重合,重合则判断苹果存在,并贴入苹果的图片。
2. 3.7蛇吃苹果
判断蛇是否吃到苹果,如果被吃了,蛇头向前延伸一格,绘制新蛇头这里注意不能向后延伸,会出现断裂。效果见图3-3。
2. 3.8判断贪吃蛇咬到自己
只要头接触到自己的身体就判定return1,并返回endgamestatus =2。
2. 3.9判断撞到墙
规定上下左右的区域,只要超出就判定为return1 并返回endgamestatus =1。
2. 3.10结束游戏函数
结束游戏函数,当endgamestatus=1和=2和=3时候,分别输出3种结果并且输出玩
家的得分,效果见图3-4。
2. 3.11更改UI 界面和backmusic 背景音乐
最后一步美化界面,用Photoshop 裁剪图片为20*20像素的jpg 格式的图片,后用格式工厂转换一首背景音乐为wav 格式的音乐。然后直接替换res 目录下的文件。效果如图
3-4.
3游戏测试
图3.1 地图搭建结果
图3.2 贪吃蛇绘制效果
图3.3 贪吃蛇吃苹果运行界面
图3.4贪吃蛇死亡界面
4结论
4.1设计完成任务
本游戏实现了创建链表贪吃蛇,吃苹果增加长度的功能,基础功能已经实现,死亡判定也已经完善(咬到自己,撞到墙,按ESC 结束游戏)。功能实现以后,做UI 替换,改变地图的围墙,四周的贴图都要替换,改变苹果的贴图,更有创意和趣味,最后换一个欢快的音乐。
4.2设计中遇到的困难
在此次系统设计中,遇到了好些问题,首先是对C 语言的不熟悉导致偶尔符号有错误,第一个遇到的问题是贪吃蛇的吃不了苹果的问题,第二个遇到的问题是地图,发现地图在边界的前一格就会死亡,在四周的边界都+20个单位,解决了该问题,最后发现一个难解决的问题,贪吃蛇吃点苹果后蛇的身体是向前变长的,如果苹果在四个角边缘,吃掉苹果后会蛇头变长撞死在边缘,尝试了一下让蛇的身体向后变长,但是会导致蛇身体收缩一格后变长,有时会尾部撕裂,
又改
回蛇头增长了,此问题暂时无法解决。虽然说,设计的过程是艰苦的,但是其中所带给我的快乐却是不言而喻的。
4.3展望
它很快顺利的运行。对于忙碌在外没有大型设备的人们来说,这样的游戏刚好迎合他们的需求,老少皆宜,用C 语言编译的贪吃蛇由于的底层语言,很容易移植到各类型设备上,手机,电脑,小心掌机,都能顺畅的运行它。
5. 源代码
#include
#include
#include
#pragma comment( lib,"winmm.lib")
#define ROWS 25
#define COLS 30
int map [ROWS ][COLS ];
#define X 0
#define Y 80
typedef struct SNAKE
{
int left ;
int top ;
int right ;
int bottom ;
struct SNAKE *next ;
}snake ;
snake *head ,*tail ;
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
int direction =RIGHT ;
snake *food ;
bool IsExistFood =false;
int score =0;
int endgamestatus ;
void InitMap()
{
setbkcolor (GREEN );
cleardevice ();
RECT r ={0,0,600,100};
drawtext (_T(" LHR超级贪食蛇"),&r , DT_CENTER | DT_VCENTER |
DT_SINGLELINE);
int i , j ;
for(i =0;i
for(j =0;j
{
if(i ==0||i ==(ROWS -1)||j ==0||j ==(COLS -1))
map [i ][j ]=1;
else
map [i ][j ]=0;
}
IMAGE imgtop , imgleft , imgright , imgbottom ;
loadimage (&imgtop ,"res\\grasstop.jpg");
loadimage (&imgleft ,"res\\grassleft.jpg");
loadimage (&imgright ,"res\\grassright.jpg");
loadimage (&imgbottom ,"res\\grassbottom.jpg");
//绘制的图形
int left =X , top =Y , right =left =20,bottom =top +20;
for(i =0;i
{
left =X ;
right =left +20;
for(j =0;j
{
if(map [i ][j ]==1&&i ==0)
{
putimage (left , top ,&imgtop );
}
if(map [i ][j ]==1&&i ==(ROWS -1))
{
putimage (left , top ,&imgbottom );
}
if(map [i ][j ]==1&&j ==0)
{
putimage (left , top ,&imgleft );
}
if(map [i ][j ]==1&&j ==(COLS -1))
{
putimage (left , top ,&imgright );
}
if(map [i ][j ]==0)
{
setfillcolor (GREEN );
fillrectangle (left , top , right , bottom );
}
left +=20;
right +=20;
}
top +=20;
bottom +=20;
}
}
void playmusic()
{
mciSendString ("open res\\backmusic.wma alias BackMusic",NULL ,0, NULL ); mciSendString ("setaudio BackMusic volume to 300",NULL ,0, NULL ); mciSendString ("play BackMusic repeat",NULL ,0, NULL );
}
void initsnake()
{
head =(snake *)malloc (sizeof(snake ));
snake *p ;
int startRow =10,startCol =5;
head ->left =startCol *20;
head ->top =startRow *20;
head ->right =(startCol +1)*20;
head ->bottom =(startRow +1)*20;
p =head ;
for(int i =0;i
tail =(snake *)malloc (sizeof(snake ));
tail ->left =startCol *20;
tail ->top =(startRow +i +1)*20;
tail ->right =(startCol +1)*20;
tail ->bottom =(startRow +i +2)*20;
p ->next =tail ;
tail ->next =NULL ;
p =tail ;
}
p =head ;
while(p !=NULL )
{
setfillcolor (RED );
fillrectangle (p ->left , p ->top , p ->right , p ->bottom );
if(p ==head )
{
int x =(p ->left +p ->right )/2;
int y =(p ->top +p ->bottom )/2;
}
p =p ->next ;
}
}
void movesnake()
{
int left , top , right , bottom ;
int newleft , newtop , newright , newbottom ;
snake *p ;
setcolor (WHITE );
setfillcolor (GREEN );
fillrectangle (tail ->left , tail ->top , tail ->right , tail ->bottom );
p =head ;
while(p !=NULL )
{ Sleep (50);
if(p ==head )
{
newleft =p ->left ;
newtop =p ->top ;
newright =p ->right ;
newbottom =p ->bottom ;
if(direction ==RIGHT ){p ->left +=20;p ->right +=20;}
if(direction ==LEFT ){p ->left -=20;p ->right -=20;}
if(direction ==UP ){p ->top -=20;p ->bottom -=20;}
if(direction ==DOWN ){p ->top +=20;p ->bottom +=20;}
}
else
{
left =p ->left ; top =p ->top ; right =p ->right ; bottom =p ->bottom ;
p ->left =newleft ; p ->right =newright ; p ->top =newtop ; p ->bottom =newbottom ;
newleft =left ; newtop =top ; newright =right ; newbottom =bottom ;
}
setcolor (WHITE ); setfillcolor (RED );
fillrectangle (p ->left , p ->top , p ->right , p ->bottom );
if(p ==head )
{
fillrectangle (newleft , newtop , newright , newbottom );
int x =(p ->left +p ->right )/2;
int y =(p ->top +p ->bottom )/2;
}
p =p ->next ;
}
}
void createfood()
{
snake *p ;
srand ((unsigned)time (NULL ));
food =(snake *)malloc (sizeof(snake ));
int row =rand ()%ROWS ;
int col =rand ()%COLS ;
if(row ==0)
row =1;
if(row ==(ROWS -1))
row =ROWS -2;
if(col ==0)
col =1;
if(col ==(COLS -1))
col =COLS -2;
food ->left =col *20;
food ->right =food ->left +20;
food ->top =row *20+80;
food ->bottom =food ->top +20;
p =head ;
bool ISSame =false;
while(p !=NULL )
{
if(p ->left ==food ->left &&p ->top ==food ->top &&p ->right ==food ->right &&p ->bo ttom ==food ->bottom )
{ ISSame =true;
free (food );
createfood();
}
p =p ->next ;
}
if(!ISSame ){
IMAGE imgfood ;
loadimage (&imgfood ,"res\\apple.jpg");
putimage (food ->left +1,food ->top +1,&imgfood );
}
void eatefood()
{
snake *p ;
p =head ;
bool IsEated =false;
//右
if(head ->left +20==food ->left &&head ->right +20==food ->right &&head ->top ==f ood ->top &&head ->bottom ==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//左
if(head ->left -20==food ->left &&head ->right -20==food ->right &&head ->top ==fo od ->top &&head ->bottom ==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//下
if(head ->left ==food ->left &&head ->right ==food ->right &&head ->top +20==food ->top &&head ->bottom +20==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//上
if(head ->left ==food ->left &&head ->right ==food ->right &&head ->top -20==food ->top &&head ->bottom -20==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
if(IsEated )
{
score ++;
fillrectangle (p ->left ,p ->top , p ->right , p ->bottom );
fillrectangle (p ->left ,p ->top , p ->right , p ->bottom );
int x =(head ->left +head ->right )/2;
int y =(head ->top +head ->bottom )/2;
setfillcolor (YELLOW );
fillcircle (x , y ,2);
}
}
int biteself()
{
snake *p ;
p =head ->next ;
while(p !=NULL )
{
if(p ->left ==head ->left &&p ->top ==head ->top &&p ->right ==head ->right &&p ->b ottom ==head ->bottom )
{
endgamestatus =2;
return 1;
}
p =p ->next ;
}
return 0;
}
int cantcrosswall()
{
if(head ->left right >580|head ->top bottom >560)
{
endgamestatus =1;
return 1;
}
return 0;
}
void pause()
{
while(1)
{
Sleep (300);
if(GetAsyncKeyState (VK_SPACE) )
{
break;
}
}
}
void endgame()
{
RECT r ={0,100,600,200};
RECT r2={0,200,600,300};
if(endgamestatus ==1)
{
drawtext (_T("对不起,您撞到墙了。按空格游戏结束。"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
else if(endgamestatus ==2)
{
drawtext (_T("对不起,您咬到自己了。按空格游戏结束。
"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
else if(endgamestatus ==3)
{
drawtext (_T("您已经结束了游戏。按空格游戏结束。"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
char s []="你的得分";
char GetScore [10];
itoa (score , GetScore ,10);
outtextxy (10,20,s );
outtextxy (80,20,GetScore );
pause();
exit (0);
}
void GameControl()
{
while(1)
{
if(GetAsyncKeyState (VK_UP) )
{
direction =UP ;
}
else if(GetAsyncKeyState (VK_DOWN) ) {
direction =DOWN ;
}
else if(GetAsyncKeyState (VK_LEFT) ) {
direction =LEFT ;
}
else if(GetAsyncKeyState (VK_RIGHT) ) {
direction =RIGHT ;
}
else if(GetAsyncKeyState (VK_ESCAPE) ) {
break;
}
movesnake();
if(!IsExistFood )
createfood();
eatefood();
if(biteself()==1||cantcrosswall()==1)
{
endgame();
}
}
}
void main(int argc ,char * argv [])
{
initgraph (800,600);
InitMap();
playmusic();
initsnake();
GameControl();
getch ();
closegraph ();
}
程序设计实践
题
目
贪吃蛇
学生姓名 教学院系 专业年级
学 号
计算机科学学院 软件工程2015级
完成日期
2016 年 6 月
摘 要
智能设备诞生以来,各种APP 游戏层出不穷伴随着科学技术的发展,人们都渴望在不工作的时候有一些娱乐活动,而贪吃蛇这一款游戏正好符合大众的心理。所以,为了迎合许多用户的需求,才开发了这款叫做贪吃蛇的小游戏,并且这款小游戏适合各阶层人士,此外它还具有很强的娱乐性和交互性。
尽管现在市面上存在的游戏版本很多,可是贪吃蛇的市场还是很大的。原因就在与它能引人入深,爱不释手。随着游戏速度的逐渐加快,其刺激性也更强。可以说该游戏的优势不仅在于它的简单易行,而且在于它很快顺利的运行。对于那些在外忙忙碌碌的人们,想让他们花费大量的时间在大型游戏上显然是不可能的,但是小游戏却刚好能够迎合他们的需求。
关键词: C 语言 Easy X photoshop 函数 游戏
目录
1绪论................................................................................................................................................ 5
1.1设计背景 . ............................................................................................................................ 5 1.2设计的目的和意义 . ............................................................................................................ 5 2游戏设计 . ....................................................................................................................................... 6
2.1 游戏需求分析 . .................................................................................................................... 6 2.2系统总体流程 . .................................................................................................................... 6 2.3系统主要模块函数设计 . .................................................................................................... 7
2.3.1思路的分析 . ............................................................................................................. 7 2.3.2地图绘制 . ................................................................................................................. 9 2. 3.3加入背景音乐 . ...................................................................................................... 11 2. 3.4绘制贪吃蛇本体 . .................................................................................................. 12 2.3.5贪吃蛇的移动和控制 . ........................................................................................... 13 2. 3.6绘制苹果 . .............................................................................................................. 14 2. 3.7蛇吃苹果 . .............................................................................................................. 15 2. 3.8判断贪吃蛇咬到自己 . .......................................................................................... 15 2. 3.9判断撞到墙 . .......................................................................................................... 16 2. 3.10结束游戏函数 . .................................................................................................... 16 2. 3.11更改UI 界面和backmusic 背景音乐 ................................................................ 16
3游戏测试 . ..................................................................................................................................... 17 4结论.............................................................................................................................................. 19
4.1设计完成任务 . .................................................................................................................. 19 4.2设计中遇到的困难 . .......................................................................................................... 19 4.3展望................................................................................................................................... 20 5. 源代码.......................................................................................................................................... 21
1绪论
1.1设计背景
信息化时代,智能设备已经做到人手一部,大家通过智能设备玩游戏已经成
为一个必不可少的手段打发时间和放松自己的手段。本游戏可以很方便的移植到IOS 安卓等便携设备和平台上。
1.2设计的目的和意义
本游戏利用VC++6.0,Easy X插件库,Visual Studio 2015,VA 番茄助手,Photoshop cs6.0,格式工厂等技术软件设计的一款人尽皆知老少皆宜的益智类游戏,搞笑的风格和有节奏的背景音乐能让人在紧张工作学习之余得到放松。
2游戏设计
2.1 游戏需求分析
本游戏是基于C 语言和Easy X环境库编译运行的小游戏,主要几个模块为地图搭建,贪吃蛇本体搭建,随机产生食物,蛇吃食物会变长,蛇咬到自己判定死亡,撞墙判定死亡,最后设计UI 界面,加入背景音乐。
2.2系统总体流程
2.3系统主要模块函数设计
从上到下的函数: 地图函数 背景音乐函数 创建贪吃蛇函数 移动贪吃蛇函数 创建食物函数 吃食物变长的函数 吃到自己函数 碰到墙的函数 暂停函数 结束游戏函数 游戏控制函数 主函数
2.3.1思路的分析
首先我收到了一个很详细的PDF ,里面有所有的搭建环境的教程还有大部分代码,首先搭建环境,要安装Easy X环境库,用VC++6.0作为编译器。测试是否安装成功。
然后看PDF 文件的设计思路,发现蛇本体用一个数组表示更方便,绘制时使用遍历数组可以,但是数组是固定的长度,不能随吃苹果数量,蛇身体边长,怎么办?所以最后决定用链表表示。
每个蛇身体就是一个节点,每个节点有左右上下坐标。确定为20,每吃一个苹果,增加一个链表节点。这个表示方法可行。
场景分析:
分析一下游戏场景(地图),发现可以用0来表示地图可以移动的区域,用1来表示墙。二维数组即可表示整个平面地图。
场景建立结果见3-1。
2.3.2地图绘制
规定游戏地图的区域25X30()包括边界:
初始化数组的值,中间的23X28为0,边界为1:
这里直接加载图片,设置上下左右边界的草坪(墙),方便接下来绘制地图边界,注意一定要是20X20的分辨率的图片:
学生资源提供的草边界为jpg 格式的图片:
绘制上下边界:
绘制左右边界:
:
:这段代码,规定背景色为绿色,在第一排中间位置显示“LHR 超级贪吃蛇”。
现在地图搭建完毕,运行结果图见3-1。
2. 3.3加入背景音乐
接下来加入背景音乐: 需要引用这个声音库:
第一行代码是打开backmusic.wma 文件 第二份代码设置音量大小为300 第三行代码设置重复播放 注意一下:为了防止编译时文件拷贝到其他文件盘的根目录下导致使用绝对位置而打不开文件,所以贴图和背景音乐都使用的是相对位置。
学生资源提供了一个 backmusic.wma 的文件:
2. 3.4绘制贪吃蛇本体
将蛇身体转化为行列坐标,每个节点为20X20:
遍历输出蛇身体,默认为红色,蛇头居中加一个黄色的圆圈作为眼睛:
绘制效果如图3-2:。
2.3.5贪吃蛇的移动和控制
遍历输出蛇身体,蛇身体随着蛇头移动到后一个位置。 控制蛇身体的移动:
根据键盘映射,上下左右按键移动。
2. 3.6绘制苹果
创建一个随机苹果,判断蛇身体是否与苹果重合,重合则判断苹果存在,并贴入苹果的图片。
2. 3.7蛇吃苹果
判断蛇是否吃到苹果,如果被吃了,蛇头向前延伸一格,绘制新蛇头这里注意不能向后延伸,会出现断裂。效果见图3-3。
2. 3.8判断贪吃蛇咬到自己
只要头接触到自己的身体就判定return1,并返回endgamestatus =2。
2. 3.9判断撞到墙
规定上下左右的区域,只要超出就判定为return1 并返回endgamestatus =1。
2. 3.10结束游戏函数
结束游戏函数,当endgamestatus=1和=2和=3时候,分别输出3种结果并且输出玩
家的得分,效果见图3-4。
2. 3.11更改UI 界面和backmusic 背景音乐
最后一步美化界面,用Photoshop 裁剪图片为20*20像素的jpg 格式的图片,后用格式工厂转换一首背景音乐为wav 格式的音乐。然后直接替换res 目录下的文件。效果如图
3-4.
3游戏测试
图3.1 地图搭建结果
图3.2 贪吃蛇绘制效果
图3.3 贪吃蛇吃苹果运行界面
图3.4贪吃蛇死亡界面
4结论
4.1设计完成任务
本游戏实现了创建链表贪吃蛇,吃苹果增加长度的功能,基础功能已经实现,死亡判定也已经完善(咬到自己,撞到墙,按ESC 结束游戏)。功能实现以后,做UI 替换,改变地图的围墙,四周的贴图都要替换,改变苹果的贴图,更有创意和趣味,最后换一个欢快的音乐。
4.2设计中遇到的困难
在此次系统设计中,遇到了好些问题,首先是对C 语言的不熟悉导致偶尔符号有错误,第一个遇到的问题是贪吃蛇的吃不了苹果的问题,第二个遇到的问题是地图,发现地图在边界的前一格就会死亡,在四周的边界都+20个单位,解决了该问题,最后发现一个难解决的问题,贪吃蛇吃点苹果后蛇的身体是向前变长的,如果苹果在四个角边缘,吃掉苹果后会蛇头变长撞死在边缘,尝试了一下让蛇的身体向后变长,但是会导致蛇身体收缩一格后变长,有时会尾部撕裂,
又改
回蛇头增长了,此问题暂时无法解决。虽然说,设计的过程是艰苦的,但是其中所带给我的快乐却是不言而喻的。
4.3展望
它很快顺利的运行。对于忙碌在外没有大型设备的人们来说,这样的游戏刚好迎合他们的需求,老少皆宜,用C 语言编译的贪吃蛇由于的底层语言,很容易移植到各类型设备上,手机,电脑,小心掌机,都能顺畅的运行它。
5. 源代码
#include
#include
#include
#pragma comment( lib,"winmm.lib")
#define ROWS 25
#define COLS 30
int map [ROWS ][COLS ];
#define X 0
#define Y 80
typedef struct SNAKE
{
int left ;
int top ;
int right ;
int bottom ;
struct SNAKE *next ;
}snake ;
snake *head ,*tail ;
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
int direction =RIGHT ;
snake *food ;
bool IsExistFood =false;
int score =0;
int endgamestatus ;
void InitMap()
{
setbkcolor (GREEN );
cleardevice ();
RECT r ={0,0,600,100};
drawtext (_T(" LHR超级贪食蛇"),&r , DT_CENTER | DT_VCENTER |
DT_SINGLELINE);
int i , j ;
for(i =0;i
for(j =0;j
{
if(i ==0||i ==(ROWS -1)||j ==0||j ==(COLS -1))
map [i ][j ]=1;
else
map [i ][j ]=0;
}
IMAGE imgtop , imgleft , imgright , imgbottom ;
loadimage (&imgtop ,"res\\grasstop.jpg");
loadimage (&imgleft ,"res\\grassleft.jpg");
loadimage (&imgright ,"res\\grassright.jpg");
loadimage (&imgbottom ,"res\\grassbottom.jpg");
//绘制的图形
int left =X , top =Y , right =left =20,bottom =top +20;
for(i =0;i
{
left =X ;
right =left +20;
for(j =0;j
{
if(map [i ][j ]==1&&i ==0)
{
putimage (left , top ,&imgtop );
}
if(map [i ][j ]==1&&i ==(ROWS -1))
{
putimage (left , top ,&imgbottom );
}
if(map [i ][j ]==1&&j ==0)
{
putimage (left , top ,&imgleft );
}
if(map [i ][j ]==1&&j ==(COLS -1))
{
putimage (left , top ,&imgright );
}
if(map [i ][j ]==0)
{
setfillcolor (GREEN );
fillrectangle (left , top , right , bottom );
}
left +=20;
right +=20;
}
top +=20;
bottom +=20;
}
}
void playmusic()
{
mciSendString ("open res\\backmusic.wma alias BackMusic",NULL ,0, NULL ); mciSendString ("setaudio BackMusic volume to 300",NULL ,0, NULL ); mciSendString ("play BackMusic repeat",NULL ,0, NULL );
}
void initsnake()
{
head =(snake *)malloc (sizeof(snake ));
snake *p ;
int startRow =10,startCol =5;
head ->left =startCol *20;
head ->top =startRow *20;
head ->right =(startCol +1)*20;
head ->bottom =(startRow +1)*20;
p =head ;
for(int i =0;i
tail =(snake *)malloc (sizeof(snake ));
tail ->left =startCol *20;
tail ->top =(startRow +i +1)*20;
tail ->right =(startCol +1)*20;
tail ->bottom =(startRow +i +2)*20;
p ->next =tail ;
tail ->next =NULL ;
p =tail ;
}
p =head ;
while(p !=NULL )
{
setfillcolor (RED );
fillrectangle (p ->left , p ->top , p ->right , p ->bottom );
if(p ==head )
{
int x =(p ->left +p ->right )/2;
int y =(p ->top +p ->bottom )/2;
}
p =p ->next ;
}
}
void movesnake()
{
int left , top , right , bottom ;
int newleft , newtop , newright , newbottom ;
snake *p ;
setcolor (WHITE );
setfillcolor (GREEN );
fillrectangle (tail ->left , tail ->top , tail ->right , tail ->bottom );
p =head ;
while(p !=NULL )
{ Sleep (50);
if(p ==head )
{
newleft =p ->left ;
newtop =p ->top ;
newright =p ->right ;
newbottom =p ->bottom ;
if(direction ==RIGHT ){p ->left +=20;p ->right +=20;}
if(direction ==LEFT ){p ->left -=20;p ->right -=20;}
if(direction ==UP ){p ->top -=20;p ->bottom -=20;}
if(direction ==DOWN ){p ->top +=20;p ->bottom +=20;}
}
else
{
left =p ->left ; top =p ->top ; right =p ->right ; bottom =p ->bottom ;
p ->left =newleft ; p ->right =newright ; p ->top =newtop ; p ->bottom =newbottom ;
newleft =left ; newtop =top ; newright =right ; newbottom =bottom ;
}
setcolor (WHITE ); setfillcolor (RED );
fillrectangle (p ->left , p ->top , p ->right , p ->bottom );
if(p ==head )
{
fillrectangle (newleft , newtop , newright , newbottom );
int x =(p ->left +p ->right )/2;
int y =(p ->top +p ->bottom )/2;
}
p =p ->next ;
}
}
void createfood()
{
snake *p ;
srand ((unsigned)time (NULL ));
food =(snake *)malloc (sizeof(snake ));
int row =rand ()%ROWS ;
int col =rand ()%COLS ;
if(row ==0)
row =1;
if(row ==(ROWS -1))
row =ROWS -2;
if(col ==0)
col =1;
if(col ==(COLS -1))
col =COLS -2;
food ->left =col *20;
food ->right =food ->left +20;
food ->top =row *20+80;
food ->bottom =food ->top +20;
p =head ;
bool ISSame =false;
while(p !=NULL )
{
if(p ->left ==food ->left &&p ->top ==food ->top &&p ->right ==food ->right &&p ->bo ttom ==food ->bottom )
{ ISSame =true;
free (food );
createfood();
}
p =p ->next ;
}
if(!ISSame ){
IMAGE imgfood ;
loadimage (&imgfood ,"res\\apple.jpg");
putimage (food ->left +1,food ->top +1,&imgfood );
}
void eatefood()
{
snake *p ;
p =head ;
bool IsEated =false;
//右
if(head ->left +20==food ->left &&head ->right +20==food ->right &&head ->top ==f ood ->top &&head ->bottom ==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//左
if(head ->left -20==food ->left &&head ->right -20==food ->right &&head ->top ==fo od ->top &&head ->bottom ==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//下
if(head ->left ==food ->left &&head ->right ==food ->right &&head ->top +20==food ->top &&head ->bottom +20==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
IsExistFood =false;
}
//上
if(head ->left ==food ->left &&head ->right ==food ->right &&head ->top -20==food ->top &&head ->bottom -20==food ->bottom )
{
food ->next =head ;
head =food ;
IsEated =true;
if(IsEated )
{
score ++;
fillrectangle (p ->left ,p ->top , p ->right , p ->bottom );
fillrectangle (p ->left ,p ->top , p ->right , p ->bottom );
int x =(head ->left +head ->right )/2;
int y =(head ->top +head ->bottom )/2;
setfillcolor (YELLOW );
fillcircle (x , y ,2);
}
}
int biteself()
{
snake *p ;
p =head ->next ;
while(p !=NULL )
{
if(p ->left ==head ->left &&p ->top ==head ->top &&p ->right ==head ->right &&p ->b ottom ==head ->bottom )
{
endgamestatus =2;
return 1;
}
p =p ->next ;
}
return 0;
}
int cantcrosswall()
{
if(head ->left right >580|head ->top bottom >560)
{
endgamestatus =1;
return 1;
}
return 0;
}
void pause()
{
while(1)
{
Sleep (300);
if(GetAsyncKeyState (VK_SPACE) )
{
break;
}
}
}
void endgame()
{
RECT r ={0,100,600,200};
RECT r2={0,200,600,300};
if(endgamestatus ==1)
{
drawtext (_T("对不起,您撞到墙了。按空格游戏结束。"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
else if(endgamestatus ==2)
{
drawtext (_T("对不起,您咬到自己了。按空格游戏结束。
"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
else if(endgamestatus ==3)
{
drawtext (_T("您已经结束了游戏。按空格游戏结束。"),&r , DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
char s []="你的得分";
char GetScore [10];
itoa (score , GetScore ,10);
outtextxy (10,20,s );
outtextxy (80,20,GetScore );
pause();
exit (0);
}
void GameControl()
{
while(1)
{
if(GetAsyncKeyState (VK_UP) )
{
direction =UP ;
}
else if(GetAsyncKeyState (VK_DOWN) ) {
direction =DOWN ;
}
else if(GetAsyncKeyState (VK_LEFT) ) {
direction =LEFT ;
}
else if(GetAsyncKeyState (VK_RIGHT) ) {
direction =RIGHT ;
}
else if(GetAsyncKeyState (VK_ESCAPE) ) {
break;
}
movesnake();
if(!IsExistFood )
createfood();
eatefood();
if(biteself()==1||cantcrosswall()==1)
{
endgame();
}
}
}
void main(int argc ,char * argv [])
{
initgraph (800,600);
InitMap();
playmusic();
initsnake();
GameControl();
getch ();
closegraph ();
}