贪吃蛇实验报告.docx
- 文档编号:12341806
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:26
- 大小:18.52KB
贪吃蛇实验报告.docx
《贪吃蛇实验报告.docx》由会员分享,可在线阅读,更多相关《贪吃蛇实验报告.docx(26页珍藏版)》请在冰豆网上搜索。
贪吃蛇实验报告
贪吃蛇实验报告
《计算机程序设计》课程设计报告
课题名称
贪吃蛇游戏
班
级
学
号
姓
名
指导教师
设计时间
至
设计地点
常熟理工学院计算机科学与工程学院
1需求分析............................................
1
2系统分析和设计......................................
1
2.1数据结构的设计和选择的理由.....................
1
2.2系统模块划分和模块结构.........................
3
2.3流程图.........................................
4
2.4数据类型、全局变量和函数说明...................
4
3程序测试和运行结果..................................
4
4课程报告小结........................................
5
4.1分数重叠显示...................................
5
4.2速度太快.......................................
5
4.3食物可能出现在蛇身上...........................
5
附录A:
程序源代码....................................
6
1需求分析
【阐述课程设计应该完成的功能】
使用键盘的上下左右,来控制蛇的运动方向,ESC键退出,并显示得分。
2系统分析和设计
2.1数据结构的设计和选择的理由
本游戏中涉及的主要数据结构是如何表示运动的蛇、食物状态等问题。
2.11.1从游戏参考画面中我们可以看到,贪吃蛇的身体是一节节的,由一个个大小相同的方块组成,那么我们可以用一个(_,y)坐标为左上角的、固定宽度的正方形来表示一节蛇身。
为表示连续的多节身体,那么我们可以采用数组(或链表,或线性表)等数据结构来表示。
下面以数组方式为例:
structPoint{
int_,y;}
structPointnodes[MA__LENGTH];
//蛇身数组,MA__LENGTH为最大蛇长
贪吃蛇是在不断的运动的,我们研究蛇的运动可以发现这样的特点:
1.
蛇头由键盘控制,键盘不操作时,保持原有方向运动;(用intdirection;表示)
2.
运动时,蛇身后面一节移动到前面一节的位置。
当我们用nodes[0]表示蛇头的时候,nodes[1]运动到nodes[0]处;nodes[2]运动到nodes[1]处...。
3.
吃到一个食物以后,蛇身会增加一节。
即该数组中的有效数据个数加一。
(用intlength;表示)
根据上面的情况,我们可以设计蛇的数据结构如下:
structSnake{
structPointnodes[MA__LENGTH];
//蛇身数组,保存每节蛇身的坐标。
MA__LENGTH为最大蛇长
intlength;
//当前蛇长
intdirection;//蛇头运动方向
intlive;
//蛇活的,还是已经死了?
}
2.11.2关于食物,有两个属性:
1.
坐标位置2.
状态:
存在,或被吃。
故我们用以下结构表示:
structFood{
structPointposition;
//食物的位置
inte_ist;
//存在?
还是被吃?
}
2.2系统模块划分和模块结构
voidmain{
init;
/_初始化_/
l=1;
while(l)
/_循环游戏_/
{
select;
/_游戏速度和结束的选择菜单_/
gamePlay;
/_游戏主程序_/
}
close;
/_关闭游戏_/
}
2.3流程图
2.4数据类型、全局变量和函数说明
2.4.1数据类型
structPoint{
/_一个存放点坐标的结构体_/
int_,y;
/_被多个结构体调用的基本参数,所以统一
用point结构体来表示_/
};
structSnake{
/_用来模拟蛇状态的结构体_/
structPointnodes[MA__LENGTH];
/_用来存放蛇每一节的位置_/
intlength;
/_蛇长_/
intdirection;
/_蛇移动的方向_/
intlive;
/_蛇是否活着_/
}snake;
/_比较形象的把蛇抽象为一个数据类型_/
structFood{
/_用来模拟食物状态的结构体_/
structPointposition;
/_食物的位置_/
inte_ist;
/_食物是否存在_/
}food;
2.4.2全局变量
Score
\\得分
left,top,right,bottom
\\游戏区域范围
last_,lasty
\\用来保存最后一节蛇的位置
keyCode
\\用来保存按下的键
2.4.3函数说明
voidinit(void);
\\初始化程序,给一些初始值赋值
voidgamePlay(void);
\\游戏主循环
voidclose(void);
\\关闭游戏
voiddrawWall(void);
\\画墙
voidcreateFood(void);
\\创造一个食物
voiddrawFood(void);
\\画出食物
voiddrawSnake(void);
\\画出蛇
voiddrawScore(void);
\\画出分数
inttouchWall(void);
\\判断
是否碰到墙
inttouchSelf(void);
\\判断是否碰到自己
voidgameOver(void);
\\游戏结束
voidmoveSnake(void);
\\移动蛇
intoppositeDirection(intkeyCode);
\\判断是否方向有误
intfoodEat(void);
\\判断是否吃到食物
voide_pandSnake(void);
\\把蛇增长一节
3程序测试和运行结果
----------------------------------------------------------------------------选择速度开始或退出
----------------------------------------------------------------------------------------游戏运行中
--------------------------------------------------------------------------------------------------------游戏结束
4课程报告小结
【遇到的问题及解决方法分析等】
14.1分数重叠显示
解决方法:
每次都用一块黑的矩形覆盖
setfillstyle(1,16);
bar(45,45,150,80);
24.2速度太快
解决方法:
循环delay
for(d=0;d<4;d++)
delay(GAME_SPEED);
34.3食物可能出现在蛇身上
解决方法:
依次判断,若重叠则重新生成食物
voidcreateFood{
inti;
label:
food.position._=left+10_((int)rand%11);
food.position.y=top+10_((int)rand%11);
for(i=0;i<=snake.length-1;i++){
if(snake.nodes[i]._==food.position._;;snake.nodes[i].y==food.position.y)
gotolabel;
}
附录A:
程序源代码
/_writer:
neolone(LB)_/
#include
#include
#include
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineUP0_4800
#defineDOWN0_5000
#defineLEFT0_4B00
#defineRIGHT0_4D00
#defineESC0_011B
#defineSPEED10_0231
#defineSPEED20_0332
#defineSPEED30_0433
#defineQUIT
0_0B30
#defineENTER0_1C0D
#defineMA__LENGTH100
/_
ma_lengthofsnakenodess_/
#defineGAME_SPEED100
/_
gamespeed_/
/_
datastructure_/
structPoint{
int_,y;
};
structSnake{
structPointnodes[MA__LENGTH];
intlength;
intdirection;
intlive;
}snake;
structFood{
structPointposition;
inte_ist;
}food;
intscore=0,ma_,ma_1,ma_2,ma_3,left=20__,top=20__,right=300,bottom=300,last_,lasty,keyCode,keyCode2,sp,l,sel,times=1;
charte_t[80];
/_
functionsdeclaration_/
voidinit(void);
voidgamePlay(void);
voidclose(void);
voiddrawWall(void);
voidcreateFood(void);
voiddrawFood(void);
voiddrawSnake(void);
voiddrawScore(void);
inttouchWall(void);
inttouchSelf(void);
voidgameOver(void);
voidmoveSnake(void);
intoppositeDirection(intkeyCode);
intfoodEat(void);
voide_pandSnake(void);
voidselect(void);
/_------------------------_/
voidmain{
init;
l=1;
while(l)
{
select;
gamePlay;
}
close;
}
voidinit{
intgdriver=VGA,gmode=VGAHI;
snake.nodes[0]._=250;
snake.nodes[0].y=250;
snake.nodes[1]._=250;
snake.nodes[1].y=260;
snake.length=2;
snake.live=1;
snake.direction=UP;
score=0;
food.e_ist=0;
initgraph(;gdriver,;gmode,“C:
\\tc20\\BGI”);
randomize;/_suijishufashengqi_/
drawWall;
}
voidclose{
FILE_fp;
closegraph;
if((fp=fopen(“data.t_t”,“w”))==NULL)
/_
关闭时保存最高分_/
{
e_it(0);
}
else
{
fprintf(fp,“%d,%d,%d”,ma_1,ma_2,ma_3);
fclose(fp);
}
printf(“pessanykeytocontinue”);
}
void
gamePlay{
intkeyCode,d;
getch;
while(TRUE){
drawScore;
drawWall;
if(touchWall||touchSelf){
gameOver;
return;
}
if(!
food.e_ist)createFood;
food.e_ist=1;
drawFood;
drawSnake;
for(d=0;d delay(GAME_SPEED); if(bioskey (1)! =0){ keyCode=bioskey(0); switch(keyCode){ caseESC: gameOver; return; default: last_=snake.nodes[snake.length-1]._; lasty=snake.nodes[snake.length-1].y; if(! oppositeDirection(keyCode)){ snake.direction=keyCode; } } } moveSnake; if(foodEat){ food.e_ist=FALSE; score+=10; e_pandSnake; } } } voiddrawWall{ rectangle(left,top,right+10,bottom+10); } voidcreateFood{ inti; label: food.position._=left+10_((int)rand%11); food.position.y=top+10_((int)rand%11); for(i=0;i<=snake.length-1;i++){ if(snake.nodes[i]._==food.position._;;snake.nodes[i].y==food.position.y) gotolabel; } } voiddrawFood{ setfillstyle(1,2); bar(food.position._,food.position.y,food.position._+10,food.position.y+10); } voiddrawSnake{ intj; setfillstyle(1,4); for(j=0;j<=snake.length-1;j++) { bar(snake.nodes[j]._,snake.nodes[j].y,snake.nodes[j]._+10,snake.nodes[j].y+10); } } voiddrawScore(void){ setfillstyle(1,16); bar(45,45,150,80); setcolor(WHITE); sprintf(te_t,“writer: neolone”); outte_t_y(170,50,te_t); sprintf(te_t,“score: %5d”,score); outte_t_y(50,50,te_t); } inttouchWall{ int_1=snake.nodes[0]._; inty1=snake.nodes[0].y; if(_1 returnTRUE; else returnFALSE; } inttouchSelf{ inti; for(i=3;i { if(snake.nodes[0]._==snake.nodes[i]._;;snake.nodes[0].y==snake.nodes[i].y) returnTRUE; } returnFALSE; } voidgameOver{ FILE_fp; int_2,y2; _2=180; y2=250; setcolor(WHITE); sprintf(te_t,“Gameover! ! yourscoreis%d,%d”,score,sel); outte_t_y(_2,y2,te_t); delay(1000); getch(); switch(sel%4) { case1: if(score>ma_1) { ma_1=score; } break; case2: if(score>ma_2) { ma_2=score; } break; case3: if(score>ma_3) { ma_3=score; } break; default: { break; } } } voidmoveSnake{ intk; setfillstyle(1,16); last_=snake.nodes[snake.length-1]._; lasty=snake.nodes[snake.length-1].y; bar(snake.nodes[snake.length-1]._,snake.nodes[snake.length-1].y,snake.nodes[snake.length-1]._+10,snake.nodes[snake.length-1].y+10); for(k=snake.length-2;k>=0;k--) { snake.nodes[k+1]._=snake.nodes[k]._; snake.nodes[k+1].y=snake.nodes[k].y; } if(snake.direction==UP) snake.nodes[0].y-=10; elseif(snake.direction==DOWN) snake.nodes[0].y+=10; elseif(snake.direction==LEFT) snake.nodes[0]._-=10; elseif(snake.direction==RIGHT) snake.nodes[0]._+=10; else ; } intoppositeDirection(intkeyCode){ if(keyCode==UP;;snake.direction==DOWN){ return1; } elseif(keyCode==DOWN;;snake.direction==UP){ return1; } elseif(keyCode==LEFT;;snake.direction==RIGHT){ return1; } elseif(keyCode==RIGHT;;snake.direction==LEFT){ return1; } else return0; } intfoodEat{ if(snake.nodes[0]._==food.position._;;snake.nodes[0].y==food.position.y) return1; else return0; } voide_pandSnake{ if(keyCode==UP){ last_-=10; } elseif(keyCode==DOWN){ last_+=10; } elseif(keyCode==LEFT){ lasty-=10; } elseif(keyCode==RIGHT){ lasty+=10; } else ; snake.nodes[snake.length]._=last_; snake.nodes[snake.length].y=lasty; snake.length++; } voidselect { setfillstyle(1,7); /_实现选择速度的可视化菜单_/ bar(420,220,490,310); setfillstyle(1,9); bar(430,230,480,240); setfillstyle(1,5); setcolor(WHITE); sprintf(te_t,“speed1”); outte_t_y(430,230,te_t); bar(430,250,480,260); sprintf(te_t,“speed2”); outte_t_y(430,250,te_t); bar(430,270,480,280); sprintf(te_t,“speed3”); outte_t_y(430,270,te_t); bar(430,290,480,300); sprintf(te_t,“quit”); outte_t_y(430,290,te_t); sel=1; t=1; while(t){ delay(10); if(bioskey (1)! =0){ keyCode=bioskey(0); switch(keyCode){ caseUP: sel--;break; caseDOWN: sel++;break; caseENTER: t=0;break; default: break; } switch(sel%4){ case0: setfillstyle(1,9); bar(430,290,480,300); setcolor(WHITE); setfillstyle(1,5); bar(430,230,480,240); sprintf(te_t,“speed1”); outte_t_y(430,230,te_t); bar(430,250,480,260); sprintf(te_t,“speed2”); outte_t_y(430,250,te_t); bar(430,270,480,280); sprintf(te_t,“speed3”); outte_t_y(430,270,te_t); sprintf(te_t,“quit”); outte_t_y(430,290,te_t); break; case1: setfillstyle(1,9); bar(430,230,480,240); setfillstyle(1,5); setcolor(WHITE); sprintf(te_t,“speed1”); outte_t_y(430,230,te_t); bar(430,250,480,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 贪吃 实验 报告