完整word版贪吃蛇实验报告.docx
- 文档编号:26193720
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:24
- 大小:52.49KB
完整word版贪吃蛇实验报告.docx
《完整word版贪吃蛇实验报告.docx》由会员分享,可在线阅读,更多相关《完整word版贪吃蛇实验报告.docx(24页珍藏版)》请在冰豆网上搜索。
完整word版贪吃蛇实验报告
《计算机程序设计》课程设计报告
课题名称贪吃蛇游戏
班级
学号
姓名
指导教师
设计时间至
设计地点
常熟理工学院计算机科学与工程学院
1需求分析1
2系统分析和设计1
2.1数据结构的设计和选择的理由1
2.2系统模块划分和模块结构2
2.3流程图2
2.4数据类型、全局变量和函数说明3
3程序测试和运行结果4
4课程报告小结5
4.1分数重叠显示5
4.2速度太快5
4.3食物可能出现在蛇身上5
附录A:
程序源代码6
1需求分析
【阐述课程设计应该完成的功能】
使用键盘的上下左右,来控制蛇的运动方向,ESC键退出,并显示得分。
2系统分析和设计
2.1数据结构的设计和选择的理由
本游戏中涉及的主要数据结构是如何表示运动的蛇、食物状态等问题。
2.1.1从游戏参考画面中我们可以看到,贪吃蛇的身体是一节节的,由一个个大小相同的方
块组成,那么我们可以用一个(x,y)坐标为左上角的、固定宽度的正方形来表示一节蛇身。
为
表示连续的多节身体,那么我们可以采用数组(或链表,或线性表)等数据结构来表示。
下面以数组方式为例:
structPoint{
intx,y;
}
structPointnodes[MAX_LENGTH];//蛇身数组,MAX_LENGTH为最大蛇长
贪吃蛇是在不断的运动的,我们研究蛇的运动可以发现这样的特点:
1.蛇头由键盘控制,键盘不操作时,保持原有方向运动;(用intdirection;表示)
2.运动时,蛇身后面一节移动到前面一节的位置。
当我们用nodes[0]表示蛇头的时候,nodes[1]
运动到nodes[0]处;nodes[2]运动到nodes[1]处…。
3•吃到一个食物以后,蛇身会增加一节。
即该数组中的有效数据个数加一。
(用intlength;
表示)
根据上面的情况,我们可以设计蛇的数据结构如下:
structSnake{
structPointnodes[MAX_LENGTH];//蛇身数组,保存每节蛇身的坐标。
MAX_LENGTH
为最大蛇长
intlength;//当前蛇长
intdirection;//蛇头运动方向
intlive;//蛇活的,还是已经死了?
}
2.1.2关于食物,有两个属性:
1.坐标位置
2.状态:
存在,或被吃。
故我们用以下结构表示:
structFood{
structPointposition;//食物的位置
intexist;//存在?
还是被吃?
}
2.2系统模块划分和模块结构
/*初始化*/
/*循环游戏*/
/*游戏速度和结束的选择菜单
/*游戏主程序*/
/*关闭游戏*/
}
241数据类型
structPoint{
intx,y;
};
2.4数据类型、全局变量和函数说明
/*一个存放点坐标的结构体*/
/*被多个结构体调用的基本参数,所以统一用point结构体来表示*/
structSnake{
structPointnodes[MAX_LENGTH];
intlength;
intdirection;
intlive;
}snake;
structFood{
structPointposition;
intexist;
}food;
2.4.2全局变量
Score
left,top,right,bottom
lastx,lasty
keyCode
243函数说明
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);
voidexpandSnake(void);
/*用来模拟蛇状态的结构体*/
/*用来存放蛇每一节的位置*/
/*蛇长*/
/*蛇移动的方向*/
/*蛇是否活着*/
/*比较形象的把蛇抽象为一个数据类型*/
/*用来模拟食物状态的结构体*/
/*食物的位置*/
/*食物是否存在*/
得分
游戏区域范围
用来保存最后一节蛇的位置
用来保存按下的键
初始化程序,给一些初始值赋值
游戏主循环
关闭游戏
画墙
创造一个食物
画出食物
画出蛇
画出分数
判断是否碰到墙
判断是否碰到自己
游戏结束
移动蛇
判断是否方向有误
判断是否吃到食物
把蛇增长一节
3程序测试和运行结果
:
和DQSBqe0.724CpuCycles:
3DQ0»Fmesfcip04Pro*raB:
选择速度开始或退出
游戏运行中
游戏结束
4课程报告小结
【遇到的问题及解决方法分析等】
4.1分数重叠显示
解决方法:
每次都用一块黑的矩形覆盖
setfillstyle(1,16);
bar(45,45,150,80);
4.2速度太快
解决方法:
循环delay
for(d=0;d<4;d++)delay(GAME_SPEED);
4.3食物可能出现在蛇身上
解决方法:
依次判断,若重叠则重新生成食物
voidcreateFood(){
inti;
label:
food.position.x=left+10*((int)rand()%11);
food.position.y=top+10*((int)rand()%11);
for(i=0;i<=snake」ength-1;i++){
if(snake.nodes[i].x==food.position.x&&snake.nodes[i].y==food.position.y)
gotolabel;
}
附录A:
程序源代码
/*writer:
neolone(LB)*/
#inelude
#include
#include
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineUP0x4800
#defineDOWN0x5000
#defineLEFT0x4B00
#defineRIGHT0x4D00
#defineESC0x011B
#defineSPEED10x0231
#defineSPEED20x0332
#defineSPEED30x0433
#defineQUIT0x0B30
#defineENTER0x1C0D
#defineMAX_LENGTH100/*maxlengthofsnakenodess*/
#defineGAME_SPEED100/*gamespeed*/
/*datastructure*/
structPoint{
intx,y;
};
structSnake{
structPointnodes[MAX_LENGTH];intlength;
intdirection;
intlive;
}snake;
structFood{
structPointposition;
intexist;
}food;
int
score=0,max,max1,max2,max3,left=200,top=200,right=300,bottom=300,lastx,lasty,keyCode,keyCode2,sp,l,sel,times=1;
chartext[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);
voidexpandSnake(void);
voidselect(void);
/**/
voidmain(){
init();
l=1;
while(l)
{
select();
gamePlay();
}
close();
}
voidinit(){
intgdriver=VGA,gmode=VGAHI;
snake.nodes[0].x=250;
snake.nodes[0].y=250;
snake.nodes[1].x=250;
snake.nodes[1].y=260;
snake.length=2;
snake.live=1;
snake.direction=UP;
score=0;
food.exist=0;
initgraph(&gdriver,&gmode,"C:
\\tc20\\BGI");
randomize();/*suijishufashengqi*/
drawWall();
}
voidclose(){
FILE*fp;
/*关闭时保存最咼分*/
closegraph();
if((fp=fopen("data.txt","w"))==NULL)
{
exit(0);
}
else
{
fprintf(fp,"%d,%d,%d",max1,max2,max3);fclose(fp);
}
printf("pessanykeytocontinue");
}
voidgamePlay(){
intkeyCode,d;
getch();
while(TRUE){
drawScore();
drawWall();
if(touchWall()||touchSelf()){
gameOver();
return;
}
if(!
food.exist)createFood();
food.exist=1;
drawFood();
drawSnake();
for(d=0;d delay(GAME_SPEED); if(bioskey (1)! =0){ keyCode=bioskey(0);switch(keyCode){caseESC: gameOver();return; default: lastx=snake.nodes[snake」ength-1].x;lasty=snake.nodes[snake」ength-1].y; if(! oppositeDirection(keyCode)){ snake.direction=keyCode; } } } moveSnake(); if(foodEat()){ food.exist=FALSE; score+=10; expandSnake(); } } } voiddrawWall(){ rectangle(left,top,right+10,bottom+10); } voidcreateFood(){ inti; label: food.position.x=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].x==food.position.x&&snake.nodes[i].y==food.position.y) gotolabel; } } voiddrawFood(){ setfillstyle(1,2); bar(food.position.x,food.position.y,food.position.x+10,food.position.y+10); } voiddrawSnake(){ intj; setfillstyle(1,4); for(j=0;j<=snake」ength-1;j++) { bar(snake.nodes[j].x,snake.nodes[j].y,snake.nodes[j].x+10,snake.nodes[j].y+10); } } voiddrawScore(void){ setfillstyle(1,16);bar(45,45,150,80); setcolor(WHITE); sprintf(text,"writer: neoIone");outtextxy(170,50,text); sprintf(text,"score: %5d",score);outtextxy(50,50,text); } inttouchWall(){ intx1=snake.nodes[0].x; inty1=snake.nodes[0].y; if(x1 else returnFALSE; } inttouchSelf(){ inti; for(i=3;i { if(snake.nodes[0].x==snake.nodes[i].x&&snake.nodes[0].y==snake.nodes[i].y)returnTRUE; } returnFALSE; } voidgameOver(){ FILE*fp; intx2,y2; x2=180; y2=250; setcolor(WHITE); sprintf(text,"Gameover! ! yourscoreis%d,%d",score,sel);outtextxy(x2,y2,text); delay(1000); getch(); switch(sel%4) { case1: if(score>max1) { max1=score; } break; case2: if(score>max2) { max2=score; } break; case3: if(score>max3) { max3=score; } break; default: { break; } } } voidmoveSnake(){ intk; setfillstyle(1,16); lastx=snake.nodes[snake.length-1].x; lasty=snake.nodes[snake.length-1].y; bar(snake.nodes[snake.length-1].x,snake.nodes[snake.length-1].y,snake.nodes[snake.length-1].x+10,snake.nodes[snake.length-1].y+1O); for(k=snake.length-2;k>=0;k--) { snake.nodes[k+1].x=snake.nodes[k].x; 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].x-=10; elseif(snake.direction==RIGHT) snake.nodes[0].x+=10; else 5 } 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].x==food.position.x&&snake.nodes[0].y==food.position.y)return1; else return0; } voidexpandSnake(){ if(keyCode==UP){ lastx-=10; } elseif(keyCode==DOWN){ lastx+=10; } elseif(keyCode==LEFT){ lasty-=10; } elseif(keyCode==RIGHT){ lasty+=10; } else 5 snake.nodes[snake」ength].x=lastx; 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(text,"speed1");outtextxy(430,230,text);bar(430,250,480,260); sprintf(text,"speed2");outtextxy(430,250,text);bar(430,270,480,280); sprintf(text,"speed3");outtextxy(430,270,text);bar(430,290,480,300); sprintf(text,"quit"); outtextxy(430,290,text); 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(text,"speed1"); outtextxy(430,230,text);bar(430,250,480,260); sprintf(text,"speed2"); outtextxy(430,250,text); bar(430,270,480,280); sprintf(text,"speed3"); outtextxy(430,270,text); sprintf(text,"quit"); outtextxy(430,290,text); break; case1: setfillstyle(1,9);bar(430,230,480,240); setfillstyle(1,5);setcolor(WHITE); sprintf(text,"speed1");outtextxy(430,230,text);bar(430,250,480,260); sprintf(text,"speed2");outtextxy(430,250,text); bar(430,270,480,280); sprintf(text,"speed3");outtextxy(430,270,text); bar(430,290,480,300);sprintf(text,"quit"); outtextxy(430,290,text);break; case2: setfillstyle(1,9); bar(430,250,480,260);setfillstyle(1,5); bar(430,230,480,240);setcolor(WHITE); sprintf(text,"speed1");outtextxy(430,230,text); sprintf(text,"speed2");outtextxy(430,250,text); bar(430,270,480
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word 贪吃 实验 报告