贪吃蛇代码

该代码转自一位博友,传送门:http://www.cnblogs.com/sosoft/p/3508072.html

Snake_Class.h文件:

#ifndef SNAKE
#define SNAKE

#include<windows.h>
#include<vector>
#include<string>

//标记界面和菜单项的ID
enum ID_ { ID_1=1, ID_2, ID_3, ID_4, ID_5, ID_6, ID_7 };

//标记初级,中级,高级三种游戏等级
enum Rank_ { first=150, middle=100, high=50 };


//贪吃蛇结构   http://www.cnblogs.com/sosoft/
struct Snake_data{
    bool state ;                    //标记蛇状态
    UINT Snake_size;                //标记蛇长度
    std::vector<COORD> Snake_coord; //蛇的当前坐标
    COORD food_coord;               //食物坐标
    UINT rank;                     //标记等级
    UINT mark;                      //分数
    UINT key;                       //记录按键方向
    ID_ ID_interface;               //标记当前停留界面ID
    short ID_option ;               //标记被选中菜单的ID
    bool Flag;                      //标记刷新
};

//贪吃蛇类
class Snake_class{
public:
    Snake_class(){}
    Snake_class(Snake_data *data): pSnake(data){}
    void ShowMenu();            //显示菜单
    void StartGame() ;          //开始游戏
    void ShowPause();           //显示暂停界面
    void SaveRecord();          //保存记录
    void ShowRank();            //显示等级
    void ShowRecord();          //显示存档记录列表
    bool Read( size_t );        //读取记录
    void ShowArmory();          //显示英雄榜
    void Die();                 //死亡界面
    size_t Create_file();       //存储文件
private:
    void JudgeDie();            //判断死亡
    bool Jesus();               //上榜判断
    void ShowSnake( COORD& );   //显示蛇
    void ShowPointer( COORD,std::string ); //显示指针
    void Show_not();            //显示无数据
    Snake_data *pSnake;
};



#endif;

Snake_class.cpp:

#include"Snake_Class.h"
#include<iostream>
#include<fstream>
#include<ctime>
#include<cstdlib>

//获取缓冲区句柄
static const HANDLE handle = GetStdHandle( STD_OUTPUT_HANDLE );
static CONSOLE_SCREEN_BUFFER_INFO info ;
//保存蛇的记录数据文件
static const char *Snake_Record[] = { "d://SnakeRecord//Snake1.txt",
                                      "d://SnakeRecord//Snake2.txt",
                                      "d://SnakeRecord//Snake3.txt",
                                      "d://SnakeRecord//Snake4.txt",
                                      "d://SnakeRecord//Snake5.txt" };

static const char *S_Armory[] = { "d://SnakeRecord//Armory1.txt",
                                  "d://SnakeRecord//Armory2.txt",
                                  "d://SnakeRecord//Armory3.txt" };
//显示主菜单(完成已测试)
void Snake_class::ShowMenu(){
    //获取缓冲区相关信息
    GetConsoleScreenBufferInfo( handle, &info );
    char *str[] = {"开 始 游 戏",
                   "难 度 等 级",
                   "读 取 存 档",
                   "英 雄 榜",
                   "退 出 游 戏"};
    //输出菜单选项
    short y = 3;
    COORD cd = { info.srWindow.Right/2 - 5, y };
    for( size_t n=0;n<sizeof(str)/sizeof(*str);++n ){
        SetConsoleCursorPosition( handle, cd );
        std::cout<<*(str+n);
        cd.Y += 2;
    }
//判断指针指向哪个菜单选项
    cd.X -= 2;
    cd.Y  = y;
    switch( pSnake->ID_option ){
        case ID_1:
            break;
        case ID_2:
            cd.Y = y+2; break;
        case ID_3:
            cd.Y = y+4; break;
        case ID_4:
            cd.Y = y+6; break;
        case ID_5:
            cd.Y = y+8; break;
    }
    ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
}

//开始游戏(完成待测试)
void Snake_class::StartGame(){
    COORD cd;
    //判断是否已有食物
    if( !pSnake->food_coord.X ){
        srand((unsigned int)time(NULL));
        while(1){
            //限制食物出现的坐标不与围墙相同
              ++( cd.X = rand()%78 ); 
              ++( cd.Y = rand()%18 );
            //判断食物坐标是否与蛇身吻合
            std::vector<COORD>::iterator ite;
            for( ite=pSnake->Snake_coord.begin(); ite!=pSnake->Snake_coord.end(); ++ite ){
                    if( ite->X == cd.X && ite->Y == cd.Y )
                        break;
            }
            if( ite == pSnake->Snake_coord.end() ){
                pSnake->food_coord.X = cd.X ;
                pSnake->food_coord.Y = cd.Y ;
                break;
            }
        }
    }
    SetConsoleCursorPosition( handle, pSnake->food_coord );
    std::cout<<"*";
    //判定按键方向
    cd.X  = pSnake->Snake_coord.begin()->X;
    cd.Y = pSnake->Snake_coord.begin()->Y ;
    switch( pSnake->key ){
        case VK_UP:
            --cd.Y; break;
        case VK_DOWN:
            ++cd.Y; break;
        case VK_LEFT:
            --cd.X; break;
        case VK_RIGHT:
            ++cd.X; break;
    }
    ShowSnake( cd );
    JudgeDie();
}

//显示暂停界面(完成已测试)
void Snake_class::ShowPause(){
    COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"游 戏 暂 停 中 ......";
    char *str[] = { "继 续 游 戏",
                    "保 存 游 戏",
                    "退 出 游 戏" };
//输出菜单选项
    short X = info.srWindow.Right/3;
    cd.X = X/2-5 ;
    cd.Y = info.srWindow.Bottom/3*2-4;
    for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
        SetConsoleCursorPosition( handle, cd );
        std::cout<<*(str+i);
        cd.X += X;
    }

//判断指针应指向的菜单选项
    switch( pSnake->ID_option ){
        case ID_1:
            cd.X = X/2-7; break;
        case ID_2:
            cd.X = X/2+X-7; break;
        case ID_3:
            cd.X = X/2+2*X-7; break;
    }
    ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
}

//保存记录(完成未测试)
void Snake_class::SaveRecord(){
    std::ofstream outopen;
    outopen.open( *( Snake_Record + Create_file() ) );
    if( !outopen ){
        std::cerr<<"\n打开文件失败!\n";
        exit(0);
    }
    //保存记录到文件中,前面加"0"是为了后面检测是否文件为空使用
    outopen<<"0 "<<pSnake->Snake_size<<" ";
    for(std::vector<COORD>::iterator ite=pSnake->Snake_coord.begin();
        ite!=pSnake->Snake_coord.end();++ite )
            outopen<<ite->X<<" "<<ite->Y<<" ";
    outopen<<pSnake->rank<<" "<<pSnake->mark<<" "<<pSnake->key;
    outopen.close();
//输出保存成功
    COORD cd = { info.srWindow.Right/2-4, info.srWindow.Bottom/3*2-1 };
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"保存成功!\a";
}

//显示等级(已测试)
void Snake_class::ShowRank(){
    COORD cd = { info.srWindow.Right/2-6, info.srWindow.Bottom/3+2 };
    char *str[] = { "初       级",
                    "中       级",
                    "高       级" };
    for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
        SetConsoleCursorPosition( handle, cd );
        std::cout<<*(str+i);
        cd.Y += 2;
    }
    //判断指针所停留的选项
    cd.X -= 2;
    cd.Y  = info.srWindow.Bottom/3+2;
    switch( pSnake->ID_option ){
        case ID_1:
            break;
        case ID_2:
            cd.Y += 2; break;
        case ID_3:
            cd.Y += 4; break;
    }
    ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
}

//显示存档记录(已测试)
void Snake_class::ShowRecord(){
    COORD cd = { info.srWindow.Right/2-12, 8 };
    //输出记录
    std::ifstream inopen;
    SetConsoleCursorPosition( handle, cd );
    for( size_t i=0;i<sizeof(Snake_Record)/sizeof(*Snake_Record);++i ){
        inopen.open( *(Snake_Record+i) );
        if( !inopen || (inopen.get() == EOF && i==0) ){
            Show_not();
            pSnake->ID_option = ID_7;//第7个选项标记,在按回车时检测下
            return;
        }
        if( inopen.get() != EOF ){
            UINT _rank, _mark;
            inopen>>_mark;
            ++(_mark *= 2);
            while( _mark-- )
                inopen>>_rank;
            inopen>>_mark;
            switch( _rank ){
                case first:
                    std::cout<<"初级"; break;
                case middle:
                    std::cout<<"中级"; break;
                case high:
                    std::cout<<"高级"; break;
            }
            std::cout<<"\t\t\t  "<<_mark;            
        }else
            std::cout<<" ---\t\t\t  ---"; 

        cd.Y += 2;
        SetConsoleCursorPosition( handle, cd );
        inopen.close();
        inopen.clear();//重置流状态
    }
    std::cout<<"\t   返 回 菜 单";
    cd.X = info.srWindow.Right/2-4; 
    cd.Y = 4;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"存 档 记 录";
    cd.X -=10;
    cd.Y +=2;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"游戏等级\t\t当前分数";
    //输出指针
    cd.X = info.srWindow.Right/2-14;
    cd.Y = 8;
    switch( pSnake->ID_option ){
        case ID_1:
            break;
        case ID_2:
            cd.Y +=2; break;
        case ID_3:
            cd.Y +=4; break;
        case ID_4:
            cd.Y +=6; break;
        case ID_5:
            cd.Y +=8; break;
        case ID_6:
            cd.Y +=10;break;
    }
    ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
}

//读取记录
bool Snake_class::Read( size_t i ){
    std::ifstream inopen( *(Snake_Record+i) );
    if( inopen.get() == EOF ){
        std::cout<<"\a";
        inopen.close();
        return false;
    }
    inopen>>pSnake->Snake_size;
    COORD cd;
    pSnake->Snake_coord.clear();
    for( int n=1;n<=pSnake->Snake_size;++n ){
        inopen>>cd.X>>cd.Y ;
        pSnake->Snake_coord.push_back( cd );
    }
    inopen>>pSnake->rank>>pSnake->mark>>pSnake->key;
    inopen.close();
    inopen.clear();
    return true;
}

//显示英雄榜(未测试)
void Snake_class::ShowArmory(){
    short nt=0;
    COORD cd = { info.srWindow.Right/3, info.srWindow.Bottom/3 };
    std::ifstream inopen;
    for( size_t i=0;i<sizeof(S_Armory)/sizeof(*S_Armory);++i ){
        UINT _rank=0, _mark=0;
        inopen.open( *(S_Armory+i) );
        if( !inopen ){
            ++nt;
            continue;
        }
        inopen>>_rank>>_mark;
        switch( _rank ){
            case first:
                SetConsoleCursorPosition( handle, cd );
                std::cout<<"小牛 :初级\t\t  "<<_mark;
                break;
            case middle:
                cd.Y +=2;
                SetConsoleCursorPosition( handle, cd );
                std::cout<<"中牛 :中级\t\t  "<<_mark;
                break;
            case high:
                cd.Y +=2;
                SetConsoleCursorPosition( handle, cd );
                std::cout<<"大牛 :高级\t\t  "<<_mark;
                break;
        }
        inopen.close();
        inopen.clear();
    }
    if( nt == 3 ){
        Show_not();
        return;
    }
    cd.X = info.srWindow.Right/2-3;
    cd.Y = 4;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"英 雄 榜";
    cd.X -=10;
    cd.Y +=2;
    SetConsoleCursorPosition( handle,cd );
    std::cout<<"\t等 级\t\t分 数"; 
    cd.Y = info.srWindow.Bottom-7;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"按回车返回主菜单........";
}

//死亡界面(未测试)
void Snake_class::Die(){
    COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"    您 已 x_x 了 !";
    char *str[] = { "返 回 菜 单",
                    "退 出 游 戏" };
//输出菜单选项
    short X = info.srWindow.Right/2;
    cd.X = X/2-5 ;
    cd.Y = info.srWindow.Bottom/3*2-4;
    for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
        SetConsoleCursorPosition( handle, cd );
        std::cout<<*(str+i);
        cd.X += X;
    }

//判断指针应指向的菜单选项
    switch( pSnake->ID_option ){
        case ID_1:
            cd.X = X/2-7; break;
        case ID_2:
            cd.X = X/2+X-7; break;
    }
    ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
    if( Jesus() ){
        cd.X = X/2;
        cd.Y = info.srWindow.Bottom/3;
        SetConsoleCursorPosition( handle, cd );
        std::cout<<"哟...这分? ╮(╯▽╰)╭ 也能上榜。。。!";
        cd.Y +=2;
        SetConsoleCursorPosition( handle, cd );
        std::cout<<"上榜等级:";
        switch( pSnake->rank ){
            case first:
                std::cout<<"初级"; break;
            case middle:
                std::cout<<"中级"; break;
            case high:
                std::cout<<"高级"; break;
        }
        std::cout<<"\t上榜分数:"<<pSnake->mark;
    }
}

//存储记录文件(完成未测试)
size_t Snake_class::Create_file(){
    std::ifstream inopen;
    size_t fn=0, fc=0, iend = sizeof(Snake_Record)/sizeof(*Snake_Record);
    //判断文件是否存在或文件已被存满
    for( size_t i=0;i<iend;++i ){
        inopen.open( *(Snake_Record+i) );
        if( !inopen ) ++fn;
        else if( inopen.get() == EOF ){  
            inopen.close(); 
            return i; 
        }
        else { ++fc; inopen.close(); }
    }
    if( fn == iend || fc == iend ){
            std::ofstream outopen;
                   //创建文本
            for( size_t i=0;i<iend;++i ){
                outopen.open( *(Snake_Record+i) );
                outopen.close(); 
            }
    } 
    //返回打开成功的文件索引
    return 0 ;
}

//判断死亡(未测试)
void Snake_class::JudgeDie(){
    std::vector<COORD>::iterator hbeg = pSnake->Snake_coord.begin(),
        beg = hbeg+1;
    while( beg != pSnake->Snake_coord.end() ){
        if( beg->X == hbeg->X && beg->Y == hbeg->Y ){
            pSnake->state = FALSE;
            return;
        }
        ++beg;
    }
    COORD cd;
    if(hbeg->X <= 0 || hbeg->Y <= 0 ||
        hbeg->X >=info.srWindow.Right || hbeg->Y >= info.srWindow.Bottom-5 ){
            if( pSnake->Snake_size < 40 ){
                pSnake->state = FALSE;
                return;
            }
            //如果达到了40级可以穿墙
            switch( pSnake->key ){
                case VK_UP:
                    cd.X = pSnake->Snake_coord.begin()->X ;
                    cd.Y = info.srWindow.Bottom-6;
                    break;
                case VK_DOWN:
                    cd.X = pSnake->Snake_coord.begin()->X ;
                    cd.Y = 1;
                    break;
                case VK_LEFT:
                    cd.X = info.srWindow.Right-1;
                    cd.Y = pSnake->Snake_coord.begin()->Y ;
                    break;
                case VK_RIGHT:
                    cd.X = 1;
                    cd.Y = pSnake->Snake_coord.begin()->Y ;
                    break;
            }
            ShowSnake( cd );
    }
}

//上榜判断(未测试)
bool Snake_class::Jesus(){
    std::ifstream inopen;
    size_t i;
    //判断相应等级打开相应文件
    switch( pSnake->rank ){
        case first:
            i=0; break;
        case middle:
            i=1; break;
        case high:
            i=2; break;
    }
    inopen.open( *(S_Armory+i) );
    if( inopen ){
        UINT _mark;
        inopen>>_mark>>_mark;
        if( _mark >= pSnake->mark ){
            inopen.close();
            return FALSE;
        }
    }
    std::ofstream outopen( *(S_Armory+i) );//创建文件并输入
    if( !outopen ){
        std::cerr<<"打开英雄榜文件出错"<<std::endl;
        exit(0);
    }
    outopen<<pSnake->rank<<" "<<pSnake->mark;
    outopen.close();
    return TRUE;
}
//显示蛇(未测试)
void Snake_class::ShowSnake( COORD& cd){
    if( cd.X == pSnake->food_coord.X && cd.Y == pSnake->food_coord.Y ){
            //在最后添加一个坐标
        pSnake->Snake_coord.push_back( *(pSnake->Snake_coord.rbegin()) );
        pSnake->food_coord.X = pSnake->food_coord.Y = 0;//标志食物已被吃掉
        ++pSnake->mark;
        ++pSnake->Snake_size;
    }
    COORD cod;
    cod.X = (pSnake->Snake_coord.rbegin())->X ;
    cod.Y = (pSnake->Snake_coord.rbegin())->Y ;
    std::vector<COORD>::reverse_iterator rbeg = pSnake->Snake_coord.rbegin();
    while( rbeg != pSnake->Snake_coord.rend()-1 ){
        rbeg->X = (rbeg+1)->X ;
        rbeg->Y = (rbeg+1)->Y ;
        ++rbeg;
    }
    //显示蛇
    pSnake->Snake_coord.begin()->X = cd.X ;
    pSnake->Snake_coord.begin()->Y = cd.Y ;
    for( std::vector<COORD>::iterator beg = pSnake->Snake_coord.begin();
        beg != pSnake->Snake_coord.end();++beg ){
            SetConsoleCursorPosition( handle, *beg );
            std::cout<<"*";
    }
    SetConsoleCursorPosition( handle,cod );
    std::cout<<" ";
}

//显示指针(完成)
inline void Snake_class::ShowPointer( COORD cd,std::string str ){
    SetConsoleCursorPosition( handle, cd );
    std::cout<<str[0];
    pSnake->ID_interface != ID_6?cd.X += 14:cd.X = info.srWindow.Right/3*2+3;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<str[1];
}

//显示无数据(完成)
inline void Snake_class::Show_not(){
    COORD cd = { info.srWindow.Right/2-4 ,info.srWindow.Bottom/2 };
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"无 数 据 !";
    cd.X -= 6;
    cd.Y += 2;
    SetConsoleCursorPosition( handle, cd );
    std::cout<<"请按回车返回主菜单......";
}

main.cpp :

#include<iostream>
#include<direct.h>
#include"Snake_Class.h"

#define _max(ID) --snake.ID_option < ID_1?ID : snake.ID_option
#define _min(ID) ++snake.ID_option > ID?ID_1 : snake.ID_option

//钩子过程
LRESULT CALLBACK _HookProc(int,WPARAM,LPARAM);

void Wall();       //画墙函数
void Frame();      //画框函数
void initialize_();//初始化蛇结构数据

Snake_data snake;
Snake_class csnake(&snake);
static HANDLE handle;  //控制台句柄
//控制台信息结构
static CONSOLE_SCREEN_BUFFER_INFO info ;

int main(){
    using namespace std;
        //获取输出缓冲区句柄
    handle = GetStdHandle(STD_OUTPUT_HANDLE); 
    //获取相关信息(主要是缓冲区大小)
    GetConsoleScreenBufferInfo( handle, &info );
    initialize_();
    _mkdir( "d://SnakeRecord" ); //创建目录

    CONSOLE_CURSOR_INFO cursor;           //光标结构 
    cursor.dwSize = 10;
    cursor.bVisible = 0;                  //0为隐藏光标
    SetConsoleCursorInfo(handle, &cursor);//设置隐藏光标函数 

    //csnake.ShowMenu();
    HHOOK hook;
    MSG msg;
    //相应的钩子有相应的过程函数MSDN中可看,安装键盘钩子 
    hook = SetWindowsHookEx(WH_KEYBOARD_LL,_HookProc,GetModuleHandle(NULL),0);
    while(1){
        //判断蛇是否还活着
        Wall();
        if( !snake.state && snake.ID_interface == ID_2 ){
               //csnake.Die();
               snake.ID_interface = ID_4;
               Frame();
        }
        if( snake.ID_interface == ID_2 ){
             csnake.StartGame();
             Sleep( snake.rank );
        }
        if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ){//循环接收消息
               TranslateMessage(&msg);
               DispatchMessage(&msg);
        }
    }

    UnhookWindowsHookEx( hook );    //卸载钩子 
    return 0;
}

//定义钩子过程(未完成)
LRESULT CALLBACK _HookProc(int message, WPARAM wParam, LPARAM lParam){
    //判断是否弹起按键消息
    if( wParam == WM_KEYUP){
        bool state = true;
            switch(((LPKBDLLHOOKSTRUCT) lParam)->vkCode){//lParam:指向一个结构 
                //按下上键
                case VK_UP:              
                    switch( snake.ID_interface ){
                        case ID_1:
                            snake.Flag = true;
                            csnake.ShowMenu();
                            snake.Flag = false;
                            snake.ID_option = _max( ID_5 );
                            csnake.ShowMenu();
                            break;
                        case ID_2:
                            if( snake.key != VK_DOWN && snake.key != VK_UP ){
                                snake.key = VK_UP;
                            }
                            break;
                        case ID_5:
                            snake.Flag = true;
                            csnake.ShowRank();
                            snake.ID_option = _max( ID_3 );
                            snake.Flag = false;
                            csnake.ShowRank();
                            break;
                        case ID_6:
                            snake.Flag = true;
                            csnake.ShowRecord();
                            snake.ID_option = _max( ID_6 );
                            snake.Flag = false;
                            csnake.ShowRecord();
                            break;
                    }
                    break;
                    //按下下键
                case VK_DOWN:
                    switch( snake.ID_interface ){
                        case ID_1:
                            snake.Flag = true;
                            csnake.ShowMenu();
                            snake.Flag = false;
                            snake.ID_option = _min( ID_5 );
                            csnake.ShowMenu();
                            break;
                        case ID_2:
                            if( snake.key != VK_UP && snake.key != VK_DOWN ){
                                snake.key = VK_DOWN;
                            }
                            break;
                        case ID_5:
                            snake.Flag = true;
                            csnake.ShowRank();
                            snake.ID_option = _min( ID_3 );
                            snake.Flag = false;
                            csnake.ShowRank();
                            break;
                        case ID_6:
                            snake.Flag = true;
                            csnake.ShowRecord();
                            snake.ID_option = _min( ID_6 );
                            snake.Flag = false;
                            csnake.ShowRecord();
                            break;
                    }
                    break;
                    //按下左键
                case VK_LEFT:
                    switch( snake.ID_interface ){
                        case ID_2:
                            if( snake.key != VK_RIGHT && snake.key != VK_LEFT ){
                                snake.key = VK_LEFT;
                            }
                            break;
                        case ID_3:
                            snake.Flag = true;
                            csnake.ShowPause();
                            snake.ID_option = _max( ID_3 );
                            snake.Flag = false;
                            csnake.ShowPause();
                            break;
                        case ID_4:
                            snake.Flag = true;
                            csnake.Die();
                            snake.ID_option = _max( ID_2 );
                            snake.Flag = false;
                            csnake.Die();
                            break;
                    }
                    break;
                    //按下右键
                 case VK_RIGHT:
                     switch( snake.ID_interface ){
                        case ID_2:
                            if( snake.key != VK_LEFT && snake.key != VK_RIGHT ){
                                snake.key = VK_RIGHT;
                            }
                            break;
                        case ID_3:
                            snake.Flag = true;
                            csnake.ShowPause();
                            snake.ID_option = _min( ID_3 );
                            snake.Flag = false;
                            csnake.ShowPause();
                            break;
                        case ID_4:
                            snake.Flag = true;
                            csnake.Die();
                            snake.ID_option = _min( ID_2 );
                            snake.Flag = false;
                            csnake.Die();
                            break;
                     }
                     break;
                     //按下空格和回车键
                 case VK_SPACE:
                 case VK_RETURN:
                     system( "cls" );
                     switch( snake.ID_interface ){
                        case ID_1://主菜单界面
                            switch( snake.ID_option ){
                                 case ID_1:
                                     snake.ID_interface = ID_2;//开始游戏界面ID
                                     csnake.StartGame();
                                     break;
                                 case ID_2:
                                     snake.ID_interface = ID_5;//等级界面
                                     snake.ID_option = ID_1;
                                     Frame();
                                     //csnake.ShowRank();
                                     break;
                                 case ID_3:
                                     snake.ID_interface = ID_6;//读取记录界面
                                     snake.ID_option = ID_1;
                                     csnake.ShowRecord();
                                     break;
                                 case ID_4:
                                     snake.ID_interface = ID_7;//英雄榜界面
                                     csnake.ShowArmory();
                                     break;
                                 case ID_5:
                                     state = false;
                                     break;
                            }
                            break;

                        case ID_2://游戏界面
                            snake.ID_interface = ID_3;
                            snake.ID_option = ID_1;
                            Frame();
                            //csnake.ShowPause();
                            break;

                        case ID_3://暂停界面
                            switch( snake.ID_option ){
                                 case ID_1:
                                     snake.ID_interface = ID_2;
                                     csnake.StartGame();
                                     break;
                                 case ID_2:
                                     csnake.SaveRecord();
                                     break;
                                 case ID_3:
                                     state = false;
                                     break;
                            }
                            break;

                        case ID_4://死亡界面
                            switch( snake.ID_option ){
                                 case ID_1:
                                     snake.ID_interface = ID_1;
                                     snake.ID_option = ID_1;
                                     initialize_();
                                     csnake.ShowMenu();
                                     break;
                                 case ID_2:
                                     state = false;
                                     break;
                            }
                            break;

                        case ID_5://等级界面
                            switch( snake.ID_option ){
                                 case ID_1:
                                     snake.rank = first;
                                     break;
                                 case ID_2:
                                     snake.rank = middle;
                                     break;
                                 case ID_3:
                                     snake.rank = high;
                                     break;
                            }
                            snake.ID_interface = ID_1;
                            snake.ID_option = ID_1;
                            csnake.ShowMenu();
                            break;

                        case ID_6://读取界面
                            size_t id;
                            switch( snake.ID_option ){
                                 case ID_1:
                                     id = 0; break;
                                 case ID_2:
                                     id = 1; break;
                                 case ID_3:
                                     id = 2; break;
                                 case ID_4:
                                     id = 3; break;
                                 case ID_5:
                                     id = 4; break;
                            }
                            //进行读取文件
                            if( snake.ID_option != ID_6&&snake.ID_option != ID_7 ){
                                     initialize_();
                                     if( csnake.Read( id ) ){
                                         snake.ID_interface = ID_2;
                                         csnake.StartGame();
                                     }
                                     else snake.ID_interface = ID_6;
                            }
                            else {
                                     snake.ID_interface = ID_1;
                                     snake.ID_option = ID_1;
                                     csnake.ShowMenu();
                            }
                            break;

                        case ID_7://英雄榜界面
                            snake.ID_interface = ID_1;
                            snake.ID_option = ID_1;
                            csnake.ShowMenu();
                            break;
                     }
                     if( !state ){
                         COORD cd = { info.srWindow.Right/4, info.srWindow.Bottom/5*4 };
                         SetConsoleCursorPosition( handle,cd );
                         exit(0);
                     }
                     snake.ID_option = ID_1;
                    break;
            }
    }
          //消息传给下个钩子
          return CallNextHookEx ( NULL, message, wParam, lParam );
}

//画墙函数和调用相应界面(已测试完成)
void Wall(){
    short i;
    COORD coord = { 0,0 };  //坐标结构
//绘墙
    SetConsoleCursorPosition( handle, coord );
    for( i=0;i<=info.srWindow.Right;++i )
            std::cout<<"#";

    coord.X = info.srWindow.Right;
    coord.Y = 1;
    for( i=1;i<info.srWindow.Bottom;++i ){
        SetConsoleCursorPosition( handle, coord );
        std::cout<<"#";
        ++coord.Y ;
    }

    coord.X = 0;
    coord.Y = info.srWindow.Bottom;
    for( i=1;i<=info.srWindow.Right;++i ){
        SetConsoleCursorPosition( handle, coord );
        std::cout<<"#";
        ++coord.X ;
    }

    coord.X = 0;
    coord.Y = 1;
    for( i=1;i<info.srWindow.Bottom;++i ){
        SetConsoleCursorPosition( handle, coord );
        std::cout<<"#";
        ++coord.Y ;
    }
//判断所在界面显示相关界面的菜单选项及其它
    int j = info.srWindow.Right/4;
    switch( snake.ID_interface ){
        case ID_1:
            csnake.ShowMenu(); 
            coord.X = j;
            coord.Y = info.srWindow.Bottom-6;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"o(-\"-)o  贪  #^_^#  吃  →_→  蛇  \\(^o^)/";
            break;//显示菜单选项

        case ID_2:
        case ID_3:
        case ID_4:
            //绘输出信息框
            coord.X = 1;
            coord.Y = info.srWindow.Bottom - 5;
            SetConsoleCursorPosition( handle, coord );
            for( i=1;i<info.srWindow.Right; std::cout<<"#", ++i );
            for( coord.X=j;coord.X<=info.srWindow.Right-j;coord.X+=j ){
                coord.Y = info.srWindow.Bottom - 5;
                for( i=coord.Y;i<info.srWindow.Bottom;++i ){
                        SetConsoleCursorPosition( handle, coord );
                        std::cout<<"#";
                        ++coord.Y ;
                }
            }
            //输出每个框的信息
            coord.X = 2;
            coord.Y-= 4;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"游戏难度:";
            coord.Y +=2;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"\t   ";
            switch( snake.rank ){
                  case first:
                      std::cout<<"初 级"; break;
                  case middle:
                      std::cout<<"中 级"; break;
                  case high:
                      std::cout<<"高 级"; break;
            }
      //当前分数
            coord.X += j;
            coord.Y -= 2;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"  当 前 分 数";
            coord.X +=j/2-3;
            coord.Y +=2;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<snake.mark ;
      //操作说明
            coord.X = j*2+1;
            coord.Y = info.srWindow.Bottom -4;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<" 操作说明: ";
            coord.Y +=2;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"  ↑ ↓ ←  →";
            ++coord.Y; 
            SetConsoleCursorPosition( handle, coord );
            std::cout<<" 空格: 暂停游戏";
      //制作人
            coord.X += j;
            SetConsoleCursorPosition( handle, coord );
            std::cout<<"\t制作人: _ 翼";
            break;

        case ID_5:
            csnake.ShowRank(); break;//显示游戏等级

        case ID_6:
            csnake.ShowRecord(); break;//显示存档记录

        case ID_7:
            csnake.ShowArmory(); break;//显示英雄榜
    }

}

//画框函数(完成)
void Frame(){
    COORD coord = { 0, info.srWindow.Bottom/3 };
    SetConsoleCursorPosition( handle, coord );
    for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
        
    coord.Y = info.srWindow.Bottom/3*2;
    SetConsoleCursorPosition( handle, coord );
    for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
        
    switch( snake.ID_interface ){
        case ID_3:
            csnake.ShowPause(); break;//显示暂停菜单
        case ID_4:
            csnake.Die(); break;//显示死亡界面菜单
        case ID_5:
            csnake.ShowRank(); break;//显示等级选项
    }
}

//初始化蛇数据(完成)
void initialize_(){
    snake.state = true; //蛇状态
    snake.Snake_size = 5; //蛇初始化长度
    //初始化蛇位置
    COORD cd;
    cd.Y = 3;
    snake.Snake_coord.clear();
    for( size_t i=10;i>5;--i ){
        cd.X = i;
        snake.Snake_coord.push_back( cd );
    }
    snake.food_coord.X = 0;
    snake.food_coord.Y = 0;
    snake.rank = first;   //默认等级
    snake.mark = 0; //分数
    snake.key = VK_RIGHT; 
    snake.ID_interface = ID_1;//界面标记
    snake.ID_option = ID_1;   //选项标记
    snake.Flag = false;
}

 

转载于:https://www.cnblogs.com/lancoyun/p/5928305.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值