贪吃蛇游戏 C语言程序设计

来源:互联网 发布:剑网3女神脸数据 编辑:程序博客网 时间:2024/05/22 23:59

 

《计算机程序设计》课程设计报告

 

课 题 名 称     贪吃蛇游戏          

班       级       软件1班           

姓       名       neolone                


 



目录

 

1 需求分析... 1

2 系统分析和设计... 1

2.1 数据结构的设计和选择的理由... 1

2.2 系统模块划分和模块结构... 2

2.3 流程图... 3

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)坐标为左上角的、固定宽度的正方形来表示一节蛇身。为表示连续的多节身体,那么我们可以采用数组(或链表,或线性表)等数据结构来表示。下面以数组方式为例:
struct Point {
    int x, y;
}

struct Point nodes[MAX_LENGTH];  //蛇身数组,MAX_LENGTH为最大蛇长

贪吃蛇是在不断的运动的,我们研究蛇的运动可以发现这样的特点:
1. 蛇头由键盘控制,键盘不操作时,保持原有方向运动;(用 intdirection;表示)
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;             //存在?还是被吃?
}

 

2.2 系统模块划分和模块结构

void main() {

       init();                           /*初始化*/

       l=1;                            

       while(l)                          /*循环游戏*/

       {

          select();                       /*游戏速度和结束的选择菜单*/

          gamePlay();                    /*游戏主程序*/

       }

       close();                           /*关闭游戏*/

}

2.3 流程图

 

 

 

 

 

2.4 数据类型、全局变量和函数说明

2.4.1数据类型

struct Point {                                         /*一个存放点坐标的结构体*/

       intx, y;          /*被多个结构体调用的基本参数,所以统一用point结构体来表示*/

};

 

struct Snake {                                        /*用来模拟蛇状态的结构体*/

       structPoint nodes[MAX_LENGTH];                /*用来存放蛇每一节的位置*/

       intlength;                                      /*蛇长*/

       intdirection;                                    /*蛇移动的方向*/

       intlive;                                                      /*蛇是否活着*/

} snake;

                                           /*比较形象的把蛇抽象为一个数据类型*/

struct Food {                                        /*用来模拟食物状态的结构体*/

       structPoint position;                             /*食物的位置*/

       intexist;                                       /*食物是否存在*/

} 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);                                                       \\游戏结束

void moveSnake(void);                               \\移动蛇

int oppositeDirection(int keyCode);                     \\判断是否方向有误

int foodEat(void);                                                             \\判断是否吃到食物

void expandSnake(void);                              \\把蛇增长一节

 

3 程序测试和运行结果


----------------------------------------------------------------------------选择速度开始或退出


----------------------------------------------------------------------------------------游戏运行中


--------------------------------------------------------------------------------------------------------游戏结束

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食物可能出现在蛇身上

解决方法:依次判断,若重叠则重新生成食物

void createFood() {

       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;

       }

附录A:程序源代码

 

/*writer:  neolone*/#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 UP0x4800#define DOWN0x5000#define LEFT0x4B00#define RIGHT0x4D00#define ESC0x011B#define SPEED10x0231#define SPEED20x0332#define SPEED30x0433#defineQUIT  0x0B30#define ENTER 0x1C0D #defineMAX_LENGTH 100         /* max length ofsnake nodess */#defineGAME_SPEED 100      /* game speed */  /* datastructure */struct Point {                                  int x, y;}; struct Snake {                                  struct Pointnodes[MAX_LENGTH];                                  int length;                                  int direction;                                  int live;} snake; struct Food {                                  struct Pointposition;                                  int exist;} food;   intscore=0,max,max1,max2,max3,left=200,top=200,right=300,bottom=300,lastx,lasty,keyCode,keyCode2,sp,l,sel,times=1;char text[80]; /* functionsdeclaration */void init(void);voidgamePlay(void);voidclose(void);voiddrawWall(void);voidcreateFood(void);voiddrawFood(void);voiddrawSnake(void);voiddrawScore(void);inttouchWall(void);inttouchSelf(void);voidgameOver(void);void moveSnake(void);intoppositeDirection(int keyCode);intfoodEat(void);voidexpandSnake(void);voidselect(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("pessany 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){                                                 caseESC:                                                        gameOver();                                                        return;                                                 default:                                       lastx=snake.nodes[snake.length-1].x;                                       lasty=snake.nodes[snake.length-1].y;                                                        if(!oppositeDirection(keyCode)) {                                                               snake.direction= keyCode;                                                        }                                                        }                                   }                                   moveSnake();                                   if(foodEat()) {                                          food.exist= FALSE;                                          score+= 10;                                          expandSnake();                                   }                                  }} void drawWall(){    rectangle(left,top,right+10,bottom+10);} voidcreateFood() {                                  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);     }  } voiddrawScore(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;    else       return 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;                                    setcolor(WHITE);                                  sprintf(text,"Gameover !!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                                  ;} intoppositeDirection(int keyCode) {   if(keyCode==UP&&snake.direction==DOWN){      return 1;      }    elseif(keyCode==DOWN&&snake.direction==UP) {      return 1;      }    elseif(keyCode==LEFT&&snake.direction==RIGHT){      return 1;      }    elseif(keyCode==RIGHT&&snake.direction==LEFT){      return 1;      }    else      return 0;} int foodEat() {   if(snake.nodes[0].x==food.position.x&&snake.nodes[0].y==food.position.y)       return 1;    else       return 0;} voidexpandSnake() {    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.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){                                          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,280);                                                               sprintf(text,"speed3");                                                               outtextxy(430,270,text);                                                               bar(430,290,480,300);                                                               sprintf(text,"quit ");                                                               outtextxy(430,290,text);                                                               break;                                           case3:                                                               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 thefile");                                    exit(0);                                    }                                    else                                    {                                    fscanf(fp,"%d,%d,%d",&max1,&max2,&max3);                                    }                                    fclose(fp);                                    times=0;   }    switch(sel%4) {                                 /*选择速度*/                                          case0:                                          l=0;                                          gameOver();                                          close();                                          break;                                           case1:                                          sp=5;                                          init();                                          sprintf(text,"Hightestscore:%d",max1);                                          outtextxy(50,90,text);                                          break;                                           case2:                                          sp=3;                                          init();                                          sprintf(text,"Hightestscore:%d",max2);                                          outtextxy(50,90,text);                                          break;                                           case3:                                          sp=1;                                          init();                                          sprintf(text,"Hightestscore:%d",max3);                                          outtextxy(50,90,text);                                          break;                                           default:                                          break;                                   } }

这是资源地址,源代码http://download.csdn.net/source/3483954

设计报告http://download.csdn.net/source/3483963


原创粉丝点击