• C++控制台贪吃蛇代码


    游戏截图:

    以下是3个代码文件:

    Snake_Class.h文件:

     1 #ifndef SNAKE
     2 #define SNAKE
     3 
     4 #include<windows.h>
     5 #include<vector>
     6 #include<string>
     7 
     8 //标记界面和菜单项的ID
     9 enum ID_ { ID_1=1, ID_2, ID_3, ID_4, ID_5, ID_6, ID_7 };
    10 
    11 //标记初级,中级,高级三种游戏等级
    12 enum Rank_ { first=150, middle=100, high=50 };
    13 
    14 
    15 //贪吃蛇结构   http://www.cnblogs.com/sosoft/
    16 struct Snake_data{
    17     bool state ;                    //标记蛇状态
    18     UINT Snake_size;                //标记蛇长度
    19     std::vector<COORD> Snake_coord; //蛇的当前坐标
    20     COORD food_coord;               //食物坐标
    21     UINT rank;                     //标记等级
    22     UINT mark;                      //分数
    23     UINT key;                       //记录按键方向
    24     ID_ ID_interface;               //标记当前停留界面ID
    25     short ID_option ;               //标记被选中菜单的ID
    26     bool Flag;                      //标记刷新
    27 };
    28 
    29 //贪吃蛇类
    30 class Snake_class{
    31 public:
    32     Snake_class(){}
    33     Snake_class(Snake_data *data): pSnake(data){}
    34     void ShowMenu();            //显示菜单
    35     void StartGame() ;          //开始游戏
    36     void ShowPause();           //显示暂停界面
    37     void SaveRecord();          //保存记录
    38     void ShowRank();            //显示等级
    39     void ShowRecord();          //显示存档记录列表
    40     bool Read( size_t );        //读取记录
    41     void ShowArmory();          //显示英雄榜
    42     void Die();                 //死亡界面
    43     size_t Create_file();       //存储文件
    44 private:
    45     void JudgeDie();            //判断死亡
    46     bool Jesus();               //上榜判断
    47     void ShowSnake( COORD& );   //显示蛇
    48     void ShowPointer( COORD,std::string ); //显示指针
    49     void Show_not();            //显示无数据
    50     Snake_data *pSnake;
    51 };
    52 
    53 
    54 
    55 #endif;

    Snake_class.cpp:

      1 #include"Snake_Class.h"
      2 #include<iostream>
      3 #include<fstream>
      4 #include<ctime>
      5 #include<cstdlib>
      6 
      7 //获取缓冲区句柄
      8 static const HANDLE handle = GetStdHandle( STD_OUTPUT_HANDLE );
      9 static CONSOLE_SCREEN_BUFFER_INFO info ;
     10 //保存蛇的记录数据文件
     11 static const char *Snake_Record[] = { "d://SnakeRecord//Snake1.txt",
     12                                       "d://SnakeRecord//Snake2.txt",
     13                                       "d://SnakeRecord//Snake3.txt",
     14                                       "d://SnakeRecord//Snake4.txt",
     15                                       "d://SnakeRecord//Snake5.txt" };
     16 
     17 static const char *S_Armory[] = { "d://SnakeRecord//Armory1.txt",
     18                                   "d://SnakeRecord//Armory2.txt",
     19                                   "d://SnakeRecord//Armory3.txt" };
     20 //显示主菜单(完成已测试)
     21 void Snake_class::ShowMenu(){
     22     //获取缓冲区相关信息
     23     GetConsoleScreenBufferInfo( handle, &info );
     24     char *str[] = {"开 始 游 戏",
     25                    "难 度 等 级",
     26                    "读 取 存 档",
     27                    "英 雄 榜",
     28                    "退 出 游 戏"};
     29     //输出菜单选项
     30     short y = 3;
     31     COORD cd = { info.srWindow.Right/2 - 5, y };
     32     for( size_t n=0;n<sizeof(str)/sizeof(*str);++n ){
     33         SetConsoleCursorPosition( handle, cd );
     34         std::cout<<*(str+n);
     35         cd.Y += 2;
     36     }
     37 //判断指针指向哪个菜单选项
     38     cd.X -= 2;
     39     cd.Y  = y;
     40     switch( pSnake->ID_option ){
     41         case ID_1:
     42             break;
     43         case ID_2:
     44             cd.Y = y+2; break;
     45         case ID_3:
     46             cd.Y = y+4; break;
     47         case ID_4:
     48             cd.Y = y+6; break;
     49         case ID_5:
     50             cd.Y = y+8; break;
     51     }
     52     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
     53 }
     54 
     55 //开始游戏(完成待测试)
     56 void Snake_class::StartGame(){
     57     COORD cd;
     58     //判断是否已有食物
     59     if( !pSnake->food_coord.X ){
     60         srand((unsigned int)time(NULL));
     61         while(1){
     62             //限制食物出现的坐标不与围墙相同
     63               ++( cd.X = rand()%78 ); 
     64               ++( cd.Y = rand()%18 );
     65             //判断食物坐标是否与蛇身吻合
     66             std::vector<COORD>::iterator ite;
     67             for( ite=pSnake->Snake_coord.begin(); ite!=pSnake->Snake_coord.end(); ++ite ){
     68                     if( ite->X == cd.X && ite->Y == cd.Y )
     69                         break;
     70             }
     71             if( ite == pSnake->Snake_coord.end() ){
     72                 pSnake->food_coord.X = cd.X ;
     73                 pSnake->food_coord.Y = cd.Y ;
     74                 break;
     75             }
     76         }
     77     }
     78     SetConsoleCursorPosition( handle, pSnake->food_coord );
     79     std::cout<<"*";
     80     //判定按键方向
     81     cd.X  = pSnake->Snake_coord.begin()->X;
     82     cd.Y = pSnake->Snake_coord.begin()->Y ;
     83     switch( pSnake->key ){
     84         case VK_UP:
     85             --cd.Y; break;
     86         case VK_DOWN:
     87             ++cd.Y; break;
     88         case VK_LEFT:
     89             --cd.X; break;
     90         case VK_RIGHT:
     91             ++cd.X; break;
     92     }
     93     ShowSnake( cd );
     94     JudgeDie();
     95 }
     96 
     97 //显示暂停界面(完成已测试)
     98 void Snake_class::ShowPause(){
     99     COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
    100     SetConsoleCursorPosition( handle, cd );
    101     std::cout<<"游 戏 暂 停 中 ......";
    102     char *str[] = { "继 续 游 戏",
    103                     "保 存 游 戏",
    104                     "退 出 游 戏" };
    105 //输出菜单选项
    106     short X = info.srWindow.Right/3;
    107     cd.X = X/2-5 ;
    108     cd.Y = info.srWindow.Bottom/3*2-4;
    109     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
    110         SetConsoleCursorPosition( handle, cd );
    111         std::cout<<*(str+i);
    112         cd.X += X;
    113     }
    114 
    115 //判断指针应指向的菜单选项
    116     switch( pSnake->ID_option ){
    117         case ID_1:
    118             cd.X = X/2-7; break;
    119         case ID_2:
    120             cd.X = X/2+X-7; break;
    121         case ID_3:
    122             cd.X = X/2+2*X-7; break;
    123     }
    124     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
    125 }
    126 
    127 //保存记录(完成未测试)
    128 void Snake_class::SaveRecord(){
    129     std::ofstream outopen;
    130     outopen.open( *( Snake_Record + Create_file() ) );
    131     if( !outopen ){
    132         std::cerr<<"
    打开文件失败!
    ";
    133         exit(0);
    134     }
    135     //保存记录到文件中,前面加"0"是为了后面检测是否文件为空使用
    136     outopen<<"0 "<<pSnake->Snake_size<<" ";
    137     for(std::vector<COORD>::iterator ite=pSnake->Snake_coord.begin();
    138         ite!=pSnake->Snake_coord.end();++ite )
    139             outopen<<ite->X<<" "<<ite->Y<<" ";
    140     outopen<<pSnake->rank<<" "<<pSnake->mark<<" "<<pSnake->key;
    141     outopen.close();
    142 //输出保存成功
    143     COORD cd = { info.srWindow.Right/2-4, info.srWindow.Bottom/3*2-1 };
    144     SetConsoleCursorPosition( handle, cd );
    145     std::cout<<"保存成功!a";
    146 }
    147 
    148 //显示等级(已测试)
    149 void Snake_class::ShowRank(){
    150     COORD cd = { info.srWindow.Right/2-6, info.srWindow.Bottom/3+2 };
    151     char *str[] = { "初       级",
    152                     "中       级",
    153                     "高       级" };
    154     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
    155         SetConsoleCursorPosition( handle, cd );
    156         std::cout<<*(str+i);
    157         cd.Y += 2;
    158     }
    159     //判断指针所停留的选项
    160     cd.X -= 2;
    161     cd.Y  = info.srWindow.Bottom/3+2;
    162     switch( pSnake->ID_option ){
    163         case ID_1:
    164             break;
    165         case ID_2:
    166             cd.Y += 2; break;
    167         case ID_3:
    168             cd.Y += 4; break;
    169     }
    170     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
    171 }
    172 
    173 //显示存档记录(已测试)
    174 void Snake_class::ShowRecord(){
    175     COORD cd = { info.srWindow.Right/2-12, 8 };
    176     //输出记录
    177     std::ifstream inopen;
    178     SetConsoleCursorPosition( handle, cd );
    179     for( size_t i=0;i<sizeof(Snake_Record)/sizeof(*Snake_Record);++i ){
    180         inopen.open( *(Snake_Record+i) );
    181         if( !inopen || (inopen.get() == EOF && i==0) ){
    182             Show_not();
    183             pSnake->ID_option = ID_7;//第7个选项标记,在按回车时检测下
    184             return;
    185         }
    186         if( inopen.get() != EOF ){
    187             UINT _rank, _mark;
    188             inopen>>_mark;
    189             ++(_mark *= 2);
    190             while( _mark-- )
    191                 inopen>>_rank;
    192             inopen>>_mark;
    193             switch( _rank ){
    194                 case first:
    195                     std::cout<<"初级"; break;
    196                 case middle:
    197                     std::cout<<"中级"; break;
    198                 case high:
    199                     std::cout<<"高级"; break;
    200             }
    201             std::cout<<"			  "<<_mark;            
    202         }else
    203             std::cout<<" ---			  ---"; 
    204 
    205         cd.Y += 2;
    206         SetConsoleCursorPosition( handle, cd );
    207         inopen.close();
    208         inopen.clear();//重置流状态
    209     }
    210     std::cout<<"	   返 回 菜 单";
    211     cd.X = info.srWindow.Right/2-4; 
    212     cd.Y = 4;
    213     SetConsoleCursorPosition( handle, cd );
    214     std::cout<<"存 档 记 录";
    215     cd.X -=10;
    216     cd.Y +=2;
    217     SetConsoleCursorPosition( handle, cd );
    218     std::cout<<"游戏等级		当前分数";
    219     //输出指针
    220     cd.X = info.srWindow.Right/2-14;
    221     cd.Y = 8;
    222     switch( pSnake->ID_option ){
    223         case ID_1:
    224             break;
    225         case ID_2:
    226             cd.Y +=2; break;
    227         case ID_3:
    228             cd.Y +=4; break;
    229         case ID_4:
    230             cd.Y +=6; break;
    231         case ID_5:
    232             cd.Y +=8; break;
    233         case ID_6:
    234             cd.Y +=10;break;
    235     }
    236     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
    237 }
    238 
    239 //读取记录
    240 bool Snake_class::Read( size_t i ){
    241     std::ifstream inopen( *(Snake_Record+i) );
    242     if( inopen.get() == EOF ){
    243         std::cout<<"a";
    244         inopen.close();
    245         return false;
    246     }
    247     inopen>>pSnake->Snake_size;
    248     COORD cd;
    249     pSnake->Snake_coord.clear();
    250     for( int n=1;n<=pSnake->Snake_size;++n ){
    251         inopen>>cd.X>>cd.Y ;
    252         pSnake->Snake_coord.push_back( cd );
    253     }
    254     inopen>>pSnake->rank>>pSnake->mark>>pSnake->key;
    255     inopen.close();
    256     inopen.clear();
    257     return true;
    258 }
    259 
    260 //显示英雄榜(未测试)
    261 void Snake_class::ShowArmory(){
    262     short nt=0;
    263     COORD cd = { info.srWindow.Right/3, info.srWindow.Bottom/3 };
    264     std::ifstream inopen;
    265     for( size_t i=0;i<sizeof(S_Armory)/sizeof(*S_Armory);++i ){
    266         UINT _rank=0, _mark=0;
    267         inopen.open( *(S_Armory+i) );
    268         if( !inopen ){
    269             ++nt;
    270             continue;
    271         }
    272         inopen>>_rank>>_mark;
    273         switch( _rank ){
    274             case first:
    275                 SetConsoleCursorPosition( handle, cd );
    276                 std::cout<<"小牛 :初级		  "<<_mark;
    277                 break;
    278             case middle:
    279                 cd.Y +=2;
    280                 SetConsoleCursorPosition( handle, cd );
    281                 std::cout<<"中牛 :中级		  "<<_mark;
    282                 break;
    283             case high:
    284                 cd.Y +=2;
    285                 SetConsoleCursorPosition( handle, cd );
    286                 std::cout<<"大牛 :高级		  "<<_mark;
    287                 break;
    288         }
    289         inopen.close();
    290         inopen.clear();
    291     }
    292     if( nt == 3 ){
    293         Show_not();
    294         return;
    295     }
    296     cd.X = info.srWindow.Right/2-3;
    297     cd.Y = 4;
    298     SetConsoleCursorPosition( handle, cd );
    299     std::cout<<"英 雄 榜";
    300     cd.X -=10;
    301     cd.Y +=2;
    302     SetConsoleCursorPosition( handle,cd );
    303     std::cout<<"	等 级		分 数"; 
    304     cd.Y = info.srWindow.Bottom-7;
    305     SetConsoleCursorPosition( handle, cd );
    306     std::cout<<"按回车返回主菜单........";
    307 }
    308 
    309 //死亡界面(未测试)
    310 void Snake_class::Die(){
    311     COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
    312     SetConsoleCursorPosition( handle, cd );
    313     std::cout<<"    您 已 x_x 了 !";
    314     char *str[] = { "返 回 菜 单",
    315                     "退 出 游 戏" };
    316 //输出菜单选项
    317     short X = info.srWindow.Right/2;
    318     cd.X = X/2-5 ;
    319     cd.Y = info.srWindow.Bottom/3*2-4;
    320     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
    321         SetConsoleCursorPosition( handle, cd );
    322         std::cout<<*(str+i);
    323         cd.X += X;
    324     }
    325 
    326 //判断指针应指向的菜单选项
    327     switch( pSnake->ID_option ){
    328         case ID_1:
    329             cd.X = X/2-7; break;
    330         case ID_2:
    331             cd.X = X/2+X-7; break;
    332     }
    333     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
    334     if( Jesus() ){
    335         cd.X = X/2;
    336         cd.Y = info.srWindow.Bottom/3;
    337         SetConsoleCursorPosition( handle, cd );
    338         std::cout<<"哟...这分? ╮(╯▽╰)╭ 也能上榜。。。!";
    339         cd.Y +=2;
    340         SetConsoleCursorPosition( handle, cd );
    341         std::cout<<"上榜等级:";
    342         switch( pSnake->rank ){
    343             case first:
    344                 std::cout<<"初级"; break;
    345             case middle:
    346                 std::cout<<"中级"; break;
    347             case high:
    348                 std::cout<<"高级"; break;
    349         }
    350         std::cout<<"	上榜分数:"<<pSnake->mark;
    351     }
    352 }
    353 
    354 //存储记录文件(完成未测试)
    355 size_t Snake_class::Create_file(){
    356     std::ifstream inopen;
    357     size_t fn=0, fc=0, iend = sizeof(Snake_Record)/sizeof(*Snake_Record);
    358     //判断文件是否存在或文件已被存满
    359     for( size_t i=0;i<iend;++i ){
    360         inopen.open( *(Snake_Record+i) );
    361         if( !inopen ) ++fn;
    362         else if( inopen.get() == EOF ){  
    363             inopen.close(); 
    364             return i; 
    365         }
    366         else { ++fc; inopen.close(); }
    367     }
    368     if( fn == iend || fc == iend ){
    369             std::ofstream outopen;
    370                    //创建文本
    371             for( size_t i=0;i<iend;++i ){
    372                 outopen.open( *(Snake_Record+i) );
    373                 outopen.close(); 
    374             }
    375     } 
    376     //返回打开成功的文件索引
    377     return 0 ;
    378 }
    379 
    380 //判断死亡(未测试)
    381 void Snake_class::JudgeDie(){
    382     std::vector<COORD>::iterator hbeg = pSnake->Snake_coord.begin(),
    383         beg = hbeg+1;
    384     while( beg != pSnake->Snake_coord.end() ){
    385         if( beg->X == hbeg->X && beg->Y == hbeg->Y ){
    386             pSnake->state = FALSE;
    387             return;
    388         }
    389         ++beg;
    390     }
    391     COORD cd;
    392     if(hbeg->X <= 0 || hbeg->Y <= 0 ||
    393         hbeg->X >=info.srWindow.Right || hbeg->Y >= info.srWindow.Bottom-5 ){
    394             if( pSnake->Snake_size < 40 ){
    395                 pSnake->state = FALSE;
    396                 return;
    397             }
    398             //如果达到了40级可以穿墙
    399             switch( pSnake->key ){
    400                 case VK_UP:
    401                     cd.X = pSnake->Snake_coord.begin()->X ;
    402                     cd.Y = info.srWindow.Bottom-6;
    403                     break;
    404                 case VK_DOWN:
    405                     cd.X = pSnake->Snake_coord.begin()->X ;
    406                     cd.Y = 1;
    407                     break;
    408                 case VK_LEFT:
    409                     cd.X = info.srWindow.Right-1;
    410                     cd.Y = pSnake->Snake_coord.begin()->Y ;
    411                     break;
    412                 case VK_RIGHT:
    413                     cd.X = 1;
    414                     cd.Y = pSnake->Snake_coord.begin()->Y ;
    415                     break;
    416             }
    417             ShowSnake( cd );
    418     }
    419 }
    420 
    421 //上榜判断(未测试)
    422 bool Snake_class::Jesus(){
    423     std::ifstream inopen;
    424     size_t i;
    425     //判断相应等级打开相应文件
    426     switch( pSnake->rank ){
    427         case first:
    428             i=0; break;
    429         case middle:
    430             i=1; break;
    431         case high:
    432             i=2; break;
    433     }
    434     inopen.open( *(S_Armory+i) );
    435     if( inopen ){
    436         UINT _mark;
    437         inopen>>_mark>>_mark;
    438         if( _mark >= pSnake->mark ){
    439             inopen.close();
    440             return FALSE;
    441         }
    442     }
    443     std::ofstream outopen( *(S_Armory+i) );//创建文件并输入
    444     if( !outopen ){
    445         std::cerr<<"打开英雄榜文件出错"<<std::endl;
    446         exit(0);
    447     }
    448     outopen<<pSnake->rank<<" "<<pSnake->mark;
    449     outopen.close();
    450     return TRUE;
    451 }
    452 //显示蛇(未测试)
    453 void Snake_class::ShowSnake( COORD& cd){
    454     if( cd.X == pSnake->food_coord.X && cd.Y == pSnake->food_coord.Y ){
    455             //在最后添加一个坐标
    456         pSnake->Snake_coord.push_back( *(pSnake->Snake_coord.rbegin()) );
    457         pSnake->food_coord.X = pSnake->food_coord.Y = 0;//标志食物已被吃掉
    458         ++pSnake->mark;
    459         ++pSnake->Snake_size;
    460     }
    461     COORD cod;
    462     cod.X = (pSnake->Snake_coord.rbegin())->X ;
    463     cod.Y = (pSnake->Snake_coord.rbegin())->Y ;
    464     std::vector<COORD>::reverse_iterator rbeg = pSnake->Snake_coord.rbegin();
    465     while( rbeg != pSnake->Snake_coord.rend()-1 ){
    466         rbeg->X = (rbeg+1)->X ;
    467         rbeg->Y = (rbeg+1)->Y ;
    468         ++rbeg;
    469     }
    470     //显示蛇
    471     pSnake->Snake_coord.begin()->X = cd.X ;
    472     pSnake->Snake_coord.begin()->Y = cd.Y ;
    473     for( std::vector<COORD>::iterator beg = pSnake->Snake_coord.begin();
    474         beg != pSnake->Snake_coord.end();++beg ){
    475             SetConsoleCursorPosition( handle, *beg );
    476             std::cout<<"*";
    477     }
    478     SetConsoleCursorPosition( handle,cod );
    479     std::cout<<" ";
    480 }
    481 
    482 //显示指针(完成)
    483 inline void Snake_class::ShowPointer( COORD cd,std::string str ){
    484     SetConsoleCursorPosition( handle, cd );
    485     std::cout<<str[0];
    486     pSnake->ID_interface != ID_6?cd.X += 14:cd.X = info.srWindow.Right/3*2+3;
    487     SetConsoleCursorPosition( handle, cd );
    488     std::cout<<str[1];
    489 }
    490 
    491 //显示无数据(完成)
    492 inline void Snake_class::Show_not(){
    493     COORD cd = { info.srWindow.Right/2-4 ,info.srWindow.Bottom/2 };
    494     SetConsoleCursorPosition( handle, cd );
    495     std::cout<<"无 数 据 !";
    496     cd.X -= 6;
    497     cd.Y += 2;
    498     SetConsoleCursorPosition( handle, cd );
    499     std::cout<<"请按回车返回主菜单......";
    500 }

    main.cpp :

      1 #include<iostream>
      2 #include<direct.h>
      3 #include"Snake_Class.h"
      4 
      5 #define _max(ID) --snake.ID_option < ID_1?ID : snake.ID_option
      6 #define _min(ID) ++snake.ID_option > ID?ID_1 : snake.ID_option
      7 
      8 //钩子过程
      9 LRESULT CALLBACK _HookProc(int,WPARAM,LPARAM);
     10 
     11 void Wall();       //画墙函数
     12 void Frame();      //画框函数
     13 void initialize_();//初始化蛇结构数据
     14 
     15 Snake_data snake;
     16 Snake_class csnake(&snake);
     17 static HANDLE handle;  //控制台句柄
     18 //控制台信息结构
     19 static CONSOLE_SCREEN_BUFFER_INFO info ;
     20 
     21 int main(){
     22     using namespace std;
     23         //获取输出缓冲区句柄
     24     handle = GetStdHandle(STD_OUTPUT_HANDLE); 
     25     //获取相关信息(主要是缓冲区大小)
     26     GetConsoleScreenBufferInfo( handle, &info );
     27     initialize_();
     28     _mkdir( "d://SnakeRecord" ); //创建目录
     29 
     30     CONSOLE_CURSOR_INFO cursor;           //光标结构 
     31     cursor.dwSize = 10;
     32     cursor.bVisible = 0;                  //0为隐藏光标
     33     SetConsoleCursorInfo(handle, &cursor);//设置隐藏光标函数 
     34 
     35     //csnake.ShowMenu();
     36     HHOOK hook;
     37     MSG msg;
     38     //相应的钩子有相应的过程函数MSDN中可看,安装键盘钩子 
     39     hook = SetWindowsHookEx(WH_KEYBOARD_LL,_HookProc,GetModuleHandle(NULL),0);
     40     while(1){
     41         //判断蛇是否还活着
     42         Wall();
     43         if( !snake.state && snake.ID_interface == ID_2 ){
     44                //csnake.Die();
     45                snake.ID_interface = ID_4;
     46                Frame();
     47         }
     48         if( snake.ID_interface == ID_2 ){
     49              csnake.StartGame();
     50              Sleep( snake.rank );
     51         }
     52         if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ){//循环接收消息
     53                TranslateMessage(&msg);
     54                DispatchMessage(&msg);
     55         }
     56     }
     57 
     58     UnhookWindowsHookEx( hook );    //卸载钩子 
     59     return 0;
     60 }
     61 
     62 //定义钩子过程(未完成)
     63 LRESULT CALLBACK _HookProc(int message, WPARAM wParam, LPARAM lParam){
     64     //判断是否弹起按键消息
     65     if( wParam == WM_KEYUP){
     66         bool state = true;
     67             switch(((LPKBDLLHOOKSTRUCT) lParam)->vkCode){//lParam:指向一个结构 
     68                 //按下上键
     69                 case VK_UP:              
     70                     switch( snake.ID_interface ){
     71                         case ID_1:
     72                             snake.Flag = true;
     73                             csnake.ShowMenu();
     74                             snake.Flag = false;
     75                             snake.ID_option = _max( ID_5 );
     76                             csnake.ShowMenu();
     77                             break;
     78                         case ID_2:
     79                             if( snake.key != VK_DOWN && snake.key != VK_UP ){
     80                                 snake.key = VK_UP;
     81                             }
     82                             break;
     83                         case ID_5:
     84                             snake.Flag = true;
     85                             csnake.ShowRank();
     86                             snake.ID_option = _max( ID_3 );
     87                             snake.Flag = false;
     88                             csnake.ShowRank();
     89                             break;
     90                         case ID_6:
     91                             snake.Flag = true;
     92                             csnake.ShowRecord();
     93                             snake.ID_option = _max( ID_6 );
     94                             snake.Flag = false;
     95                             csnake.ShowRecord();
     96                             break;
     97                     }
     98                     break;
     99                     //按下下键
    100                 case VK_DOWN:
    101                     switch( snake.ID_interface ){
    102                         case ID_1:
    103                             snake.Flag = true;
    104                             csnake.ShowMenu();
    105                             snake.Flag = false;
    106                             snake.ID_option = _min( ID_5 );
    107                             csnake.ShowMenu();
    108                             break;
    109                         case ID_2:
    110                             if( snake.key != VK_UP && snake.key != VK_DOWN ){
    111                                 snake.key = VK_DOWN;
    112                             }
    113                             break;
    114                         case ID_5:
    115                             snake.Flag = true;
    116                             csnake.ShowRank();
    117                             snake.ID_option = _min( ID_3 );
    118                             snake.Flag = false;
    119                             csnake.ShowRank();
    120                             break;
    121                         case ID_6:
    122                             snake.Flag = true;
    123                             csnake.ShowRecord();
    124                             snake.ID_option = _min( ID_6 );
    125                             snake.Flag = false;
    126                             csnake.ShowRecord();
    127                             break;
    128                     }
    129                     break;
    130                     //按下左键
    131                 case VK_LEFT:
    132                     switch( snake.ID_interface ){
    133                         case ID_2:
    134                             if( snake.key != VK_RIGHT && snake.key != VK_LEFT ){
    135                                 snake.key = VK_LEFT;
    136                             }
    137                             break;
    138                         case ID_3:
    139                             snake.Flag = true;
    140                             csnake.ShowPause();
    141                             snake.ID_option = _max( ID_3 );
    142                             snake.Flag = false;
    143                             csnake.ShowPause();
    144                             break;
    145                         case ID_4:
    146                             snake.Flag = true;
    147                             csnake.Die();
    148                             snake.ID_option = _max( ID_2 );
    149                             snake.Flag = false;
    150                             csnake.Die();
    151                             break;
    152                     }
    153                     break;
    154                     //按下右键
    155                  case VK_RIGHT:
    156                      switch( snake.ID_interface ){
    157                         case ID_2:
    158                             if( snake.key != VK_LEFT && snake.key != VK_RIGHT ){
    159                                 snake.key = VK_RIGHT;
    160                             }
    161                             break;
    162                         case ID_3:
    163                             snake.Flag = true;
    164                             csnake.ShowPause();
    165                             snake.ID_option = _min( ID_3 );
    166                             snake.Flag = false;
    167                             csnake.ShowPause();
    168                             break;
    169                         case ID_4:
    170                             snake.Flag = true;
    171                             csnake.Die();
    172                             snake.ID_option = _min( ID_2 );
    173                             snake.Flag = false;
    174                             csnake.Die();
    175                             break;
    176                      }
    177                      break;
    178                      //按下空格和回车键
    179                  case VK_SPACE:
    180                  case VK_RETURN:
    181                      system( "cls" );
    182                      switch( snake.ID_interface ){
    183                         case ID_1://主菜单界面
    184                             switch( snake.ID_option ){
    185                                  case ID_1:
    186                                      snake.ID_interface = ID_2;//开始游戏界面ID
    187                                      csnake.StartGame();
    188                                      break;
    189                                  case ID_2:
    190                                      snake.ID_interface = ID_5;//等级界面
    191                                      snake.ID_option = ID_1;
    192                                      Frame();
    193                                      //csnake.ShowRank();
    194                                      break;
    195                                  case ID_3:
    196                                      snake.ID_interface = ID_6;//读取记录界面
    197                                      snake.ID_option = ID_1;
    198                                      csnake.ShowRecord();
    199                                      break;
    200                                  case ID_4:
    201                                      snake.ID_interface = ID_7;//英雄榜界面
    202                                      csnake.ShowArmory();
    203                                      break;
    204                                  case ID_5:
    205                                      state = false;
    206                                      break;
    207                             }
    208                             break;
    209 
    210                         case ID_2://游戏界面
    211                             snake.ID_interface = ID_3;
    212                             snake.ID_option = ID_1;
    213                             Frame();
    214                             //csnake.ShowPause();
    215                             break;
    216 
    217                         case ID_3://暂停界面
    218                             switch( snake.ID_option ){
    219                                  case ID_1:
    220                                      snake.ID_interface = ID_2;
    221                                      csnake.StartGame();
    222                                      break;
    223                                  case ID_2:
    224                                      csnake.SaveRecord();
    225                                      break;
    226                                  case ID_3:
    227                                      state = false;
    228                                      break;
    229                             }
    230                             break;
    231 
    232                         case ID_4://死亡界面
    233                             switch( snake.ID_option ){
    234                                  case ID_1:
    235                                      snake.ID_interface = ID_1;
    236                                      snake.ID_option = ID_1;
    237                                      initialize_();
    238                                      csnake.ShowMenu();
    239                                      break;
    240                                  case ID_2:
    241                                      state = false;
    242                                      break;
    243                             }
    244                             break;
    245 
    246                         case ID_5://等级界面
    247                             switch( snake.ID_option ){
    248                                  case ID_1:
    249                                      snake.rank = first;
    250                                      break;
    251                                  case ID_2:
    252                                      snake.rank = middle;
    253                                      break;
    254                                  case ID_3:
    255                                      snake.rank = high;
    256                                      break;
    257                             }
    258                             snake.ID_interface = ID_1;
    259                             snake.ID_option = ID_1;
    260                             csnake.ShowMenu();
    261                             break;
    262 
    263                         case ID_6://读取界面
    264                             size_t id;
    265                             switch( snake.ID_option ){
    266                                  case ID_1:
    267                                      id = 0; break;
    268                                  case ID_2:
    269                                      id = 1; break;
    270                                  case ID_3:
    271                                      id = 2; break;
    272                                  case ID_4:
    273                                      id = 3; break;
    274                                  case ID_5:
    275                                      id = 4; break;
    276                             }
    277                             //进行读取文件
    278                             if( snake.ID_option != ID_6&&snake.ID_option != ID_7 ){
    279                                      initialize_();
    280                                      if( csnake.Read( id ) ){
    281                                          snake.ID_interface = ID_2;
    282                                          csnake.StartGame();
    283                                      }
    284                                      else snake.ID_interface = ID_6;
    285                             }
    286                             else {
    287                                      snake.ID_interface = ID_1;
    288                                      snake.ID_option = ID_1;
    289                                      csnake.ShowMenu();
    290                             }
    291                             break;
    292 
    293                         case ID_7://英雄榜界面
    294                             snake.ID_interface = ID_1;
    295                             snake.ID_option = ID_1;
    296                             csnake.ShowMenu();
    297                             break;
    298                      }
    299                      if( !state ){
    300                          COORD cd = { info.srWindow.Right/4, info.srWindow.Bottom/5*4 };
    301                          SetConsoleCursorPosition( handle,cd );
    302                          exit(0);
    303                      }
    304                      snake.ID_option = ID_1;
    305                     break;
    306             }
    307     }
    308           //消息传给下个钩子
    309           return CallNextHookEx ( NULL, message, wParam, lParam );
    310 }
    311 
    312 //画墙函数和调用相应界面(已测试完成)
    313 void Wall(){
    314     short i;
    315     COORD coord = { 0,0 };  //坐标结构
    316 //绘墙
    317     SetConsoleCursorPosition( handle, coord );
    318     for( i=0;i<=info.srWindow.Right;++i )
    319             std::cout<<"#";
    320 
    321     coord.X = info.srWindow.Right;
    322     coord.Y = 1;
    323     for( i=1;i<info.srWindow.Bottom;++i ){
    324         SetConsoleCursorPosition( handle, coord );
    325         std::cout<<"#";
    326         ++coord.Y ;
    327     }
    328 
    329     coord.X = 0;
    330     coord.Y = info.srWindow.Bottom;
    331     for( i=1;i<=info.srWindow.Right;++i ){
    332         SetConsoleCursorPosition( handle, coord );
    333         std::cout<<"#";
    334         ++coord.X ;
    335     }
    336 
    337     coord.X = 0;
    338     coord.Y = 1;
    339     for( i=1;i<info.srWindow.Bottom;++i ){
    340         SetConsoleCursorPosition( handle, coord );
    341         std::cout<<"#";
    342         ++coord.Y ;
    343     }
    344 //判断所在界面显示相关界面的菜单选项及其它
    345     int j = info.srWindow.Right/4;
    346     switch( snake.ID_interface ){
    347         case ID_1:
    348             csnake.ShowMenu(); 
    349             coord.X = j;
    350             coord.Y = info.srWindow.Bottom-6;
    351             SetConsoleCursorPosition( handle, coord );
    352             std::cout<<"o(-"-)o  贪  #^_^#  吃  →_→  蛇  \(^o^)/";
    353             break;//显示菜单选项
    354 
    355         case ID_2:
    356         case ID_3:
    357         case ID_4:
    358             //绘输出信息框
    359             coord.X = 1;
    360             coord.Y = info.srWindow.Bottom - 5;
    361             SetConsoleCursorPosition( handle, coord );
    362             for( i=1;i<info.srWindow.Right; std::cout<<"#", ++i );
    363             for( coord.X=j;coord.X<=info.srWindow.Right-j;coord.X+=j ){
    364                 coord.Y = info.srWindow.Bottom - 5;
    365                 for( i=coord.Y;i<info.srWindow.Bottom;++i ){
    366                         SetConsoleCursorPosition( handle, coord );
    367                         std::cout<<"#";
    368                         ++coord.Y ;
    369                 }
    370             }
    371             //输出每个框的信息
    372             coord.X = 2;
    373             coord.Y-= 4;
    374             SetConsoleCursorPosition( handle, coord );
    375             std::cout<<"游戏难度:";
    376             coord.Y +=2;
    377             SetConsoleCursorPosition( handle, coord );
    378             std::cout<<"	   ";
    379             switch( snake.rank ){
    380                   case first:
    381                       std::cout<<"初 级"; break;
    382                   case middle:
    383                       std::cout<<"中 级"; break;
    384                   case high:
    385                       std::cout<<"高 级"; break;
    386             }
    387       //当前分数
    388             coord.X += j;
    389             coord.Y -= 2;
    390             SetConsoleCursorPosition( handle, coord );
    391             std::cout<<"  当 前 分 数";
    392             coord.X +=j/2-3;
    393             coord.Y +=2;
    394             SetConsoleCursorPosition( handle, coord );
    395             std::cout<<snake.mark ;
    396       //操作说明
    397             coord.X = j*2+1;
    398             coord.Y = info.srWindow.Bottom -4;
    399             SetConsoleCursorPosition( handle, coord );
    400             std::cout<<" 操作说明: ";
    401             coord.Y +=2;
    402             SetConsoleCursorPosition( handle, coord );
    403             std::cout<<"  ↑ ↓ ←  →";
    404             ++coord.Y; 
    405             SetConsoleCursorPosition( handle, coord );
    406             std::cout<<" 空格: 暂停游戏";
    407       //制作人
    408             coord.X += j;
    409             SetConsoleCursorPosition( handle, coord );
    410             std::cout<<"	制作人: _ 翼";
    411             break;
    412 
    413         case ID_5:
    414             csnake.ShowRank(); break;//显示游戏等级
    415 
    416         case ID_6:
    417             csnake.ShowRecord(); break;//显示存档记录
    418 
    419         case ID_7:
    420             csnake.ShowArmory(); break;//显示英雄榜
    421     }
    422 
    423 }
    424 
    425 //画框函数(完成)
    426 void Frame(){
    427     COORD coord = { 0, info.srWindow.Bottom/3 };
    428     SetConsoleCursorPosition( handle, coord );
    429     for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
    430         
    431     coord.Y = info.srWindow.Bottom/3*2;
    432     SetConsoleCursorPosition( handle, coord );
    433     for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
    434         
    435     switch( snake.ID_interface ){
    436         case ID_3:
    437             csnake.ShowPause(); break;//显示暂停菜单
    438         case ID_4:
    439             csnake.Die(); break;//显示死亡界面菜单
    440         case ID_5:
    441             csnake.ShowRank(); break;//显示等级选项
    442     }
    443 }
    444 
    445 //初始化蛇数据(完成)
    446 void initialize_(){
    447     snake.state = true; //蛇状态
    448     snake.Snake_size = 5; //蛇初始化长度
    449     //初始化蛇位置
    450     COORD cd;
    451     cd.Y = 3;
    452     snake.Snake_coord.clear();
    453     for( size_t i=10;i>5;--i ){
    454         cd.X = i;
    455         snake.Snake_coord.push_back( cd );
    456     }
    457     snake.food_coord.X = 0;
    458     snake.food_coord.Y = 0;
    459     snake.rank = first;   //默认等级
    460     snake.mark = 0; //分数
    461     snake.key = VK_RIGHT; 
    462     snake.ID_interface = ID_1;//界面标记
    463     snake.ID_option = ID_1;   //选项标记
    464     snake.Flag = false;
    465 }
  • 相关阅读:
    订阅发布模式概念基础
    HTML与CSS之display:none
    HTML与CSS之导航栏
    微信小程序-笔记
    基于设计模式的用户管理
    微信小程序-开发组件-笔记1
    JavaScript异常处理
    微信小程序开发-笔记
    封装类实现增删改查
    脚本方式实现数据库增删改查
  • 原文地址:https://www.cnblogs.com/sosoft/p/3508072.html
Copyright © 2020-2023  润新知