自学内容网 自学内容网

基于C语言的“贪吃蛇”游戏设计理念

3.功能描述本游戏主要实现以下几种功能

                         图1.游戏功能模块

3.1. 贪吃蛇的控制功能:通过各种条件的判断,实现对游戏蛇的左移、右移、下移、上移、自由移动,贪吃蛇的加长功能。

3.2. 游戏显示更新功能:当贪吃蛇左右移动、上下移动,以及身体加长时要清除先前的贪吃蛇图像,用新坐标重绘贪吃蛇。

3.3. 游戏分数更新功能:在游戏玩家进行游戏过程中,需要按照一定的游戏规则给游戏玩家计算游戏分数。比如,贪吃蛇每吃到一个事物就加十分。

4.数据结构设计

4.1食物Food结构体

      struct Food

{

        int x;/*食物的横坐标*/

        int y;/*食物的纵坐标*/

      int yes;/*判断是否要出现食物的变量*/

}food;

4.2贪吃蛇snake的结构体

     struct Snake

{

     int x[N];

     int y[N];

     int node;/*蛇的节数*/

     int direction;/*蛇移动方向*/

     int life;/* 蛇的生命,0活着,1死亡*/

}snake;

5.程序设计实现

5.1. 主函数main()

 Main()函数主要实现了对整个程序的运行控制,以及相关功能模块的调用。

void Init(void);/*图形驱动*/

void Close(void);/*图形结束*/

void DrawK(void);/*开始画面*/

void GameOver(void);/*结束游戏*/

void GamePlay(void);/*玩游戏具体过程*/

void PrScore(void);/*输出成绩*/

void main(void)

{

   Init();/*图形驱动*/

   DrawK();/*开始画面*/

   GamePlay();/*玩游戏具体过程*/

   Close();/*图形结束*/

}

5.2. 图形驱动init()

Init()主要功能是初始化屏幕为图形模式函数。

void Init(void)

{

   int gd=DETECT,gm;

   initgraph(&gd,&gm,"c:\\tc");

   cleardevice();

}

5.3. 开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙

void DrawK(void)

{

/*setbkcolor(LIGHTGREEN);*/

   setcolor(11);

   setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/

   for(i=50;i<=600;i+=10)/*画围墙*/

   {

      rectangle(i,40,i+10,49); /*上边*/

      rectangle(i,451,i+10,460);/*下边*/

   }

  for(i=40;i<=450;i+=10)

  {

     rectangle(50,i,59,i+10); /*左边*/

     rectangle(601,i,610,i+10);/*右边*/

  }

}

5.4. 玩游戏具体过程

主要实现游戏运行中的操作,以及分数更新等。

void GamePlay(void)

{

   randomize();/*随机数发生器*/

   food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/

   snake.life=0;/*活着*/

   snake.direction=1;/*方向往右*/

   snake.x[0]=100;snake.y[0]=100;/*蛇头*/

   snake.x[1]=110;snake.y[1]=100;

   snake.node=2;/*节数*/

   PrScore();/*输出得分*/

   while(1)/*可以重复玩游戏,压ESC键结束*/

   {

      while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/

      {

  if(food.yes==1)/*需要出现新食物*/

  {

      food.x=rand()%400+60;

      food.y=rand()%350+60;

      while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/

  food.x++;

      while(food.y%10!=0)

  food.y++;

  food.yes=0;/*画面上有食物了*/

  }

  if(food.yes==0)/*画面上有食物了就要显示*/

  {

              setcolor(GREEN);

              rectangle(food.x,food.y,food.x+10,food.y-10);

  }

         for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/

         {

            snake.x[i]=snake.x[i-1];

     snake.y[i]=snake.y[i-1];

  }

       /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/

  switch(snake.direction)

  {

     case 1:snake.x[0]+=10;break;

     case 2: snake.x[0]-=10;break;

     case 3: snake.y[0]-=10;break;

     case 4: snake.y[0]+=10;break;

  }

  for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/

  {

     if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])

     {

               GameOver();/*显示失败*/

               snake.life=1;

               break;

     }

        }

 if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||

    snake.y[0]>455)/*蛇是否撞到墙壁*/

 {

     GameOver();/*本次游戏结束*/

     snake.life=1; /*蛇死*/

 }

 if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/

           break;

 if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/

 {

           setcolor(0);/*把画面上的食物东西去掉*/

           rectangle(food.x,food.y,food.x+10,food.y-10);

    snake.x[snake.node]=-20;snake.y[snake.node]=-20;

          /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/

    snake.node++;/*蛇的身体长一节*/

    food.yes=1;/*画面上需要出现新的食物*/

    score+=10;

    PrScore();/*输出新得分*/

 }

 setcolor(4);/*画出蛇*/

 for(i=0;i<snake.node;i++)

    rectangle(snake.x[i],snake.y[i],snake.x[i]+10,

               snake.y[i]-10);

 delay(gamespeed);

 setcolor(0);/*用黑色去除蛇的的最后一节*/

 rectangle(snake.x[snake.node-1],snake.y[snake.node-1],

 snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);

     }  /*endwhile(!kbhit)*/

    if(snake.life==1)/*如果蛇死就跳出循环*/

        break;

    key=bioskey(0);/*接收按键*/

    if(key==ESC)/*按ESC键退出*/

       break;

    else

       if(key==UP&&snake.direction!=4)

/*判断是否往相反的方向移动*/

   snake.direction=3;

       else

   if(key==RIGHT&&snake.direction!=2)

      snake.direction=1;

   else

      if(key==LEFT&&snake.direction!=1)

  snake.direction=2;

      else

  if(key==DOWN&&snake.direction!=3)

     snake.direction=4;

   }/*endwhile(1)*/

}

5.5. 游戏结束

结束游戏的运行。

void GameOver(void)

{

    cleardevice();

    PrScore();

   setcolor(RED);

   settextstyle(0,0,4);

   outtextxy(200,200,"GAME OVER");

   getch();

}

5.6. 输出成绩

其功能是输出玩家游戏结束后的分数。

void PrScore(void)

{   

   char str[10];

   setfillstyle(SOLID_FILL,YELLOW);

   bar(50,15,220,35);

   setcolor(6);

   settextstyle(0,0,2);

   sprintf(str,"score:%d",score);

   outtextxy(55,20,str);

}

5.7. 图形结束

结束图形驱动函数,退出程序。

void Close(void)

{    getch();

    closegraph();

}

6.游戏设计过程与思路

      首先,明确该游戏所拥有的功能与游戏规则。

贪吃蛇的要求为:一条蛇在封密的围墙内,在围墙内随机出现一个食物。通过按键盘上的四个光标控键控制蛇向上下左右四个方向移动,蛇头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时计10分,接着又出现食物,等待被蛇吃掉。如果蛇在移动过程中,撞到墙壁或蛇头撞到自己身体游戏结束。

这个程序的关键点是表示蛇的图形以及蛇的移动。可以用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇。这时,由于没有清屏的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来蛇会多一节身体,应将蛇的最后一节用背景覆盖。食物的出现和消失也可以用画矩形块和覆盖矩形块方法实现。为了便于理解,可以定义两个结构体:食物和蛇。

整个游戏可分为四个步骤:

1. 自行设计开始界面,按键或鼠标点击开始游戏。

2. 显示游戏界面,按游戏规则进行游戏。

3. 画面实时显示选手得分,贪吃蛇每吃一个食物,蛇身长一节。

4. 结束时给出提示和得分。

7.结论

本文讲述了贪吃蛇游戏的实现原理,对程序的模块设计、数据结构设计做了简单分析。并通过源码分析讲述了各个模块的实现方法。在几个模块的实现过程中渗透了部分图形功能函数。通过本文的编写过程 ,掌握了以下几点知识点:

  1. 图形系统的初始化和关闭
  2. 各种画图函数的使用
  3. 结构体的定义
  4. 数组定义及应用
  5. 函数嵌套及调用
  6. 键盘操作

参考文献:

【1】姜灵芝,余健.  C语言课程设计案例精编 . 清华大学出版社   2008

【2】何援军 .计算机图形学.  机械工业出版社  2002

【3】 谭浩强 .C程序设计(第三版).  清华大学出版社  2005

【4】李春葆. 数据结构教程(第二版).   清华大学出版社  2007.3


原文地址:https://blog.csdn.net/qq_42769760/article/details/136805505

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!