1、计算机程序设计课程设计报告课 题 名 称 贪吃蛇游戏 班 级 学 号 姓 名 指 导 教 师 设 计 时 间 至 设 计 地 点 常熟理工学院计算机科学与工程学院常熟理工学院计算机科学与工程学院目录1 需求分 析 .12 系统分析和设计 .12.1 数据结构的设计和选择的理由 12.2 系统模块划分和模块结构 22.3 流程图 32.4 数据类型、全局变量和函数说明 33 程序测试和运行结果 .44 课程报告小结 .54.1 分数重叠显示 .54.2 速度太快 .54.3 食物可能出现在蛇身上 .5附录 A:程序源代码 .6C 程序设计课程设计11 需求分析【阐述课程设计应该完成的功能】使用键
2、盘的上下左右,来控制蛇的运动方向,ESC 键退出,并显示得分。2 系统分析和设计2.1 数据结构的设计和选择的理由本游戏中涉及的主要数据结构是如何表示运动的蛇、食物状态等问题。2.1.1 从游戏参考画面中我们可以看到,贪吃蛇的身体是一节节的,由一个个大小相同的方块组成,那么我们可以用一个(x,y)坐标为左上角的、固定宽度的正方形来表示一节蛇身。为表示连续的多节身体,那么我们可以采用数组(或链表,或线性表)等数据结构来表示。下面以数组方式为例:struct Point int x, y;struct Point nodesMAX_LENGTH; /蛇身数组,MAX_LENGTH 为最大蛇长贪吃蛇
3、是在不断的运动的,我们研究蛇的运动可以发现这样的特点:1. 蛇头由键盘控制,键盘不操作时,保持原有方向运动;(用 int direction;表示) 2. 运动时,蛇身后面一节移动到前面一节的位置。当我们用 nodes0表示蛇头的时候,nodes1运动到 nodes0处; nodes2运动到 nodes1处.。3. 吃到一个食物以后,蛇身会增加一节。即该数组中的有效数据个数加一。(用 int length;表示)根据上面的情况,我们可以设计蛇的数据结构如下:struct Snake struct Point nodesMAX_LENGTH; /蛇身数组,保存每节蛇身的坐标。 MAX_LENGT
4、H为最大蛇长int length; /当前蛇长int direction; /蛇头运动方向int live; /蛇活的,还是已经死了?2.1.2 关于食物,有两个属性:1. 坐标位置2. 状态:存在,或被吃。故我们用以下结构表示:struct Food struct Point position; /食物的位置int exist; /存在?还是被吃?常熟理工学院计算机科学与工程学院2.2 系统模块划分和模块结构void main() init(); /*初始化*/l=1; while(l) /*循环游戏*/select(); /*游戏速度和结束的选择菜单*/gamePlay(); /*游戏主程
5、序*/close(); /*关闭游戏*/2.3 流程图C 程序设计课程设计32.4 数据类型、全局变量和函数说明2.4.1 数据类型struct Point /*一个存放点坐标的结构体*/int x, y; /*被多个结构体调用的基本参数,所以统一用 point 结构体来表示*/;struct Snake /*用来模拟蛇状态的结构体*/struct Point nodesMAX_LENGTH; /*用来存放蛇每一节的位置*/ int length; /*蛇长*/int direction; /*蛇移动的方向*/int live; /*蛇是否活着*/ snake;/*比较形象的把蛇抽象为一个数据
6、类型*/struct Food /*用来模拟食物状态的结构体*/struct Point position; /*食物的位置*/int exist; /*食物是否存在*/ food;2.4.2 全局变量Score 得分left,top,right,bottom 游戏区域范围lastx,lasty 用来保存最后一节蛇的位置keyCode 用来保存按下的键2.4.3 函数说明void init(void); 初始化程序,给一些初始值赋值void gamePlay(void); 游戏主循环void close(void); 关闭游戏void drawWall(void); 画墙void create
7、Food(void); 创造一个食物void drawFood(void); 画出食物void drawSnake(void); 画出蛇void drawScore(void); 画出分数int touchWall(void); 判断是否碰到墙int touchSelf(void); 判断是否碰到自己void gameOver(void); 游戏结束void moveSnake(void); 移动蛇int oppositeDirection(int keyCode); 判断是否方向有误int foodEat(void); 判断是否吃到食物void expandSnake(void); 把蛇增长
8、一节常熟理工学院计算机科学与工程学院3 程序测试和运行结果 -选择速度开始或退出-游戏运行中C 程序设计课程设计5-游戏结束4 课程报告小结【遇到的问题及解决方法分析等】4.1 分数重叠显示解决方法:每次都用一块黑的矩形覆盖setfillstyle(1,16);bar(45,45,150,80);4.2 速度太快解决方法:循环 delayfor(d=0;d#include #include #include #include #include #include #define TRUE 1#define FALSE 0#define UP 0x4800#define DOWN 0x5000#d
9、efine LEFT 0x4B00#define RIGHT 0x4D00#define ESC 0x011B#define SPEED1 0x0231#define SPEED2 0x0332#define SPEED3 0x0433#define QUIT 0x0B30#define ENTER 0x1C0D#define MAX_LENGTH 100 /* max length of snake nodess */#define GAME_SPEED 100 /* game speed */* data structure */struct Point int x, y;struct S
10、nake struct Point nodesMAX_LENGTH;int length;int direction;int live; snake;struct Food struct Point position;C 程序设计课程设计7int exist; 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;char text80;/* functions declaration */void init(
11、void);void gamePlay(void);void close(void);void drawWall(void);void createFood(void);void drawFood(void);void drawSnake(void);void drawScore(void);int touchWall(void);int touchSelf(void);void gameOver(void);void moveSnake(void);int oppositeDirection(int keyCode);int foodEat(void);void expandSnake(vo
12、id);void select(void);/*-*/void main() init();l=1;while(l)select();gamePlay();close();void init() int gdriver=VGA ,gmode=VGAHI ;常熟理工学院计算机科学与工程学院snake.nodes0.x=250;snake.nodes0.y=250;snake.nodes1.x=250;snake.nodes1.y=260;snake.length=2;snake.live=1;snake.direction=UP;score=0;food.exist=0;initgraph (r
13、andomize();/*sui ji shu fa sheng qi*/drawWall();void close() FILE *fp;closegraph();if(fp=fopen(“data.txt“,“w“)=NULL) /*关闭时保存最高分*/exit(0);elsefprintf(fp,“%d,%d,%d“,max1,max2,max3);fclose(fp);printf(“pess any key to continue“);void gamePlay() int keyCode,d;getch();while(TRUE) drawScore();drawWall();if
14、 (touchWall() | touchSelf() C 程序设计课程设计9gameOver();return;if (!food.exist) createFood();food.exist=1;drawFood();drawSnake();for(d=0;dright|y1bottom)return TRUE;C 程序设计课程设计11elsereturn FALSE;int touchSelf() int i;for (i=3;imax1)max1=score;break;case 2:if(scoremax2)max2=score;break;case 3:常熟理工学院计算机科学与工程
15、学院if(scoremax3)max3=score;break;default :break;void moveSnake() int k;setfillstyle(1,16);lastx=snake.nodessnake.length-1.x;lasty=snake.nodessnake.length-1.y;bar(snake.nodessnake.length-1.x,snake.nodessnake.length-1.y,snake.nodessnake.length-1.x+10,snake.nodessnake.length-1.y+10);for(k=snake.length-2
16、;k=0;k-)snake.nodesk+1.x=snake.nodesk.x;snake.nodesk+1.y=snake.nodesk.y;if(snake.direction=UP)snake.nodes0.y-=10;else if(snake.direction=DOWN)snake.nodes0.y+=10;else if(snake.direction=LEFT)snake.nodes0.x-=10;else if(snake.direction=RIGHT)snake.nodes0.x+=10;else;int oppositeDirection(int keyCode) if
17、(keyCode=UPelse if(keyCode=DOWNelse if(keyCode=LEFTelse if(keyCode=RIGHTelsereturn 0;int foodEat() if(snake.nodes0.x=food.position.xelsereturn 0;void expandSnake() if(keyCode=UP)lastx-=10;else if(keyCode=DOWN) lastx+=10;else if(keyCode=LEFT)lasty-=10;else if(keyCode=RIGHT)lasty+=10;else;snake.nodess
18、nake.length.x=lastx;snake.nodessnake.length.y=lasty;snake.length+;void select()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
19、(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) case UP:sel-;break;case DOWN:sel+;brea
20、k;case ENTER:t=0;break;default :break;switch(sel%4) case 0: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);C 程序设计课程设计15bar(430,270,480,280)
21、;sprintf(text,“speed3“);outtextxy(430,270,text);sprintf(text,“ quit “);outtextxy(430,290,text);break;case 1: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(
22、430,270,480,280);sprintf(text,“speed3“);outtextxy(430,270,text);bar(430,290,480,300);sprintf(text,“ quit “);outtextxy(430,290,text);break;case 2: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,“
23、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;常熟理工学院计算机科学与工程学院case 3:setfillstyle(1,9);bar(430,270,480,280);setfillstyle(1,5);bar(430,230,480,240);setcolor(WHITE);sprintf(
24、text,“speed1“);outtextxy(430,230,text);bar(430,250,480,260);sprintf(text,“speed2“);outtextxy(430,250,text);sprintf(text,“speed3“);outtextxy(430,270,text);bar(430,290,480,300);sprintf(text,“ quit “);outtextxy(430,290,text);break;default :break;/*ch=getch();*/if(times=1) /*读取历史最高分 */if(fp=fopen(“data.
25、txt“,“r“)=NULL)sprintf(text,“Can not open the file“);exit(0);elsefscanf(fp,“%d,%d,%d“,fclose(fp);times=0;switch(sel%4) /*选择速度*/case 0:l=0;C 程序设计课程设计17gameOver();close();break;case 1:sp=5;init();sprintf(text,“Hightest score:%d“,max1);outtextxy(50,90,text);break;case 2:sp=3;init();sprintf(text,“Hightest score:%d“,max2);outtextxy(50,90,text);break;case 3:sp=1;init();sprintf(text,“Hightest score:%d“,max3);outtextxy(50,90,text);break;default :break;