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

3 篇文章 1 订阅
3 篇文章 0 订阅

 

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

 

课 题 名 称     贪吃蛇游戏          

班       级       软件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


  • 33
    点赞
  • 210
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值