创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*《计算机程序设计》课程设计报告课题名称贪吃蛇游戏班级学号姓名指导教师设计时间至设计地点常熟理工学院计算机科学与工程学院常熟理工学院计算机科学与工程学院目录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)《C程序设计》课程设计1 需求分析【阐述课程设计应该完成的功能】使用键盘的上下左右,来控制蛇的运动方向,ESC键退出,并显示得分。
2 系统分析和设计2.1 数据结构的设计和选择的理由本游戏中涉及的主要数据结构是如何表示运动的蛇、食物状态等问题。
2.1.1从游戏参考画面中我们可以看到,贪吃蛇的身体是一节节的,由一个个大小相同的方块组成,那么我们可以用一个(x,y)坐标为左上角的、固定宽度的正方形来表示一节蛇身。
为表示连续的多节身体,那么我们可以采用数组(或链表,或线性表)等数据结构来表示。
下面以数组方式为例:struct Point {int x, y;}struct Point nodes[MAX_LENGTH]; //蛇身数组,MAX_LENGTH为最大蛇长贪吃蛇是在不断的运动的,我们研究蛇的运动可以发现这样的特点:1. 蛇头由键盘控制,键盘不操作时,保持原有方向运动;(用int direction;表示)2. 运动时,蛇身后面一节移动到前面一节的位置。
当我们用nodes[0]表示蛇头的时候,nodes[1]运动到nodes[0]处;nodes[2]运动到nodes[1]处...。
3. 吃到一个食物以后,蛇身会增加一节。
即该数组中的有效数据个数加一。
(用int length;表示)根据上面的情况,我们可以设计蛇的数据结构如下:struct Snake {struct Point nodes[MAX_LENGTH]; //蛇身数组,保存每节蛇身的坐标。
MAX_LENGTH为最大蛇长int length; //当前蛇长int direction; //蛇头运动方向int live; //蛇活的,还是已经死了?}2.1.2 关于食物,有两个属性:1. 坐标位置2. 状态:存在,或被吃。
故我们用以下结构表示:struct Food {struct Point position; //食物的位置int exist; //存在?还是被吃?}1常熟理工学院计算机科学与工程学院2.2 系统模块划分和模块结构void main() {init(); /*初始化*/l=1;while(l) /*循环游戏*/{select(); /*游戏速度和结束的选择菜单*/gamePlay(); /*游戏主程序*/}close(); /*关闭游戏*/}2.3 流程图《C程序设计》课程设计2.4 数据类型、全局变量和函数说明2.4.1数据类型struct Point { /*一个存放点坐标的结构体*/int x, y; /*被多个结构体调用的基本参数,所以统一用point结构体来表示*/};struct Snake { /*用来模拟蛇状态的结构体*/struct Point nodes[MAX_LENGTH]; /*用来存放蛇每一节的位置*/int length; /*蛇长*/int direction; /*蛇移动的方向*/int live; /*蛇是否活着*/} snake;/*比较形象的把蛇抽象为一个数据类型*/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 createFood(void); \\创造一个食物void drawFood(void); \\画出食物void drawSnake(void); \\画出蛇void drawScore(void); \\画出分数int touchWall(void); \\判断是否碰到墙int touchSelf(void); \\判断是否碰到自己void gameOver(void); \\游戏结束3常熟理工学院计算机科学与工程学院void moveSnake(void); \\移动蛇int oppositeDirection(int keyCode); \\判断是否方向有误int foodEat(void); \\判断是否吃到食物void expandSnake(void); \\把蛇增长一节3 程序测试和运行结果----------------------------------------------------------------------------选择速度开始或退出《C程序设计》课程设计----------------------------------------------------------------------------------------游戏运行中--------------------------------------------------------------------------------------------------------游戏结束5常熟理工学院计算机科学与工程学院4 课程报告小结【遇到的问题及解决方法分析等】4.1分数重叠显示解决方法:每次都用一块黑的矩形覆盖setfillstyle(1,16);bar(45,45,150,80);4.2速度太快解决方法:循环delayfor(d=0;d<4;d++)delay(GAME_SPEED);4.3食物可能出现在蛇身上解决方法:依次判断,若重叠则重新生成食物void createFood() {int i;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)goto label;}附录A:程序源代码/*writer: neolone(LB)*/#include <graphics.h>#include <stdlib.h>#include <time.h>#include <stdio.h>#include <dos.h>#include <conio.h>#include <bios.h>#define TRUE 1#define FALSE 0#define UP 0x4800#define DOWN 0x5000#define LEFT 0x4B00#define RIGHT 0x4D00#define ESC 0x011B#define SPEED1 0x0231#define SPEED2 0x0332#define SPEED3 0x0433《C程序设计》课程设计#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 Snake {struct Point nodes[MAX_LENGTH];int length;int direction;int live;} snake;struct Food {struct Point position;int exist;} food;intscore=0,max,max1,max2,max3,left=200,top=200,right=300,bottom=300,lastx,lasty,keyCod e,keyCode2,sp,l,sel,times=1;char text[80];/* functions declaration */void init(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);7常熟理工学院计算机科学与工程学院int oppositeDirection(int keyCode);int foodEat(void);void expandSnake(void);void select(void);/*------------------------*/void main() {init();l=1;while(l){select();gamePlay();}close();}void init() {int gdriver=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();/*sui ji shu fa sheng qi*/drawWall();}void close() {FILE *fp;closegraph();if((fp=fopen("data.txt","w"))==NULL) /*关闭时保存最高分*/{exit(0);}else{fprintf(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 (touchWall() || touchSelf()) {gameOver();return;}if (!food.exist) createFood();food.exist=1;drawFood();drawSnake();for(d=0;d<sp;d++)delay(GAME_SPEED);if (bioskey(1) != 0) {keyCode = bioskey(0);switch(keyCode) {case ESC:gameOver();return;default:lastx=snake.nodes[snake.length-1].x;lasty=snake.nodes[snake.length-1].y;if (!oppositeDirection(keyCode)) {snake.direction = keyCode;}}}9moveSnake();if (foodEat()) {food.exist = FALSE;score += 10;expandSnake();}}}void drawWall() {rectangle(left,top,right+10,bottom+10);}void createFood() {int i;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)goto label;}}void drawFood() {setfillstyle(1,2);bar(food.position.x,food.position.y,food.position.x+10,food.position.y+10);}void drawSnake() {int j;setfillstyle(1,4);for(j=0;j<=snake.length-1;j++){bar(snake.nodes[j].x,snake.nodes[j].y,snake.nodes[j].x+10,snake.nodes[j].y+10);}void drawScore(void) {setfillstyle(1,16);bar(45,45,150,80);setcolor(WHITE);sprintf(text,"writer:neolone");outtextxy(170,50,text);sprintf(text,"score:%5d",score);outtextxy(50,50,text);}int touchWall() {int x1=snake.nodes[0].x;int y1=snake.nodes[0].y;if(x1<left||x1>right||y1<top||y1>bottom)return TRUE;elsereturn FALSE;}int touchSelf() {int i;for (i=3;i<snake.length-1;i++){if(snake.nodes[0].x==snake.nodes[i].x&&snake.nodes[0].y==snake.nodes[i].y) return TRUE;}return FALSE;}void gameOver() {FILE *fp;int x2,y2;x2=180;y2=250;11setcolor(WHITE);sprintf(text,"Game over !!your score is %d,%d",score,sel);outtextxy(x2,y2,text);delay(1000);getch();switch(sel%4){case 1:if(score>max1){max1=score;}break;case 2:if(score>max2){max2=score;}break;case 3:if(score>max3){max3=score;}break;default :{break;}}}void moveSnake() {int k;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+10);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;else if(snake.direction==DOWN)snake.nodes[0].y+=10;else if(snake.direction==LEFT)snake.nodes[0].x-=10;else if(snake.direction==RIGHT)snake.nodes[0].x+=10;else;}int oppositeDirection(int keyCode) {if(keyCode==UP&&snake.direction==DOWN){return 1;}else if(keyCode==DOWN&&snake.direction==UP) {return 1;}else if(keyCode==LEFT&&snake.direction==RIGHT){return 1;}else if(keyCode==RIGHT&&snake.direction==LEFT){return 1;}elsereturn 0;}int foodEat() {if(snake.nodes[0].x==food.position.x&&snake.nodes[0].y==food.position.y) return 1;elsereturn 0;}void expandSnake() {if(keyCode==UP){lastx-=10;}else if(keyCode==DOWN) {lastx+=10;13}else if(keyCode==LEFT){lasty-=10;}else if(keyCode==RIGHT){lasty+=10;}else;snake.nodes[snake.length].x=lastx;snake.nodes[snake.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(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++;break;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);bar(430,270,480,280);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(430,270,480,280);sprintf(text,"speed3");outtextxy(430,270,text);bar(430,290,480,300);15sprintf(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,"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(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.txt","r"))==NULL){sprintf(text,"Can not open the file");exit(0);}else{fscanf(fp,"%d,%d,%d",&max1,&max2,&max3);}fclose(fp);times=0;}switch(sel%4) { /*选择速度*/case 0:l=0;gameOver();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);17outtextxy(50,90,text);break;default :break;}}创作编号:GB8878185555334563BT9125XW创作者:凤呜大王*。