C++版贪吃蛇游戏

来源:互联网 发布:文科恋曲知乎 编辑:程序博客网 时间:2024/06/07 02:36

  贪吃蛇游戏的设计思路如下:

      1)用二维数组来存储显示面板,即有蛇的地方用1表示,没有的地方用0表示,最后据此来绘制图。

      2)用时间函数来控制小蛇的移动速度,如每个1秒或500ms等,可以用此来设置等级。

      3)贪吃蛇所有的轨迹都是其蛇头走过的轨迹,所以只要记录蛇头的位置,其后的节点都跟随他。

      4)用二维数组来记录蛇的所有节点。

 截图:

截图:

转载请标明出处:http://blog.csdn.net/u012027907

过多的我就不说了,下面是代码,有很详细的注释。

[cpp] view plaincopy
  1. #include <stdio.h>    
  2. #include <windows.h>    
  3. #include <time.h>    
  4. #include <conio.h>       
  5. #include <iostream.h>  
  6.   
  7. //-------------------------------------------------------------------  
  8. void GotoXY(int x, int y)      //设定输出位置  
  9. {    
  10.     COORD c;    
  11.     c.X = x-1;    
  12.     c.Y = y-1;    
  13.     SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);    
  14. }   
  15. //-----------------------------------------------------------------  
  16. void color(int a)              //颜色函数  
  17. {  
  18. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);  
  19. }  
  20. struct HeroList  
  21. {  
  22.     char Name[10];  
  23.     int Highscore;  
  24. }Hero[10];  
  25. //----------------------------------------------------------  
  26. void Save()                    //存储最高分及名字  
  27. {  
  28.     FILE *fp;  
  29.     if((fp=fopen("Hero_list","wb"))==NULL)  
  30.     {cout<<"can not open file!"<<endl;return;}  
  31.     if(fwrite(&Hero[0],sizeof(struct HeroList),1,fp)!=1)  
  32.         cout<<"file write error!"<<endl;  
  33.     fclose(fp);  
  34. }  
  35. //**********************************************************  
  36. class CSnake  
  37. {  
  38.      int image[20][20];        //游戏面板,即小蛇活动范围  
  39.      int FoodX;                //事物出现的X坐标  
  40.      int FoodY;                //事物出现的Y坐标  
  41.      int snakeX;               //记录小蛇的头部X坐标  
  42.      int snakeY;               //记录小蛇的头部Y坐标  
  43.      int head;                 //小蛇头部下标  
  44.      int tail;                 //小蛇尾部下标  
  45.      int snake[2][2000];         //记录小蛇所有身体的坐标  
  46.      int node;                 //小蛇的节数  
  47.      int direction;            //小蛇头部的方向          
  48.      int i,j;         
  49.      int gamespeed;            //速度  
  50.      int score;                //记录分数  
  51.      char arrowKey;            //接受按键的变量  
  52.      int GameOver;             //使游戏结束的变量  
  53.      int level;                //设置等级  
  54.      int length;               //为了设置等级而与node一样记录设的长度  
  55. public:  
  56.        
  57.     CSnake()        //构造函数初始化部分变量  
  58.     {  
  59.         head=3;                //初始化头部下标  
  60.         tail=0;                //初始化尾部下标  
  61.         node=4;                //小蛇初始节数为4节  
  62.         gamespeed=300;         //游戏速度(移动的间隔时间)  
  63.         score=0;               //初始化分数为0  
  64.         direction=6;           //小蛇的初始方向向右  
  65.         GameOver=0;            //进入游戏初始化为0  
  66.         level=1;  
  67.         length=4;  
  68.     }  
  69.     ~CSnake()     //析构函数  
  70.     {}    
  71.     void Init();                //初始化游戏面板及小蛇的坐标  
  72.     int  DrawSnake();           //记录小蛇每次移动后头部及身体的下一坐标  
  73.     void  Automove();            //使小蛇自动移动  
  74.     int  Gameover();            //判断游戏是否结束  
  75.     int  Generatefood();        //产生食物  
  76.     void display();             //显示游戏面板  
  77.     void shiftLeft();           //控制左移  
  78.     void shiftRight();          //控制右移  
  79.     void shiftDown();           //控制下移  
  80.     void shiftUp();             //控制上移  
  81.     int  PlayGame();            //执行游戏的函数  
  82.     void Setspeed();            //设置速度  
  83.     int Pause();                //游戏的暂停  
  84. };  
  85. //-------------------------------------- -------------------------------  
  86.  void CSnake::Init()             //初始化部分数据  
  87. {  
  88.        
  89.  for(i=0;i<20;i++)                   //初始化游戏面板  
  90.    for(j=0;j<20;j++)      
  91.     image[i][j]=0;  
  92.  for(i=0;i<4;i++)                    //初始化小蛇初始位置  
  93.     { snake[0][i]=1;  
  94.       snake[1][i]=i+1;  
  95.     }  
  96.  for(i=1;i<=3;i++)                   //初始化小蛇坐标的显示值(即初始化小蛇显示图形对应的值)  
  97.         image[1][i]=3;   
  98.    image[1][4]=1;  
  99. }  
  100. //---------------------------------------------------------------  
  101. int CSnake::Gameover()                //判断游戏是否结束  
  102. {  
  103.   if(snakeX<0 || snakeX>19 ||snakeY<0 || snakeY>19)                       // 碰到墙壁游戏结束  
  104.   {    
  105.       GotoXY(1,25);     
  106.       cout << "Game over!" << endl;  
  107.       GameOver=1;  
  108.      return GameOver;  
  109.   }  
  110.   if((image[snakeX][snakeY]!=0)&&!(snakeX==FoodX&&snakeY==FoodY))         //蛇头碰到蛇身游戏结束  
  111.    {   
  112.       GotoXY(1,25);   
  113.       cout << "Game over!" << endl;  
  114.       GameOver=1;  
  115.       return GameOver;  
  116.   }  
  117.   return 0;  
  118. }  
  119. //----------------------------------------------------------------  
  120. int CSnake::DrawSnake()  
  121. {   if(snakeX==FoodX && snakeY==FoodY)                                  //若小蛇头部坐标与食物坐标重叠则吃掉食物  
  122.      {                                  
  123.       node++;                                                           // 小蛇节数增一  
  124.       score+=10;                                                        //分数增加    
  125.       length++;  
  126.       if(length>=8)                                                     //当小蛇增长到8个时,等级加一  
  127.       {length-=8;  
  128.       level++;}  
  129.       image[snakeX][snakeY]=1;                                           //小蛇头部移动的下一位置头部图像对应的值赋给图像  
  130.       image[snake[0][head]][snake[1][head]] = 3;                         //小蛇头部其后紧跟的身体一格移动的下一位置头部图像对应的值赋给图像  
  131.       head=(head+1)%10000;  
  132.       snake[0][head] = snakeX;                                           //将小蛇头部此时的坐标值赋给记录头部坐标的snake[0][head]  
  133.       snake[1][head] = snakeY;  
  134.       Generatefood();                                                    //吃掉食物后再次随机分布食物  
  135.       display();                                                         //刷新显示  
  136.          
  137.       }  
  138.      else  
  139.      {                                                                    //没有吃食物  
  140.       image[snake[0][tail]][snake[1][tail]]=0;                            //擦去小蛇尾部  
  141.       tail=(tail+1)%10000;                                                  
  142.       image[snake[0][head]][snake[1][head]]=3;                            //小蛇头部其后紧跟的身体一格移动的下一位置头部图像对应的值赋给图像  
  143.       head=(head+1)%10000;  
  144.       snake[0][head]=snakeX;                                              //将小蛇头部此时的坐标值赋给记录头部坐标的snake[0][head]  
  145.       snake[1][head]=snakeY;  
  146.       image[snake[0][head]][snake[1][head]]=1;                            //小蛇头部移动的下一位置头部图像对应的值赋给图像  
  147.       display();   
  148.       }  
  149.    
  150.   return 0;  
  151. }  
  152. //-----------------------------------------------------------  
  153. void CSnake::shiftLeft()                                                 //左移则小蛇蛇头方向向左  
  154. {     
  155.     direction=4;         
  156. }  
  157. //++++++++++++++++++++++++++  
  158. void CSnake::shiftRight()                                                //右移则小蛇蛇头方向向右  
  159. {  
  160.     direction=6;         
  161. }  
  162. //+++++++++++++++++++++++++++  
  163. void CSnake::shiftUp()                                                    //上移则小蛇蛇头方向向上  
  164. {  
  165.     direction=8;         
  166. }     
  167. //+++++++++++++++++++++++++++  
  168. void CSnake::shiftDown()                                                  //下移则小蛇蛇头方向向下  
  169. {       
  170.     direction=2;         
  171. }  
  172. //------------------------------------------------------  
  173. void CSnake::Automove()  
  174. {  
  175.     switch(direction)  
  176.     {                                                                   
  177.     case 6:snakeX= snake[0][head]; snakeY= snake[1][head]+1;break;          //接收到向右的信息小蛇头部Y坐标加一,X坐标不变并赋给记录头部坐标的变量  
  178.     case 4:snakeX= snake[0][head]; snakeY= snake[1][head]-1;break;         //接收到向左的信息小蛇头部Y坐标减一,X坐标不变并赋给记录头部坐标的变量  
  179.     case 8:snakeX= snake[0][head]-1; snakeY= snake[1][head];break;          //接收到向上的信息小蛇头部X坐标加一,Y坐标不变并赋给记录头部坐标的变量  
  180.     case 2:snakeX= snake[0][head]+1; snakeY= snake[1][head];break;          //接收到向下的信息小蛇头部X坐标加一,Y坐标不变并赋给记录头部坐标的变量  
  181.     default:;  
  182.     }  
  183. }  
  184. //---------------------------------------------------------------------   
  185. int CSnake::Generatefood()                                        // 产生食物  
  186. {    
  187.     srand(time(0));                                               //以时间为种子生成随机序列  
  188.     do{   
  189.      FoodX=rand()%20;                                             //食物输出的X坐标  
  190.      FoodY=rand()%20;                                             //食物输出的Y坐标  
  191.     }while(image[FoodX][FoodY]!=0);                               //产生的食物坐标限定在游戏面板内,且食物坐标不与小蛇身体坐标重合  
  192.     image[FoodX][FoodY]=2;  
  193.  return image[FoodX][FoodY];  
  194. }  
  195. //----------------------------------------------------------------  
  196. void CSnake::display()                                            // 显示游戏面板(包括围墙、食物及小蛇)  
  197. {    
  198.     color(10);  
  199.     GotoXY(1,1);  
  200.     for(i=0;i<22;i++)    
  201.     printf("■");    
  202.     GotoXY(1,2);   
  203.     for(i=0;i<20;i++)    
  204.     {   color(10);  
  205.     printf("■");    
  206.     for(j=0;j<20;j++)    
  207.     {  
  208.         switch(image[i][j])    
  209.         {  
  210.         case 0:color(15);printf("  ");break;    
  211.         case 1:color(11);printf("□");break;  
  212.         case 2:color(12);printf("☆");break;   
  213.         case 3:color(13);printf("●");break;  
  214.         }  
  215.     }  color(10);  
  216.     printf("■\n");  
  217. }    
  218.     color(10);  
  219. for(i=0;i<22;i++)    
  220. printf("■");  color(13);  
  221. GotoXY(46,9); printf("SCORE:%d",score);         //记录分数  
  222. GotoXY(46,10); printf("LEVEL=%d",level);         //记录等级  
  223. color(12);  
  224. GotoXY(46,5); printf("本程序由张亚超编写!\n");  
  225. GotoXY(46,6); printf("版权所有!侵权必究!");  
  226. }  
  227. //----------------------------------------------------  
  228. void CSnake::Setspeed()                           //设置小蛇移动的速度  
  229. {    
  230.     int Esc=0;   
  231.     while(!Esc)  
  232.     {  
  233.         int speed;  
  234.                 color(12);  
  235.                 cout<<"1.Very Slow   2.Slow   3.Normal   4.Fast   5.Very Fast "<<endl;  
  236.                 cout<<"请输入您的选择:";  
  237.                 cin>>speed;  
  238.                 switch(speed)  
  239.                 {  
  240.                 case 0:  
  241.                     Esc=1;  
  242.                     gamespeed=300;  
  243.                     break;  
  244.                 case 1:  
  245.                     gamespeed=300;  
  246.                     Esc=1;  
  247.                     break;  
  248.                 case 2:  
  249.                     gamespeed=200;  
  250.                     Esc=1;  
  251.                     break;  
  252.                 case 3:  
  253.                     gamespeed=80;  
  254.                     Esc=1;  
  255.                     break;  
  256.                case 4:  
  257.                     gamespeed=30;  
  258.                     Esc=1;  
  259.                     break;  
  260.               case 5:  
  261.                     gamespeed=12;  
  262.                     Esc=1;  
  263.                     break;  
  264.                 }  
  265.     }  
  266. }  
  267. //-----------------------------------------------------------  
  268. int CSnake::Pause()                   //暂停功能  
  269. {  
  270.     char c;    
  271.    // GotoXY(1,25);printf("Pause! ");    
  272.     do    
  273.     {c=getch();}    
  274.     while(c!='p');    
  275.     arrowKey=0;  
  276.     return arrowKey;  
  277. }   
  278. //--------------------------------------------     
  279. //**************************************************************  
  280. int CSnake::PlayGame()                                        //执行游戏函数  
  281.  {  
  282.    Init();                                                    //初始化数据  
  283.    Generatefood();                                            //产生食物  
  284.    display();                                                 //显示游戏面板  
  285.     while (!GameOver)         
  286.     {         
  287.         if(kbhit())                                            //接受按键  
  288.         {  
  289.           arrowKey = getch();  
  290.         }     
  291.             if(direction==2||direction==8)                     //当小蛇的头部移动方向为上下时,左右键才起作用  
  292.             {  
  293.               switch(arrowKey)  
  294.               {  
  295.               case'6':shiftRight();break;  
  296.               case'4':shiftLeft();break;                    
  297.               case'e':exit(1);break;  
  298.               case'p':Pause();break;  
  299.               default:break;  
  300.                }          
  301.             }  
  302.             else if(direction==4||direction==6)                 //当小蛇的头部移动方向为左右时,上下键才起作用  
  303.             {  
  304.               switch(arrowKey)                          
  305.               {  
  306.               case'8':shiftUp();break;  
  307.               case'5':shiftDown();break;                   
  308.               case'e':exit(1);break;                    
  309.               case'p':Pause();break;  
  310.               default:break;  
  311.               }               
  312.             }     
  313.             Sleep(gamespeed);                                 //小蛇移动一格的速度  
  314.             Automove();                                       // 校舍自动移动  
  315.             Gameover();                                       //判断游戏是否结束  
  316.             if(GameOver==1)                                   //若游戏结束,则直接跳出循环  
  317.                 break;  
  318.             DrawSnake();                                      //判断是否吃食物  
  319.             display();                                        //显示游戏面板  
  320.     }  
  321.     Hero[0].Highscore=score;  
  322.     getch();  
  323.     return 0;  
  324. }  
  325. //**************************************************************************  
  326. void Welcome(void)                                           //欢迎界面  
  327. {  
  328.     printf("                                                                                ");color(13);  
  329.     printf(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ");  
  330.     printf("                                                                                ");  
  331.     printf("                                                                                ");  
  332.     printf("                                                                                ");color(14);  
  333.     printf("                                                                                ");  
  334.     printf("  ■■■■■    ■■■        ■■      ■■■      ■■       ■  ■■■■■■ ");  
  335.     printf("■■■■■■■  ■■■■      ■■    ■■■■■    ■■      ■   ■■■■■■ ");  
  336.     printf("■■■  ■■■  ■■ ■■     ■■   ■■    ■■   ■■    ■     ■■         ");  
  337.     printf("■■■          ■■  ■■    ■■  ■■      ■■  ■■  ■       ■■         ");  
  338.     printf("  ■■■■      ■■   ■■   ■■  ■■      ■■  ■■ ■        ■■■■■■ ");  
  339.     printf("   ■■■■■   ■■    ■■  ■■  ■■■■■■■  ■■■         ■■■■■■ ");  
  340.     printf("        ■■■  ■■     ■■ ■■  ■■■■■■■  ■■ ■        ■■         ");  
  341.     printf("■■■  ■■■  ■■      ■■■■  ■■      ■■  ■■   ■      ■■         ");  
  342.     printf("■■■■■■■  ■■        ■■■  ■■      ■■  ■■     ■    ■■■■■■ ");  
  343.     printf("  ■■■■■    ■■          ■■  ■■      ■■  ■■      ■■ ■■■■■■ ");  
  344.     printf("                                                                                ");  
  345.     printf("                                                                                ");color(13);  
  346.     printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ");color(10);  
  347.     printf("【C++语言贪吃蛇游戏】张亚超编写!!! 版权所有,侵权必究!\n");  
  348.     printf("[上移:8 ;下移:5 ;左移:4 ;右移:6 ; 暂停:P; 退出:E]\n");                                
  349.     system("pause");  
  350.     system("cls");  
  351. }  
  352.   
  353.   
  354. //----------------------------------------------  
  355. ////////////////////////////////////////////////////////////////////////////////////////////////////  
  356. void main()                                        //主函数  
  357. {     
  358.     CSnake SNAKE;  
  359.     char Name[10]=" ";  
  360. //  int Highscore=0;  
  361.     char ch;  
  362.     char Get=0;  
  363. //  int i;  
  364.     Welcome();  
  365.     while(1)  
  366.     {      
  367.         color(14);                                                  // 主界面  
  368.         cout<<"     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     "<<endl;  
  369.         cout<<"   -----* - * - * - * - * - * - *----   "<<endl;  
  370.         cout<<"   $   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁   $      "<<endl;  
  371.         cout<<"   $   ▏                          ▏ $      "<<endl;  
  372.         cout<<"   $   ▏       1.开始游戏         ▏ $      "<<endl;  
  373.         cout<<"   $   ▏       2.设置速度         ▏ $      "<<endl;  
  374.         cout<<"   $   ▏       3.使用说明         ▏ $      "<<endl;  
  375.         cout<<"   $   ▏       4.英雄榜           ▏ $      "<<endl;  
  376.         cout<<"   $   ▏       5.退出             ▏ $      "<<endl;  
  377.         cout<<"   $   ▏                          ▏ $      "<<endl;  
  378.         cout<<"   $   ▔▔▔▔▔▔▔▔▔▔▔▔▔▔   $      "<<endl;  
  379.         cout<<"   -----* - * - * - * - * - * - *----   "<<endl;  
  380.         cout<<"     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     "<<endl;  
  381.         cin>>ch;  
  382.           
  383.         if(ch=='1')  
  384.         {     
  385.             system("cls");  
  386.             SNAKE.PlayGame();  
  387.             system("cls");  
  388.             if(Hero[0].Highscore<100)  
  389.             {cout<<"您还需努力哟!"<<endl;cout<<endl;}  
  390.             else if(400>Hero[0].Highscore&&Hero[0].Highscore>200)  
  391.             {cout<<"您一定是高手!"<<endl;cout<<endl;}  
  392.             else if(600>Hero[0].Highscore&&Hero[0].Highscore>400)  
  393.             {   cout<<"您实在太厉害了!"<<endl;cout<<endl;}  
  394.             else  
  395.             {   cout<<"您一定是骨灰级玩家!佩服!佩服!"<<endl;cout<<endl;}  
  396.             if(Hero[0].Highscore>200)  
  397.             {  
  398.             cout<<"请输入您的大名:";  
  399.             cin>>Hero[0].Name;              
  400.             Save();       
  401.             }  
  402.             system("pause");  
  403.             system("cls");    
  404.             break;  
  405.         }  
  406.         else if(ch=='2')  
  407.         {  
  408.             system("cls");  
  409.             SNAKE.Setspeed();  
  410.             system("pause");  
  411.             system("cls");  
  412.             continue;  
  413.         }  
  414.         else if(ch=='3')                                               //详细使用说明  
  415.         {  
  416.             system("cls");  
  417.             cout<<"                                                    "<<endl;  
  418.             cout<<"                                                    "<<endl;color(14);  
  419.             cout<<"    *********************************************** "<<endl;color(12);  
  420.             cout<<"    *   上移:8 ;       左移:4 ;    暂停:P      * "<<endl;  
  421.             cout<<"    *   下移:5 ;       右移:6 ;    退出:E      * "<<endl;color(14);   
  422.             cout<<"    *********************************************** "<<endl;color(12);  
  423.             cout<<"    $        按相应的键可以控制小蛇的移动!        $ "<<endl;  
  424.             cout<<"    $         通过控制小蛇的移动来吃食物!        $ "<<endl;  
  425.             cout<<"    $当小蛇的头部撞到墙壁或自己的身体时,游戏结束!$ "<<endl;color(14);  
  426.             cout<<"    #-------------------------------------------- # "<<endl;  
  427.             cout<<"    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "<<endl;  
  428.             cout<<"                                                    "<<endl;  
  429.             cout<<"                                                    "<<endl;  
  430.             system("pause");  
  431.             system("cls");  
  432.             continue;  
  433.         }  
  434.         else if(ch=='4')                                             // 记录最高分,显示英雄榜  
  435.         {  
  436.             system("cls");  
  437.             color(10);  
  438.             FILE *fp;  
  439.             fp=fopen("Hero_list","rb");  
  440.             fread(&Hero[0],sizeof(struct HeroList),1,fp);  
  441.             cout<<"$#######_---   英雄榜:  ---_#######$"<<endl;  
  442.             cout<<"               名字:"<<Hero[0].Name<<endl;  
  443.             cout<<"               最高分:"<<Hero[0].Highscore<<endl;  
  444.             cout<<"--------------------------------------------"<<endl;  
  445.             fclose(fp);  
  446.             system("pause");  
  447.             system("cls");            
  448.             continue;  
  449.         }  
  450.         else if(ch=='5')  
  451.         {  
  452.             system("cls");  
  453.             exit(0);  
  454.         }  
  455.         else  
  456.         {  
  457.             system("cls");  
  458.             cout<<"请重新输入!"<<endl;     
  459.             continue;  
  460.         }  
  461.     }     
  462.           
  463. }   
  464.       原文地址:http://blog.csdn.net/u012027907/article/details/12114991
  465.