• 基于C++控制台实现的贪吃蛇


    本文为大大维原创,最早于博客园发表,转载请注明出处!!!

    虽然本人一直是个免费的游戏测试员(/手动滑稽),但一直有着一个游戏架构师的梦想。正如马爸爸所说,梦想还是要有的,万一实现了呢?

    这些天放寒假,有些空闲时间,就想着做一个简单的游戏机。能达到小时候十几块钱买的那种小霸王的功能就差不多了(有贪吃蛇,赛车小游戏,俄罗斯方块,雷霆战机,坦克大战,2048,拼图等),好吧,原谅我有些浮夸风(/手动斜眼)。。。

    这不,下面是我这两天抠出来的一个最简单的贪吃蛇小游戏,姑且叫它“大大维的贪吃蛇v1”吧!!!

    游戏功能比较简单,后续还需要完善。先将代码在这保存一份,日后看看,也是一件挺有意思的事情吧!!!

      1 /**--------------------------------------------------**/
      2 /**名称:大大维的贪吃蛇v1             日期:2017/1/22**/
      3 /**描述:实现了贪吃蛇的基本功能,可以调节游戏难度,**/
      4 /**做了一个简单的用户界面                           **/
      5 /**存在的问题:由于使用了全局数组存贮,因此对Space **/
      6 /**类的封装有些欠缺;由于使用了全局刷新,游戏运行中**/
      7 /**会出现闪屏现象,游戏难度越高,闪动越严重;不能够**/
      8 /**存储玩家的游戏记录,由于不是图形化界面,用户界面**/
      9 /**较丑;不能改变游戏的地图大小                      **/
     10 /**笔者会在后续版本逐步完善这些问题!!!              **/
     11 /**--------------------------------------------------**/
     12 
     13 #include<iostream>
     14 #include<ctime>
     15 #include<cstdlib>
     16 #include<cstdio>
     17 #include<conio.h>
     18 #include<windows.h>
     19 using namespace std;
     20 const int SpaceLENG=20;
     21 const int SpaceHIGH=40;
     22 const int HARDSPEED=100;
     23 const int NOMALSPEED=400;
     24 const int EASYSPEED=700;
     25 int speed=NOMALSPEED;
     26 bool FLAG=true;
     27 enum dir {UP,DOWN,LEFT,RIGHT};///使用小写会引发歧义
     28 enum level {HARD,ESAY,NOMAL};
     29 ///----------------------------------------------------
     30 ///游戏空间定义
     31 class Space
     32 {
     33 public:
     34     void InitSpace();
     35     void DisplaySpace();
     36 public:
     37     char SpaceData[SpaceLENG+2][SpaceHIGH+2];
     38 };
     39 void Space::InitSpace()
     40 {
     41     for(int i=-1; i<SpaceLENG+1; i++)
     42         for(int j=-1; j<SpaceHIGH+1; j++)
     43         {
     44             if(i<0||i==SpaceLENG||j<0||j==SpaceHIGH)
     45                 SpaceData[i][j]='#';
     46             else
     47                 SpaceData[i][j]=' ';
     48         }
     49 }
     50 void Space::DisplaySpace()
     51 {
     52     for(int i=-1; i<SpaceLENG+1; i++)
     53     {
     54         for(int j=-1; j<SpaceHIGH+1; j++)
     55         {
     56             cout<<SpaceData[i][j];
     57         }
     58         cout<<endl;
     59     }
     60     cout<<endl<<endl;
     61 }
     62 Space *spa=new Space();
     63 ///----------------------------------------------------
     64 ///蛇节点定义
     65 class SnakeNode
     66 {
     67 public:
     68     void setXY(int m,int n)
     69     {
     70         x=m;
     71         y=n;
     72     }
     73     void setNext(SnakeNode *temp)
     74     {
     75         next=temp;
     76     }
     77     void setPrior(SnakeNode *temp)
     78     {
     79         prior=temp;
     80     }
     81     int getX()
     82     {
     83         return x;
     84     }
     85     int getY()
     86     {
     87         return y;
     88     }
     89     SnakeNode* getNext()
     90     {
     91         return next;
     92     }
     93     SnakeNode* getPrior()
     94     {
     95         return prior;
     96     }
     97 private:
     98     int x,y;
     99     SnakeNode *prior,*next;
    100 };
    101 ///----------------------------------------------------
    102 ///食物定义
    103 class Food
    104 {
    105 public:
    106     void foodCreate()
    107     {
    108         bool flag=true;
    109         while(flag)
    110         {
    111             srand((unsigned int)time(NULL));
    112             fx=rand()%SpaceLENG;
    113             fy=rand()%SpaceHIGH;
    114             if(spa->SpaceData[fx][fy]!='*')
    115                 flag=false;
    116         }
    117 
    118         spa->SpaceData[fx][fy]='$';
    119     }
    120     int getFx()
    121     {
    122         return fx;
    123     }
    124     int getFy()
    125     {
    126         return fy;
    127     }
    128 private:
    129     int fx;
    130     int fy;
    131 };
    132 ///----------------------------------------------------
    133 ///蛇定义
    134 class Snake:public SnakeNode,public Food
    135 {
    136 public:
    137     Snake()
    138     {
    139         addHead(SpaceLENG/2,SpaceHIGH/2);
    140         addHead(SpaceLENG/2,SpaceHIGH/2-1);
    141         addHead(SpaceLENG/2,SpaceHIGH/2-2);
    142     }
    143     void addHead(int x,int y);
    144     void delTail();
    145     void moving();
    146     void changePoint(char keydown);
    147     SnakeNode* getHead()
    148     {
    149         return head;
    150     }
    151     SnakeNode* getTail()
    152     {
    153         return tail;
    154     }
    155     int getLEN()
    156     {
    157         return LEN;
    158     }
    159 private:
    160     SnakeNode *head=NULL,*tail=NULL;
    161     int LEN=0;
    162     dir point=LEFT;
    163 };
    164 void Snake::addHead(int x,int y)
    165 {
    166     SnakeNode *temp=new SnakeNode();
    167     temp->setXY(x,y);
    168     temp->setNext(head);
    169     temp->setPrior(NULL);
    170     if(head)
    171     {
    172         head->setPrior(temp);///如果头不为空
    173         spa->SpaceData[head->getX()][head->getY()]='*';///旧头
    174     }
    175     head=temp;
    176     if(!tail)tail=head;///如果尾为空
    177     spa->SpaceData[head->getX()][head->getY()]='@';///新头
    178     LEN++;
    179 }
    180 void Snake::delTail()
    181 {
    182     SnakeNode *temp=tail;
    183     spa->SpaceData[tail->getX()][tail->getY()]=' ';
    184     if(tail==head)
    185         tail=head=NULL;
    186     else
    187     {
    188         tail=tail->getPrior();
    189         tail->setNext(NULL);
    190         LEN--;
    191     }
    192     delete temp;
    193 
    194 }
    195 void Snake::moving()
    196 {
    197     int a,b;
    198     SnakeNode* temp=getHead();
    199     a=temp->getX();
    200     b=temp->getY();
    201     switch(point)
    202     {
    203     case UP:
    204         --a;
    205         break;
    206     case DOWN:
    207         ++a;
    208         break;
    209     case LEFT:
    210         --b;
    211         break;
    212     case RIGHT:
    213         ++b;
    214         break;
    215     }
    216     ///撞墙
    217     if(a==SpaceLENG||b==SpaceHIGH||a==-1||b==-1)
    218     {
    219         FLAG=false;
    220     }
    221     ///撞自己身体
    222     if(spa->SpaceData[a][b]=='*')
    223     {
    224         spa->SpaceData[a][b]=='@';///用头结点覆盖相撞节点
    225         FLAG=false;
    226     }
    227     ///吃食物
    228     if(a==getFx()&&b==getFy())
    229     {
    230         addHead(a,b);
    231         foodCreate();
    232     }
    233     ///普通移动
    234     else
    235     {
    236         addHead(a,b);
    237         delTail();
    238     }
    239 }
    240 void Snake::changePoint(char keydown)///方向控制
    241 {
    242     switch(keydown)
    243     {
    244     case 'w':
    245     {
    246         if(point!=DOWN)
    247         {
    248             point=UP;
    249             break;
    250         }
    251         else break;
    252     }
    253     case 'W':
    254     {
    255         if(point!=DOWN)
    256         {
    257             point=UP;
    258             break;
    259         }
    260         else break;
    261     }
    262     case 's':
    263     {
    264         if(point!=UP)
    265         {
    266             point=DOWN;
    267             break;
    268         }
    269         else break;
    270     }
    271     case 'S':
    272     {
    273         if(point!=UP)
    274         {
    275             point=DOWN;
    276             break;
    277         }
    278         else break;
    279     }
    280     case 'a':
    281     {
    282         if(point!=RIGHT)
    283         {
    284             point=LEFT;
    285             break;
    286         }
    287         else break;
    288     }
    289     case 'A':
    290     {
    291         if(point!=RIGHT)
    292         {
    293             point=LEFT;
    294             break;
    295         }
    296         else break;
    297     }
    298     case 'd':
    299     {
    300         if(point!=LEFT)
    301         {
    302             point=RIGHT;
    303             break;
    304         }
    305         else break;
    306     }
    307     case 'D':
    308     {
    309         if(point!=LEFT)
    310         {
    311             point=RIGHT;
    312             break;
    313         }
    314         else break;
    315     }
    316     }
    317 }
    318 ///----------------------------------------------------
    319 ///用户交互界面创建
    320 class UserView
    321 {
    322 public:
    323     int menuCreate();
    324     int gameSetting();
    325 };
    326 int UserView::menuCreate()
    327 {
    328     bool flag=true;
    329     while(flag)
    330     {
    331         cout<<"                 MENU"<<endl<<endl;
    332         cout<<"Instruction:"<<endl<<endl;
    333         cout<<"The Snake's original length is 3."<<endl<<endl;
    334         cout<<"Using 'w,s,a,d' or 'W,S,A,D' to control the direction."<<endl<<endl<<endl<<endl;
    335         cout<<"Please Input 'Y'or'y' to start game;"<<endl;
    336         cout<<"Please Input 'N'or'n' to end game;"<<endl;
    337         cout<<"Please Input 'S'or's' to game setting;"<<endl;
    338         cout<<"Please Input else to stay!"<<endl;
    339         char startKey=getch();
    340         if(startKey=='N'||startKey=='n')
    341         {
    342             system("cls");
    343             cout<<"Good Bye!!!"<<endl;
    344             exit(0);
    345         }
    346         else if(startKey=='Y'||startKey=='y')
    347         {
    348             system("cls");
    349             cout<<"         Game Start!!!"<<endl<<endl<<endl<<endl<<endl;
    350             cout<<"         GOOD LUCK!!!"<<endl;
    351             getch();
    352             flag=false;
    353         }
    354         else if(startKey=='S'||startKey=='s')
    355         {
    356             gameSetting();
    357         }
    358         system("cls");
    359     }
    360     system("cls");
    361     return 0;
    362 }
    363 int UserView::gameSetting()
    364 {
    365     system("cls");
    366     cout<<"         Setting:"<<endl<<endl<<endl<<endl;
    367     cout<<"Please Chose Game Difficulty"<<endl;
    368     cout<<"Input 'H'or'h'---Hard  Level"<<endl;
    369     cout<<"Input 'N'or'n'---Nomal Level"<<endl;
    370     cout<<"Input 'E'or'e'---Easy  Level"<<endl;
    371     cout<<"Input else return the MENU"<<endl;
    372     char hardKey=getch();
    373     if(hardKey=='H'||hardKey=='h')
    374     {
    375         cout<<"The Game's Difficulty now is Hard  Level!!!"<<endl;
    376         speed=HARDSPEED;
    377         return 0;
    378     }
    379     else if(hardKey=='N'||hardKey=='n')
    380     {
    381         cout<<"The Game's Difficulty now is Nomal  Level!!!"<<endl;
    382         speed=NOMALSPEED;
    383         return 0;
    384     }
    385     else if(hardKey=='E'||hardKey=='e')
    386     {
    387         cout<<"The Game's Difficulty now is Easy  Level!!!"<<endl;
    388         speed=EASYSPEED;
    389         return 0;
    390     }
    391     system("cls");
    392     return 0;
    393 }
    394 ///----------------------------------------------------
    395 ///程序入口
    396 int main()
    397 {
    398     while(true)
    399     {
    400         FLAG=true;
    401         UserView view;
    402         view.menuCreate();
    403         spa->InitSpace();
    404         Snake sna;
    405         sna.foodCreate();
    406         spa->DisplaySpace();
    407         while(FLAG)
    408         {
    409             char downKey=getch();
    410             sna.changePoint(downKey);
    411             ///kbhit(),检查是否有键盘输入,若有,则返回一个非0值,否则返回0,在头文件<conio.h>中定义
    412             ///此处FLAG如果不加,会产生蛇吃墙现象
    413             while(FLAG&&!kbhit())
    414             {
    415                 system("cls");
    416                 sna.moving();
    417                 spa->DisplaySpace();
    418                 Sleep(speed);
    419             }
    420         }
    421         cout<<"Game Over!!!"<<endl;
    422         cout<<"The Snake's Length is :"<<sna.getLEN()<<endl<<endl<<endl<<endl;
    423         cout<<"The Game Will Return Back MENU!"<<endl;
    424         getch();
    425         system("cls");
    426     }
    427     return 0;
    428 }
    View Code

    最后上几张游戏的运行的截图:

  • 相关阅读:
    [CF997E] Good SubSegment
    CF916E
    BZOJ2006 超级钢琴
    BZOJ4571
    凸包总结
    树形DP入门
    bzoj4300 绝世好题(位运算+DP)
    bzoj4552 [Tjoi2016&Heoi2016]排序 (线段树+二分)
    SP1716 GSS3
    Noip2009 Hankson 的趣味题 (简单数学)
  • 原文地址:https://www.cnblogs.com/liujw2114/p/6341515.html
Copyright © 2020-2023  润新知