小项目-贪吃蛇

老师布置的寒假作业:写个贪吃蛇 

以前没写过 所以写的超级长,不过好歹写完了。错误数据的判断和明显的bug还没有做。放出来先做个纪念。

注解非常非常非常非常详细

 

#include<stdio.h>
#include<cstdio>
#include<stdlib.h>//代码的x代表行,y代表列 如果按照笛卡尔坐标系的话这里的x,y是反过来的 
#include<string.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define MAXNX 20//地图高 
#define MAXNY 70//地图宽
int a[MAXNX][MAXNY];//1是蛇身体用@表示 2是墙壁用*表示  0是空地用一个空格表示 -1是食物用&表示 
void menu_1();//打印主页面
void shuaxin(); //刷新屏幕 
void x_1();//开始游戏 
void x_2();//查看排行榜 
void x_3();//清空排行榜 
void x_4();//游戏设置 
void drt();//设置方向
void move();//移动 
void draw();//画食物 
void rank();//读入排行榜 
void n_rank();//写入排行榜 
int drt1=1,drt_x[MAXNX],drt_y[MAXNY],tail=3;//drt1默认方向向右 1右 2下 3左 4上 ;drt_x,drt_y是蛇身体,tail是蛇长度 
int fx,fy;//食物的x,y坐标 
int flag;//撞墙判断 =1时撞墙 
int score;//得分 1个10分 
int rank1[11];//排行榜 
int stop;//暂停游戏 用于设置、查看排行榜等界面 
unsigned long times;//刷新时间 ms 
FILE *fp;
int main(){
    fp=fopen("排行榜.text","r");
    if(fp==NULL){
        fp=fopen("排行榜.text","w+");
        fprintf(fp,"游戏得分排行榜\n");
        for(int i=1;i<=10;i++) fprintf(fp,"%d 0\n",i);
        fclose(fp);
        fp=fopen("游戏设置.text","w+");
        fprintf(fp,"游戏刷新率:50");
        fclose(fp);
    }
    else fclose(fp);
    menu_1();
    return 0;
}
void menu_1(){
    fp=fopen("游戏设置.text","r+");//初始化游戏刷新率
    fscanf(fp,"游戏刷新率:%d",&times);
    fclose(fp);
    system("cls");//清空屏幕 
    int tem_menu_1;
    printf(" _______________________________________________________________________\n");
    printf("|                                                                       |\n");
    printf("|");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
    printf("               欢迎游玩贪吃蛇,祝你有个愉快而有趣的体验                ");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    printf("|\n");
    printf("|");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
    printf("            Welcome to visit Game, and wish you a pleasant             ");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    printf("|\n");
    printf("|");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
    printf("                    and interesting experience.                        ");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    printf("|\n");
    printf("|                                                                       |\n");
    printf("|                         WSAD 控制方向                                 |\n");
    printf("|                      输入相应的数字进行操作                           |\n");
    printf("|                                                                       |\n");
    printf("|         ● 1 开始游戏            ● 2 查看排行榜                      |\n");
    printf("|                                                                       |\n");
    printf("|                                                                       |\n");
    printf("|         ● 3 清除排行榜          ● 4 游戏刷新率设置                  |\n");
    printf("|                                                                       |\n");
    printf("|                        ●  0 退出游戏                                 |\n");
    printf("|_______________________________________________________________________|\n");
    fflush(stdin);//清空输入缓冲区
    scanf("%d",&tem_menu_1);
    switch(tem_menu_1){
        case 1:
            stop=1;
            x_1();
            
            break;
        case 2:
            x_2();
            break;
        case 3:
            x_3();
            break;
        case 4:
            x_4();
            break;
        case 0:
            system("cls");//清空屏幕 
            printf("游戏结束,感谢游玩。");
            exit(0);
            break;
        default:
            fflush(stdin);//清空输入缓冲区 
            system("cls");//清空屏幕 
            printf("输入错误,请重新输入。\n");
            menu_1();
            break;
    }
    
}
void x_1(){//开始游戏 
    score=0;rank(); //分数初始化,排行榜初始化 
    for(int i=0;i<MAXNX;i++){//初始化地图 
        for(int j=0;j<MAXNY;j++) a[i][j]=0;
    }
    memset(drt_x,-1,sizeof(drt_x));memset(drt_y,-1,sizeof(drt_y));//初始化蛇身体
    drt_x[0]=MAXNX-2;drt_x[1]=MAXNX-2;drt_x[2]=MAXNX-2;
    drt_y[0]=3;drt_y[1]=2;drt_y[2]=1;tail=3; 
    a[MAXNX-2][1]=1;a[MAXNX-2][2]=1;a[MAXNX-2][3]=1;//创建蛇身体 
    draw();//初始化食物位置; 
    drt1=1;//初始化方向 
    //初始化墙壁 开始 
    for(int i=0;i<MAXNY;i++) a[0][i]=2;
    for(int i=0;i<MAXNY;i++) a[MAXNX-1][i]=2;
    for(int i=0;i<MAXNX;i++) a[i][0]=2;
    for(int i=0;i<MAXNX;i++) a[i][MAXNY-1]=2;
    //初始化墙壁 结束 
    
    while(stop){
        if(_kbhit()){//如果按了按键 
            drt();
        }
        move();
        shuaxin();//打印地图 
        Sleep(times);
    }
}
void x_2(){//查看排行榜 
    system("cls");//清空屏幕 
    fflush(stdin);//清空输入缓冲区 
    printf("========排行榜========\n");
    for(int i=1;i<=10;i++) printf("====第%d名:%d====\n",i,rank1[i]);
    printf("3秒后返回主菜单");
    Sleep(3000);menu_1();
}
void x_3(){//清空排行榜 
    system("cls");//清空屏幕 
    fflush(stdin);//清空输入缓冲区 
    fp=fopen("排行榜.text","r+");
    fprintf(fp,"游戏得分排行榜\n");
    for(int i=1;i<=10;i++) fprintf(fp,"%d 0\n",i);
    fclose(fp);
    rank();
    printf("清空成功!\n");
    printf("3秒后返回主菜单");
    Sleep(3000);menu_1();
}
void x_4(){//游戏设置 
    FILE *fp_x_4;
    system("cls");//清空屏幕 
    fflush(stdin);//清空输入缓冲区 
    fp_x_4=fopen("游戏设置.text","r+");
    printf("目前的刷新速度:%d\n请输入需要的刷新速度(整数ms):\n",times);
    scanf("%d",&times);
    fprintf(fp_x_4,"游戏刷新率:%d",times);
    fclose(fp_x_4);
    printf("设置成功!3秒后返回主菜单");
    Sleep(3000);menu_1();
}
void shuaxin(){
    system("cls");//清空屏幕 
    if(flag==1){//撞到之后 
        printf("游戏结束!你的得分是:%d。3秒后返回主菜单。",score);flag=0;stop=0;
        n_rank();rank();
        Sleep(3000);menu_1();
    }
    else{
        for(int i=0;i<MAXNX;i++){//打印地图 
            for(int j=0;j<MAXNY;j++){
                if(a[i][j]==2){
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
                    printf("*");
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
                }
                else if(a[i][j]==1){
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
                    printf("@");
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
                }
                else if(a[i][j]==-1){
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2);
                    printf("&"); 
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
                }
                else printf(" ");
            }
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
            switch(i){
                case 0://得分 
                    printf("-------得分-------:%d",score);
                    break;
                case 1://排行榜 
                    printf(" --排行榜-- ");break;
                case 2:printf("|  第1-%d  |",rank1[1]);break;
                case 3:printf("|  第2-%d  |",rank1[2]);break;
                case 4:printf("|  第3-%d  |",rank1[3]);break;
                case 5:printf("|  第4-%d  |",rank1[4]);break;
                case 6:printf("|  第5-%d  |",rank1[5]);break;
                case 7:printf("|  第6-%d  |",rank1[6]);break;
                case 8:printf("|  第7-%d  |",rank1[7]);break;
                case 9:printf("|  第8-%d  |",rank1[8]);break;
                case 10:printf("|  第9-%d  |",rank1[9]);break;
                case 11:printf("|  第10-%d |",rank1[10]);break;
                case 12:printf("============",rank1[10]);break;
            }
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
            printf("\n");
        }
        
    }
    
}
void drt(){
    switch(_getch()){//改变方向 
        case 'd':case 'D':
        if(drt1!=3)drt1=1;break;
        case 's':case 'S':
        if(drt1!=4)drt1=2;break;
        case 'a':case 'A':
        if(drt1!=1)drt1=3;break;
        case 'w':case 'W':
        if(drt1!=2)drt1=4;break;
    }
}
void move(){
    int tem_fx=fx,tem_fy=fy;//用于在吃掉食物后食物刷新前食物的位置,判断头可以出现在该位置 
    if(drt_x[0]!=fx || drt_y[0]!=fy){
        a[drt_x[tail-1]][drt_y[tail-1]]=0;//蛇尾巴标记为 0 
    }
    
    else{
        tail++;score+=10;
        a[fx][fy]=1;//这里设置是为了防止画的食物和身体(也就是头)重合 
        draw();
    }
    for(int i=tail-1;i>0;i--){//蛇身体坐标集体移动一格 
        drt_x[i]=drt_x[i-1];
        drt_y[i]=drt_y[i-1];
        
    }
    switch(drt1){//蛇头位移方向 
        case 1: 
        if(a[drt_x[0]][drt_y[0]+1]==0 || drt_y[0]+1==tem_fy){
            drt_y[0]+=1;a[drt_x[0]][drt_y[0]]=1;
        }
        else flag=1;//移动的地方不是空地或者食物 
        break;
        case 2:
        if(a[drt_x[0]+1][drt_y[0]]==0 || drt_x[0]+1==tem_fx){
            drt_x[0]+=1;a[drt_x[0]][drt_y[0]]=1;
        }
        else flag=1;
        break;
        case 3:if(a[drt_x[0]][drt_y[0]-1]==0 || drt_y[0]-1==tem_fy){
            drt_y[0]-=1;a[drt_x[0]][drt_y[0]]=1;
        }
        else flag=1;
        break;
        case 4:if(a[drt_x[0]-1][drt_y[0]]==0 || drt_x[0]-1==tem_fx){
            drt_x[0]-=1;a[drt_x[0]][drt_y[0]]=1;
        }
        else flag=1;
        break;
    }
    
    
}
void draw(){
    while(fx<=0 || fy<=0 || fx>=MAXNX-1 || fy>=MAXNY-1 || a[fx][fy]!=0){
        srand(time(NULL));
        fx=rand()%MAXNX;
        fy=rand()%MAXNY;
    }
    a[fx][fy]=-1;
}
void rank(){
    int tem;char s[1000];
    FILE *fp_rank;
    fp_rank=fopen("排行榜.text","r+");
    fscanf(fp_rank,"%s",s);
    for(int i=1;i<=10;i++) fscanf(fp_rank,"%d %d",&tem,&rank1[i]);
    fclose(fp_rank);
} 
void n_rank(){
    FILE *fp_n_rank;
    if(score>rank1[10]){
        int i;
        for(i=10;i>0 &&rank1[i]<score;i--);
        if(i==0){
            for(int j=10;j>=2;j--) rank1[j]=rank1[j-1];
            rank1[1]=score;
        }
        else{
            for(int j=10;j>i+1;j--) rank1[j]=rank1[j-1];
            score=rank1[i+1];
        }
        fp_n_rank=fopen("排行榜.text","w");
        fprintf(fp_n_rank,"游戏得分排行榜\n");
        for(int i=1;i<=10;i++) fprintf(fp_n_rank,"%d %d\n",i,rank1[i]);
        fclose(fp_n_rank);
    }
    
}

 版本 UpdateTime 2022.2.16

快开学了再调一调(毕竟是作业)

分为多个文件 一个变量文件(GlobalVariables.cpp &&GlobalVariables .h)、一个函数文件(Method.cpp && Method.h),一个开始游戏文件(StartGame.cpp),统一放在项目下。

更新了各函数的名称(更直观)

增加了双缓冲避免闪瞎眼睛(.)

新增了穿墙模式和穿身体模式,在设置里调节开关。

默认为穿墙 不穿身体。

上代码:

StartGame.cpp
#include "GlobalVariables.h"
#include "Method.h"
extern Initial();
extern showMenu();
int main(){
    Initial();
    showMenu();
    return 0;
}

GlobalVariables.cpp

#include "GlobalVariables.h"//(直接不要也行?先留着吧万一用上了呢。)

GlobalVariables.h

#include<stdio.h>
#include<windows.h>

#ifndef GLOBALVARIABLES_H
#define GLOBALVARIABLES_H
#define MAXNX 20//地图高 
#define MAXNY 70//地图宽
static int numMap[MAXNX][MAXNY];//1是蛇身体用@表示 2是墙壁用*表示  0是空地用一个空格表示 -1是食物用&表示 
static char Map[MAXNX][MAXNY];//地图 
static HANDLE hOutput, hOutBuffer,Menu;
static COORD coord = { 0,0 }, coordTemp = {0,0}, menuCoord= { 0, 0};
static DWORD bytes = 0;
static bool flagBufferSwap = false;
static int drt1=1,drt_x[MAXNX],drt_y[MAXNY],tail=3;//drt1默认方向向右 1右 2下 3左 4上 ;drt_x,drt_y是蛇身体,tail是蛇长度 
static int fx,fy;//食物的x,y坐标 
static int flag;//游戏结束判断 =1时结束
static int score;//得分 1个10分 
static int rank1[11];//排行榜 
static int stop;//暂停游戏 用于设置、查看排行榜等界面 
static unsigned long times;//刷新时间 ms 
static int tem_flag=0;//第一次开始游戏 用于取消第一次对缓冲区清除导致的需要用户多按一个回车 
static FILE *fp;
static int WallThroughMode ;
static int BodyThroughMode ;
#endif

Method.cpp

#include "Method.h"
#include "GlobalVariables.h"
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>//代码的x代表行,y代表列 如果按照笛卡尔坐标系的话这里的x,y是反过来的 
#include<string.h>
#include<windows.h>
#include<conio.h>
#include<time.h>

void updateTheMap(); //刷新地图 
void startGame();//开始游戏 
void Gameover();//游戏结束 
void catchRank();//查看排行榜 
void clearRank();//清空排行榜 
void gameSetting();//游戏设置 
void drt();//设置方向
void move();//移动 
void draw();//画食物 
void rank();//读入排行榜 
void n_rank();//写入排行榜 
void cleanMenu();//清空Menu缓冲区 并显示(清屏效果) 

void Initial();//初始化 
void Show_Double_Buffer();//双缓冲显示 
void showMenu();//缓冲区菜单 
void toString(int num,char* s);

void ff(){//清空缓冲区 
    scanf("%*[^\n]%*c");
    while (_kbhit())
    {
        getch();
    }
}
void startGame(){//开始游戏 
    
    score=0;rank(); //分数初始化,排行榜初始化
    
    for(int i=0;i<MAXNX;i++){//初始化地图 
        for(int j=0;j<MAXNY;j++) numMap[i][j]=0;
    }
    memset(drt_x,-1,sizeof(drt_x));memset(drt_y,-1,sizeof(drt_y));//初始化蛇身体
    drt_x[0]=MAXNX-2;drt_x[1]=MAXNX-2;drt_x[2]=MAXNX-2;
    drt_y[0]=3;drt_y[1]=2;drt_y[2]=1;tail=3; 
    numMap[MAXNX-2][1]=1;numMap[MAXNX-2][2]=1;numMap[MAXNX-2][3]=1;//创建蛇身体 
    draw();//初始化食物位置; 
    drt1=1;//初始化方向 
    //初始化墙壁 开始 
    for(int i=0;i<MAXNY;i++) numMap[0][i]=2;
    for(int i=0;i<MAXNY;i++) numMap[MAXNX-1][i]=2;
    for(int i=0;i<MAXNX;i++) numMap[i][0]=2;
    for(int i=0;i<MAXNX;i++) numMap[i][MAXNY-1]=2;
    //初始化墙壁 结束 
    
    while(stop){
        if(_kbhit()){//如果按了按键 
            drt();
        }
        move();
        Show_Double_Buffer();//打印地图 
        Sleep(times);
    }
}
void catchRank(){//查看排行榜 
    cleanMenu();rank();
    ff();//清空输入缓冲区 
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, "========Rank========",strlen("========Rank========"), menuCoord, &bytes);
    for(int i=1,j=1;i<=10;i++,j++){
        char tem_score[10],tem_level[10];toString(rank1[i],tem_score);toString(i,tem_level);
        menuCoord={0,j}; 
        WriteConsoleOutputCharacterA(Menu, "+------Score-------+",strlen("+------Score-------+"), menuCoord, &bytes);
        COORD tem = {11 , j};
        SetConsoleCursorPosition(Menu, tem);
        WriteConsoleOutputCharacterA(Menu, tem_level,strlen(tem_level), menuCoord, &bytes);
        menuCoord={0,++j};
        WriteConsoleOutputCharacterA(Menu, tem_score,strlen(tem_score), menuCoord, &bytes);
    }
    menuCoord={0,22};WriteConsoleOutputCharacterA(Menu, "3秒后返回主菜单",strlen("3秒后返回主菜单"), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    printf("3秒后返回主菜单");
    Sleep(3000);showMenu();
}
void clearRank(){//清空排行榜 
    ff();//清空输入缓冲区 
    fp=fopen("排行榜.text","r+");
    fprintf(fp,"游戏得分排行榜\n");
    for(int i=1;i<=10;i++) fprintf(fp,"%5d 0\n",i);
    fclose(fp);
    rank();
    cleanMenu();
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, "清空成功!",strlen("清空成功!"), menuCoord, &bytes);
    menuCoord={0,1};WriteConsoleOutputCharacterA(Menu, "3秒后返回主菜单",strlen("3秒后返回主菜单"), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    Sleep(3000);showMenu();
}
void gameSetting(){//游戏设置 
    char timeString [10];
    toString(times,timeString);
    FILE *fp_x_4;
    cleanMenu();
    ff();//清空输入缓冲区 
    fp_x_4=fopen("游戏设置.text","w+");
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, "目前的刷新速度: ",strlen("目前的刷新速度: "), menuCoord, &bytes); 
    menuCoord={0,1};WriteConsoleOutputCharacterA(Menu, timeString,strlen(timeString), menuCoord, &bytes);
    menuCoord={0,2};WriteConsoleOutputCharacterA(Menu, "请输入需要的刷新速度(整数ms)、是否穿墙(1是0否)、是否穿身体(1是0否),输入为空格隔开的三个整数:",strlen("请输入需要的刷新速度(整数ms)、是否穿墙(1是0否)、是否穿身体(1是0否):"), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    COORD tem = {0 , 3};
    SetConsoleCursorPosition(Menu, tem);
    scanf("%d %d %d",&times,&WallThroughMode,&BodyThroughMode);
    fprintf(fp_x_4,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",times,WallThroughMode,BodyThroughMode);
    fclose(fp_x_4);
    cleanMenu();
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, "设置成功!3秒后返回主菜单",strlen("设置成功!3秒后返回主菜单"), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    Sleep(3000);showMenu();
}
void updateTheMap(){
    for(int i=0;i<MAXNX;i++){//更新地图 
        for(int j=0;j<MAXNY;j++){
            if(numMap[i][j]==2){
                Map[i][j] = '*';
            }
            else if(numMap[i][j]==1){
                Map[i][j] = '@';
            }
            else if(numMap[i][j]==-1){
                Map[i][j] = '&';
            }
            else Map[i][j] = ' ';
        }    
    }
    
}
void drt(){
    switch(_getch()){//改变方向 
        case 'd':case 'D':
        if(drt1!=3)drt1=1;break;
        case 's':case 'S':
        if(drt1!=4)drt1=2;break;
        case 'a':case 'A':
        if(drt1!=1)drt1=3;break;
        case 'w':case 'W':
        if(drt1!=2)drt1=4;break;
    }
}
void move(){
    int tem_fx=fx,tem_fy=fy;//用于在吃掉食物后食物刷新前食物的位置,判断头可以出现在该位置 
    if(drt_x[0]!=fx || drt_y[0]!=fy){
        numMap[drt_x[tail-1]][drt_y[tail-1]]=0;//蛇尾巴标记为 0 
    }
    
    else{
        tail++;score+=10;
        numMap[fx][fy]=1;//这里设置是为了防止画的食物和身体(也就是头)重合 
        draw();
    }
    for(int i=tail-1;i>0;i--){//蛇身体坐标集体移动一格 
        drt_x[i]=drt_x[i-1];
        drt_y[i]=drt_y[i-1];
        
    }
    switch(drt1){//蛇头位移方向 
        case 1: 
        if(numMap[drt_x[0]][drt_y[0]+1]==0 || drt_y[0]+1==tem_fy ){
            drt_y[0]+=1;numMap[drt_x[0]][drt_y[0]]=1;
        }
        else{
            if(numMap[drt_x[0]][drt_y[0]+1]==2 && WallThroughMode == 1){
                drt_y[0] = 1;numMap[drt_x[0]][drt_y[0]]=1;
            }else if(numMap[drt_x[0]][drt_y[0]+1]==1 && BodyThroughMode == 1){
                drt_y[0]+=1;numMap[drt_x[0]][drt_y[0]]=1;
            }else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式 
        }
        break;
        case 2:
        if(numMap[drt_x[0]+1][drt_y[0]]==0 || drt_x[0]+1==tem_fx){
            drt_x[0]+=1;numMap[drt_x[0]][drt_y[0]]=1;
        }
        else{
            if(numMap[drt_x[0]+1][drt_y[0]]==2 && WallThroughMode == 1){
                drt_x[0] = 1;numMap[drt_x[0]][drt_y[0]]=1;
            }else if(numMap[drt_x[0]+1][drt_y[0]]==1 && BodyThroughMode == 1){
                drt_x[0]+=1;numMap[drt_x[0]][drt_y[0]]=1;
            }else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式 
        } 
        break;
        case 3:if(numMap[drt_x[0]][drt_y[0]-1]==0 || drt_y[0]-1==tem_fy){
            drt_y[0]-=1;numMap[drt_x[0]][drt_y[0]]=1;
        }
        else{
            if(numMap[drt_x[0]][drt_y[0]-1]==2 && WallThroughMode == 1){
                drt_y[0] = MAXNY-2;numMap[drt_x[0]][drt_y[0]]=1;
            }else if(numMap[drt_x[0]][drt_y[0]-1]==1 && BodyThroughMode == 1){
                drt_y[0]-=1;numMap[drt_x[0]][drt_y[0]]=1;
            }else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式 
        } 
        break;
        case 4:if(numMap[drt_x[0]-1][drt_y[0]]==0 || drt_x[0]-1==tem_fx){
            drt_x[0]-=1;numMap[drt_x[0]][drt_y[0]]=1;
        }
        else{
            if(numMap[drt_x[0]-1][drt_y[0]]==2 && WallThroughMode == 1){
                drt_x[0] = MAXNX-2;numMap[drt_x[0]][drt_y[0]]=1;
            }else if(numMap[drt_x[0]-1][drt_y[0]]==1 && BodyThroughMode == 1){
                drt_x[0]-=1;numMap[drt_x[0]][drt_y[0]]=1;
            }else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式 
        } 
    }
    
    
}
void draw(){
    while(fx<=0 || fy<=0 || fx>=MAXNX-1 || fy>=MAXNY-1 || numMap[fx][fy]!=0){
        srand(time(NULL));
        fx=rand()%MAXNX;
        fy=rand()%MAXNY;
    }
    numMap[fx][fy]=-1;
}
void rank(){
    int tem;char s[1000];
    FILE *fp_rank;
    fp_rank=fopen("排行榜.text","r+");
    fscanf(fp_rank,"%s",s);
    for(int i=1;i<=10;i++) fscanf(fp_rank,"%d %d",&tem,&rank1[i]);
    fclose(fp_rank);
} 
void n_rank(){
    FILE *fp_n_rank;
    if(score>rank1[10]){
        int i;
        for(i=10;i>0 &&rank1[i]<score;i--);
        if(i==0){
            for(int j=10;j>=2;j--) rank1[j]=rank1[j-1];
            rank1[1]=score;
        }
        else{
            for(int j=10;j>i+1;j--) rank1[j]=rank1[j-1];
            score=rank1[i+1];
        }
        fp_n_rank=fopen("排行榜.text","w");
        fprintf(fp_n_rank,"游戏得分排行榜\n");
        for(int i=1;i<=10;i++) fprintf(fp_n_rank,"%d %d\n",i,rank1[i]);
        fclose(fp_n_rank);
    }
    
}
void Gameover(){//游戏结束
    char stringScore[10];
    toString(score,stringScore);
    cleanMenu();
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, "游戏结束!你的得分是: ",strlen("游戏结束!你的得分是: "), menuCoord, &bytes);
    menuCoord={0,1};WriteConsoleOutputCharacterA(Menu, stringScore,strlen(stringScore), menuCoord, &bytes);
    menuCoord={0,2};WriteConsoleOutputCharacterA(Menu, "3秒后返回主菜单。",strlen("3秒后返回主菜单。"), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);flag=0;stop=0;
    n_rank();rank();
    Sleep(3000);showMenu();
}
void Initial(){
    //设置、排行榜初始化 
    if(fp==NULL){
        fp=fopen("排行榜.text","w+");
        fprintf(fp,"游戏得分排行榜\n");
        for(int i=1;i<=10;i++) fprintf(fp,"%d 0\n",i);
        fclose(fp);
        fp=fopen("游戏设置.text","w+");
        fprintf(fp,"RefreshRate:200&WallThroughMode:1&BodyThroughMode:0");
        fclose(fp);
    }
    else fclose(fp);
    fp = fopen("游戏设置.text","r+");
    fscanf(fp,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",&times,&WallThroughMode,&BodyThroughMode);
    fclose(fp);
    //缓冲区初始化
     hOutBuffer = CreateConsoleScreenBuffer(
        GENERIC_WRITE,//定义进程可以往缓冲区写数据
        FILE_SHARE_WRITE,//定义缓冲区可以共享写入权限
        NULL,
        CONSOLE_TEXTMODE_BUFFER,
        NULL
     );
     hOutput = CreateConsoleScreenBuffer(
         GENERIC_WRITE,
         FILE_SHARE_WRITE,
         NULL,
         CONSOLE_TEXTMODE_BUFFER,
         NULL
     );
     Menu = CreateConsoleScreenBuffer(
         GENERIC_WRITE,
         FILE_SHARE_WRITE,
         NULL,
         CONSOLE_TEXTMODE_BUFFER,
         NULL
     );
     //隐藏缓冲区光标
     CONSOLE_CURSOR_INFO cci;
     cci.bVisible = 0;
     cci.dwSize = 1;
     SetConsoleCursorInfo(hOutBuffer, &cci);
     SetConsoleCursorInfo(hOutput, &cci);
}
void Show_Double_Buffer(){
    int i;
    char scoreString [10] ;
    memset(scoreString,'\0',sizeof(scoreString));
    toString(score,scoreString);
    if(flag != 1){
        updateTheMap();
        if (flagBufferSwap == false)
        {
            flagBufferSwap = true;
            for (i = 0; i < MAXNX; i++)
            {
                coord.Y = i;
                WriteConsoleOutputCharacterA(hOutBuffer, Map[i], MAXNY, coord, &bytes);
            }
            coord.Y = MAXNX; 
            WriteConsoleOutputCharacterA(hOutBuffer, "得分:", strlen("得分:"), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutBuffer, scoreString, strlen(scoreString), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutBuffer, "穿墙模式:", strlen("穿墙模式:"), coord, &bytes);
            coord.Y++; 
            if(WallThroughMode == 1)  WriteConsoleOutputCharacterA(hOutBuffer, "", strlen(""), coord, &bytes);
            else  WriteConsoleOutputCharacterA(hOutBuffer, "", strlen(""), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutBuffer, "穿身体模式:", strlen("穿身体模式:"), coord, &bytes);
            coord.Y++; 
            if(BodyThroughMode == 1)  WriteConsoleOutputCharacterA(hOutBuffer, "", strlen(""), coord, &bytes);
            else  WriteConsoleOutputCharacterA(hOutBuffer, "", strlen(""), coord, &bytes);
            SetConsoleActiveScreenBuffer(hOutBuffer);
        }
        else
        {
            flagBufferSwap = false;
            for (i = 0; i < MAXNX; i++)
            {
                coord.Y = i;
                WriteConsoleOutputCharacterA(hOutput, Map[i], MAXNY, coord, &bytes);
            }
            coord.Y = MAXNX; 
            WriteConsoleOutputCharacterA(hOutput, "得分:", strlen("得分:"), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutput, scoreString, strlen(scoreString), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutput, "穿墙模式:", strlen("穿墙模式:"), coord, &bytes);
            coord.Y++; 
            if(WallThroughMode == 1)  WriteConsoleOutputCharacterA(hOutput, "", strlen(""), coord, &bytes);
            else  WriteConsoleOutputCharacterA(hOutput, "", strlen(""), coord, &bytes);
            coord.Y++; 
            WriteConsoleOutputCharacterA(hOutput, "穿身体模式:", strlen("穿身体模式:"), coord, &bytes);
            coord.Y++; 
            if(BodyThroughMode == 1)  WriteConsoleOutputCharacterA(hOutput, "", strlen(""), coord, &bytes);
            else  WriteConsoleOutputCharacterA(hOutput, "", strlen(""), coord, &bytes);
            SetConsoleActiveScreenBuffer(hOutput);
        }
    }
    else Gameover(); 
}
void showMenu(){
    fp=fopen("游戏设置.text","r+");//初始化游戏刷新率
    fscanf(fp,"游戏刷新率:%d",&times);
    fclose(fp);
    cleanMenu();
    menuCoord={0,0};WriteConsoleOutputCharacterA(Menu, " _______________________________________________________________________",73, menuCoord, &bytes);
    menuCoord={0,1};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,2};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,3};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,4};WriteConsoleOutputCharacterA(Menu, "|              欢迎游玩贪吃蛇,该版本采用双缓冲避免闪屏,               |",73, menuCoord, &bytes);
    menuCoord={0,5};WriteConsoleOutputCharacterA(Menu, "|                    祝你有个愉快而有趣的体验。                         |",73, menuCoord, &bytes);
    menuCoord={0,6};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,7};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,8};WriteConsoleOutputCharacterA(Menu, "|           Welcome to visit Game, and wish you a pleasant              |",73, menuCoord, &bytes);
    menuCoord={0,9};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,10};WriteConsoleOutputCharacterA(Menu, "|                   and interesting experience.                         |",73, menuCoord, &bytes);
    menuCoord={0,11};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,12};WriteConsoleOutputCharacterA(Menu, "|                         WSAD 控制方向                                 |",73, menuCoord, &bytes);
    menuCoord={0,13};WriteConsoleOutputCharacterA(Menu, "|                      输入相应的数字进 行操作                          |",73, menuCoord, &bytes);
    menuCoord={0,14};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,15};WriteConsoleOutputCharacterA(Menu, "|         ● 1 开始游戏            ● 2 查看排行榜                      |",73, menuCoord, &bytes);
    menuCoord={0,16};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,17};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,18};WriteConsoleOutputCharacterA(Menu, "|         ● 3 清除排行榜          ● 4 游戏设置                        |",73, menuCoord, &bytes);
    menuCoord={0,19};WriteConsoleOutputCharacterA(Menu, "|                                                                       |",73, menuCoord, &bytes);
    menuCoord={0,20};WriteConsoleOutputCharacterA(Menu, "|                        ●  5 退出游戏                                 |",73, menuCoord, &bytes);
    menuCoord={0,21};WriteConsoleOutputCharacterA(Menu, "|_______________________________________________________________________|",73, menuCoord, &bytes);
    menuCoord={0,22};WriteConsoleOutputCharacterA(Menu, "请输入序号后回车:",18, menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    int choose = -1;
    if(tem_flag) ff();//清空输入缓冲区
    else tem_flag=1;
    COORD tem = {18 , 22};
    SetConsoleCursorPosition(Menu, tem);
    scanf("%d",&choose);
    if(choose==1 || choose==2 || choose==3 || choose==4 || choose==5){
        switch(choose){
            case 1:
                stop=1;
                startGame();
                
                break;
            case 2:
                catchRank();
                break;
            case 3:
                clearRank();
                break;
            case 4:
                gameSetting();
                break;
            case 5:
                cleanMenu();
                menuCoord={0,22};WriteConsoleOutputCharacterA(Menu, "游戏结束,感谢游玩。",strlen("游戏结束,感谢游玩。"), menuCoord, &bytes);
                SetConsoleActiveScreenBuffer(Menu);
                Sleep(2000);
                exit(0);
        }
    }
    else{
        ff();//清空输入缓冲区
        cleanMenu();
        menuCoord={0,22};WriteConsoleOutputCharacterA(Menu, "输入错误,请重新输入。\n",strlen("输入错误,请重新输入。\n"), menuCoord, &bytes);
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(2000);
        showMenu();
    }
}
void cleanMenu(){
    for(int i=0;i<=23;i++){
        menuCoord={0,i};
        WriteConsoleOutputCharacterA(Menu, "                                                                           ",75, menuCoord, &bytes);
    } 
    SetConsoleActiveScreenBuffer(Menu);
}
void toString(int num,char* s){
    memset(s,'\0',sizeof(s));
    if(num == 0) s[0] = '0';
    else {
        for(int i=0;num;i++){
            s[i] = '0'+num%10;
            num /= 10;
        }
        strrev(s);
    }
}
void mode(){
    
}

 

Method.h

#ifndef METHOD_H//(同样是啥用都没有的= =)
#define METHOD_H
#endif

 

缓冲区代码先套了网络模板,然后又加了一个新的区Menu来给主菜单和对话框用(因为发现在调用缓冲区显示后再用printf和system("cls")操作程序会死,不清楚是为什么),相当于三个缓冲区,但是游戏的时候只需要俩。

2022/3/13 答辩完成

增加了空格加速功能并且对UI进行亿点修改

//全局变量
#include<stdio.h>
#include<windows.h>

#ifndef GLOBALVARIABLES_H
#define GLOBALVARIABLES_H
#define MAXNX 20//地图高 
#define MAXNY 70//地图宽
static int numMap[MAXNX][MAXNY];//1是蛇身体用@表示 2是墙壁用*表示  0是空地用一个空格表示 -1是食物用&表示 
static char Map[MAXNX+10][MAXNY+10];//地图 
static HANDLE hOutput, hOutBuffer,Menu;
static COORD coord = { 0,0 }, coordTemp = {0,0}, menuCoord= { 0, 0};
static DWORD bytes = 0;
static bool flagBufferSwap = false;
static int drt1=1,drt_x[MAXNX],drt_y[MAXNY],tail=3;//drt1默认方向向右 1右 2下 3左 4上 ;drt_x,drt_y是蛇身体,tail是蛇长度 
static int fx,fy;//食物的x,y坐标 
static int flag;//游戏结束判断 =1时结束
static int score;//得分 1个10分 
static int rank1[11];//排行榜 
static int stop;//暂停游戏 用于设置、查看排行榜等界面 
static unsigned long times;//刷新时间 ms 
static int doWhat ;//状态量,表明用户在干什么 0为在主菜单,1是进行游戏,2是查看排行榜,3是清除排行榜,4是游戏设置 
static FILE *fp;
static int WallThroughMode ;
static int BodyThroughMode ;
static char ErrorPrint[22][73+2]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                                             *   *   *   *|",//4
        "|*************                                             *************|",//5
        "|    *   *                                                     *   *    |",//6
        "|*********                                                     *********|",//7
        "|*   *                                                             *   *|",//8
        "|*   *                         输入错误!                          *   *|",//9
        "|*   *                      ---请重新输入---                       *   *|",//10
        "|    *                            >-<                              *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                                                             *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********                                                     *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
        };
static     char MenuPrint[24][73+2] = {
        " _______________________________________________________________________ ",//0
        "| ______                                                                |",//1
        "|/  ___/               @@@                                              |",//2
        "| \\___ \\           @@@@ * @@                                            |",//3
        "|/_____>           @@@@@@@@@     @@@         @@@                        |",//4
        "|  ___                  @@@     @@@@@       @@@@@                       |",//5
        "| /   \\                @@@@    @@@  @@@    @@@  @@    @                 |",//6
        "||  |  |              @@@@    @@@    @@@  @@@    @@  @@                 |",//7
        "||__|__|                @@@@@@@@@      @@@@@      @@@@                  |",//8
        "|_____                                                                  |",//9
        "|\\__  \\           欢迎游玩贪吃蛇,该版本采用双缓冲避免闪屏,            |",//10
        "| / __ \\                祝你有个愉快而有趣的体验。                      |",//11
        "||____  /                                                               |",//12
        "|  __ \\/    Welcome to visit Game, and wish you a pleasant              |",//13
        "| |  | __          and interesting experience.                          |",//14
        "| |  |/ /                                                               |",//15
        "| |    <                   按下相应的数字进行操作:                      |",//16
        "| /__|_ \\           ● 1 开始游戏       ● 2 查看排行榜                 |",//17
        "| _____\\/                                                               |",//18
        "|/  __ \\            ● 3 清除排行榜     ● 4 游戏设置                   |",//19
        "||  ___/                                                                |",//20
        "| \\___ >                      ● 5 退出游戏                             |",//21
        "|_______________________________________________________________________|",//22        
    };    
static    char SettingPrint[22][73+2]={
        " _______________________________________________________________________ ",//0
        "|*********   *********  ★,°*:.☆( ̄▽ ̄)/$:*.°★*********    ********|",//1
        "|*       *   *                  游戏设置状态               *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                                             *   *   *   *|",//4
        "|*************                目前的刷新速度               *************|",//5
        "|    *   *                                                     *   *    |",//6
        "|*********                                                     *********|",//7
        "|*   *                          穿墙功能:                         *   *|",//8
        "|*   *                                                             *   *|",//9
        "|*   *                                                             *   *|",//10
        "|    *                         穿身体功能:                        *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *_____________________________________________________________*   *|",//13
        "|*   *                   按下0返回主菜单                           *   *|",//14
        "|*********               按下1进入刷新速度设置                 *********|",//15
        "|*************           按下2进入穿墙功能设置             *************|",//16
        "|*   *   *   *           按下3进入穿身体功能设置           *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                :                           *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
static    char Setting1Print[22][73+2]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                          __                 *   *   *   *|",//4
        "|*************             ______ _____/  |_               *************|",//5
        "|    *   *                /  ___// __ \\   __\\                  *   *    |",//6
        "|*********                \\___ \\\\  ___/|  |                   *********|",//7
        "|*   *                   /____  >\\___  >  |                        *   *|",//8
        "|*   *                        \\/     \\/ \\/                         *   *|",//9
        "|*   *                                                             *   *|",//10
        "|    *                        刷新速度设置                         *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                  请按下列括号里的要求输入                   *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********   需要的刷新速度(整数请输入不超过9999的正整数):   *********|",//15
        "|*************                :                            *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    }; 
static    char Setting2Print[22][73+2]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                          __                 *   *   *   *|",//4
        "|*************             ______ _____/  |_               *************|",//5
        "|    *   *                /  ___// __ \\   __\\                  *   *    |",//6
        "|*********                \\___ \\\\  ___/|  |                    *********|",//7
        "|*   *                   /____  >\\___  >  |                        *   *|",//8
        "|*   *                        \\/     \\/ \\/                         *   *|",//9
        "|*   *                                                             *   *|",//10
        "|    *                        穿墙功能设置                         *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                  请按下列括号里的要求输入                   *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********      穿墙功能是否开启(输入1为开启,0为关闭):     *********|",//15
        "|*************                :                            *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
static    char Setting3Print[22][73+2]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                          __                 *   *   *   *|",//4
        "|*************             ______ _____/  |_               *************|",//5
        "|    *   *                /  ___// __ \\   __\\                  *   *    |",//6
        "|*********                \\___ \\\\  ___/|  |                    *********|",//7
        "|*   *                   /____  >\\___  >  |                        *   *|",//8
        "|*   *                        \\/     \\/ \\/                         *   *|",//9
        "|*   *                                                             *   *|",//10
        "|    *                       穿身体功能设置                        *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                  请按下列括号里的要求输入                   *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********     穿身体功能是否开启(输入1为开启,0为关闭):    *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                :                            *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
static    char SetupSucceeded[22][75] = {
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                                             *   *   *   *|",//4
        "|*************                                             *************|",//5
        "|    *   *                                                     *   *    |",//6
        "|*********                                                     *********|",//7
        "|*   *                                                             *   *|",//8
        "|*   *                          设置成功!                          *   *|",//9
        "|*   *                       3秒后返回主菜单                       *   *|",//10
        "|    *                         ㄟ(≧◇≦)ㄏ                        *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                                                             *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********                                                     *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
};
static    char claerRankPrint[22][75]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                                             *   *   *   *|",//4
        "|*************                                             *************|",//5
        "|    *   *                                                     *   *    |",//6
        "|*********                                                     *********|",//7
        "|*   *                                                             *   *|",//8
        "|*   *                         清空成功!                          *   *|",//9
        "|*   *                      3秒后返回主菜单                        *   *|",//10
        "|    *                        ㄟ(≧◇≦)ㄏ                         *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                                                             *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********                                                     *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
static    char RankPrint[22][75]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                 Rank                        *   *   *   *|",//4
        "|*************                                             *************|",//5
        "|    *   *                Ⅰ-->1---Score:-----                 *   *    |",//6
        "|*********                Ⅱ-->2---Score:-----                 *********|",//7
        "|*   *                    Ⅲ-->3---Score:-----                     *   *|",//8
        "|*   *                    Ⅳ-->4---Score:-----                     *   *|",//9
        "|*   *                    Ⅴ-->5---Score:-----                     *   *|",//10
        "|    *                    Ⅵ-->6---Score:-----                     *    |",//11
        "|*   *                    Ⅶ-->7---Score:-----                     *   *|",//12
        "|*   *                    Ⅷ-->8---Score:-----                     *   *|",//13
        "|*   *                    Ⅸ-->9---Score:-----                     *   *|",//14
        "|*********                Ⅹ-->10--Score:-----                 *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
static    char gameOverPrint[22][75]={
        " _______________________________________________________________________ ",//0
        "|*********   *********                             *********    ********|",//1
        "|*       *   *                                             *    *      *|",//2
        "|*   ***************************************************************   *|",//3
        "|*   *   *   *                                             *   *   *   *|",//4
        "|*************                                             *************|",//5
        "|    *   *                                                     *   *    |",//6
        "|*********                                                     *********|",//7
        "|*   *                         游戏结束!                          *   *|",//8
        "|*   *                      你的得分:                             *   *|",//9
        "|*   *                      感谢游玩谢啦!!!                        *   *|",//10
        "|    *                        ㄟ(≧◇≦)ㄏ                         *    |",//11
        "|*   *                                                             *   *|",//12
        "|*   *                                                             *   *|",//13
        "|*   *                                                             *   *|",//14
        "|*********                                                     *********|",//15
        "|*************                                             *************|",//16
        "|*   *   *   *                                             *   *   *   *|",//17
        "|*   ***************************************************************   *|",//18
        "|*       *   *                                             *    *      *|",//19
        "|*********   *********                             *********    ********|",//20
        "|_______________________________________________________________________|",//21
    };
#endif
//方法 h
#ifndef METHOD_H
#define METHOD_H

void updateTheMap(); //刷新地图 
void startGame();//开始游戏 
void Gameover();//游戏结束 
void catchRank();//查看排行榜 
void clearRank();//清空排行榜 
void gameSetting();//游戏设置 
void gameSpeedSetting();//游戏速度设置
void gameWallThroughModeSetting();//游戏模式设置
void gameBodyThroughModeSetting();//
void drt(char c);//设置方向
void move();//移动 
void draw();//画食物 
void rank();//读入排行榜 
void n_rank();//写入排行榜 
void cleanMenu();//清空Menu缓冲区 并显示(清屏效果) 
void ff();//清空输入缓冲区
void ff2();
void Initial();//初始化 
void Show_Double_Buffer();//双缓冲显示 
void showMenu();//缓冲区菜单 
void toString(int num,char* s);

void SpaceAcceleration(char c);
//颜色控制
#define red_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &red, 1, coordTemp, &bytes);WriteConsoleOutputAttribute(hOutput, &red, 1, coordTemp, &bytes);
#define blue_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &blue, 1, coordTemp, &bytes);WriteConsoleOutputAttribute(hOutput, &blue, 1, coordTemp, &bytes);
#define yellow_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &yellow, 1, coordTemp, &bytes);
#define green_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &green, 1, coordTemp, &bytes);WriteConsoleOutputAttribute(hOutput, &green, 1, coordTemp, &bytes);
#define white_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &white, 1, coordTemp, &bytes);WriteConsoleOutputAttribute(hOutput, &white, 1, coordTemp, &bytes);
#define lightBlue_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &lightBlue, 1, menuCoord, &bytes);
#define Golden_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &Golden, 1, menuCoord, &bytes);
#define white_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &white, 1, menuCoord, &bytes);
#define green_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &green, 1, menuCoord, &bytes);
#define yellow_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &yellow, 1, menuCoord, &bytes);
#define red_Menu menuCoord.Y = i;menuCoord.X = j;WriteConsoleOutputAttribute(Menu, &red, 1, menuCoord, &bytes);
#define task_Map coordTemp.Y = i;coordTemp.X = j;WriteConsoleOutputAttribute(hOutBuffer, &task, 1, coordTemp, &bytes);WriteConsoleOutputAttribute(hOutput, &task, 1, coordTemp, &bytes);
//颜色控制

void showSetting();
#endif 
//方法cpp
#include "Method.h"
#include "GlobalVariables.h"
#include <stdio.h>
#include<cstdio>
#include<stdlib.h>//代码的x代表行,y代表列 如果按照笛卡尔坐标系的话这里的x,y是反过来的 
#include<string.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<wingdi.h>
#include<wincon.h>
#include<string>
WORD red = 0x4;
WORD lightBlue = 0x3;
WORD blue = 0x1;
WORD green = 0x2;
WORD yellow = 0xE;
WORD ching = 0x1A;
//    WORD Golden = 0xE;
WORD Golden = 0xE;
WORD white = 0x0f;
WORD task = 0x3;
//    WORD yellow = 0xFFFF00;
void ff() { //清空缓冲区
    scanf("%*[^\n]");
    while (_kbhit()) {
        getch();
    }
}
void ff2() { //清空缓冲区 但不获取键盘输入
    scanf("%*[^\n]");
}
void ff3() { //清空键盘输入
    while (_kbhit()) {
        getch();
    }
}
void startGame() { //开始游戏

    score=0;
    rank(); //分数初始化,排行榜初始化

    for(int i=0; i<MAXNX; i++) { //初始化地图
        for(int j=0; j<MAXNY; j++) numMap[i][j]=0;
    }
    memset(drt_x,-1,sizeof(drt_x));
    memset(drt_y,-1,sizeof(drt_y));//初始化蛇身体
    drt_x[0]=MAXNX-2;
    drt_x[1]=MAXNX-2;
    drt_x[2]=MAXNX-2;
    drt_y[0]=3;
    drt_y[1]=2;
    drt_y[2]=1;
    tail=3;
    numMap[MAXNX-2][1]=1;
    numMap[MAXNX-2][2]=1;
    numMap[MAXNX-2][3]=1;//创建蛇身体
    draw();//初始化食物位置;
    drt1=1;//初始化方向
    //初始化墙壁 开始
    for(int i=0; i<MAXNY; i++) numMap[0][i]=2;
    for(int i=0; i<MAXNY; i++) numMap[MAXNX-1][i]=2;
    for(int i=0; i<MAXNX; i++) numMap[i][0]=2;
    for(int i=0; i<MAXNX; i++) numMap[i][MAXNY-1]=2;
    //初始化墙壁 结束

    while(stop) {
        if(_kbhit()) { //如果按了按键
            char c = _getch();
            SpaceAcceleration(c);
            drt(c);
        }
        move();
        Show_Double_Buffer();//打印地图
        Sleep(times);
    }
}
void catchRank() { //查看排行榜
    rank();
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(RankPrint[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(RankPrint[i][j] == '|' || RankPrint[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                red_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, RankPrint[i],sizeof(RankPrint[i]), menuCoord, &bytes);
    }
    menuCoord.Y = 22,menuCoord.X = 0;
    WriteConsoleOutputCharacterA(Menu,"请按任意键回到主菜单",strlen("请按任意键回到主菜单"), menuCoord, &bytes);
    for(int i=1; i<=10; i++) {
        menuCoord = {41,5+i};
        char sScore[5];
        itoa(rank1[i],sScore,10);
        WriteConsoleOutputCharacterA(Menu, sScore,sizeof(sScore), menuCoord, &bytes);
    }
    SetConsoleActiveScreenBuffer(Menu);
    while(!_kbhit());
    ff3();
    showMenu();

}
void clearRank() { //清空排行榜
    fp=fopen("排行榜.text","r+");
    fprintf(fp,"游戏得分排行榜\n");
    for(int i=1; i<=10; i++) fprintf(fp,"%5d 0\n",i);
    fclose(fp);
    rank();
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(claerRankPrint[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(claerRankPrint[i][j] == '|' || claerRankPrint[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                green_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, claerRankPrint[i],sizeof(claerRankPrint[i]), menuCoord, &bytes);
    }
    SetConsoleActiveScreenBuffer(Menu);
    Sleep(3000);
    ff3();
    showMenu();
}
void gameSetting() { //游戏设置
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(SettingPrint[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(SettingPrint[i][j] == '|' || SettingPrint[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                green_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, SettingPrint[i],sizeof(SettingPrint[i]), menuCoord, &bytes);
    }
    //显示游戏速度、穿墙、穿身体
    menuCoord = {34,6};
    char sTimes[4];
    itoa(times,sTimes,10);
    WriteConsoleOutputCharacterA(Menu, sTimes,sizeof(sTimes), menuCoord, &bytes);
    char sYThrough[10] = "开启";
    char sNThrough[10] = "关闭";
    menuCoord = {34,9};
    if(WallThroughMode == 1) WriteConsoleOutputCharacterA(Menu, sYThrough,sizeof(sYThrough), menuCoord, &bytes);
    else WriteConsoleOutputCharacterA(Menu, sNThrough,sizeof(sNThrough), menuCoord, &bytes);
    menuCoord = {34,12};
    if(BodyThroughMode == 1) WriteConsoleOutputCharacterA(Menu, sYThrough,sizeof(sYThrough), menuCoord, &bytes);
    else WriteConsoleOutputCharacterA(Menu, sNThrough,sizeof(sNThrough), menuCoord, &bytes);
    SetConsoleActiveScreenBuffer(Menu);
    //显示游戏速度、穿墙、穿身体

    char choose = ' ';
    COORD temSetting = {32 , 19};
    SetConsoleCursorPosition(Menu, temSetting );
    while(!(choose == '0' || choose== '1'|| choose== '2' || choose=='3')) {
        if(_kbhit()) {
            choose = _getch();
            if(choose == '0' || choose== '1'|| choose== '2' || choose=='3') {
                switch(choose) {
                    case '0':
                        showMenu();
                        Sleep(500);
                        ff3();
                        break;
                    case '1':
                        gameSpeedSetting();
                        break;
                    case '2':
                        gameWallThroughModeSetting();
                        break;
                    case '3':
                        gameBodyThroughModeSetting();
                        break;
                }
            } else {
                ff2();//清空输入缓冲区
                cleanMenu();
                for(int i=0; i<22; i++) {
                    for(int j=0; j<75; j++) {
                        if(ErrorPrint[i][j] == '*') { // * 蓝色
                            lightBlue_Menu
                        } else if(ErrorPrint[i][j] == '|' || ErrorPrint[i][j] == '_') { //金色边框
                            Golden_Menu
                        } else {
                            red_Menu
                        }
                    }
                    menuCoord.Y = i,menuCoord.X = 0;
                    WriteConsoleOutputCharacterA(Menu, ErrorPrint[i],sizeof(ErrorPrint[i]), menuCoord, &bytes);
                }
                SetConsoleActiveScreenBuffer(Menu);
                Sleep(2000);
                gameSetting();
            }
        }
    }


}
void updateTheMap() {

    for(int i=0; i<MAXNX; i++) { //更新地图
        for(int j=0; j<MAXNY; j++) {
            if(numMap[i][j]==2) {
                yellow_Map
                Map[i][j] = '+';
            } else if(numMap[i][j]==1) {
                if(drt_x[0] == i && drt_y[0] == j) {
                    red_Map
                    Map[i][j] = '@';
                } else {
                    green_Map
                    Map[i][j] = 'O';
                }

            } else if(numMap[i][j]==-1) {
                task_Map
                Map[i][j] = '&';
            } else {
                Map[i][j] = ' ';
            }
        }
    }

}
void drt(char c) {
    switch(c) { //改变方向
        case 'd':
        case 'D':
            if(drt1!=3)drt1=1;
            break;
        case 's':
        case 'S':
            if(drt1!=4)drt1=2;
            break;
        case 'a':
        case 'A':
            if(drt1!=1)drt1=3;
            break;
        case 'w':
        case 'W':
            if(drt1!=2)drt1=4;
            break;
    }
}
void move() {
    int tem_fx=fx,tem_fy=fy;//用于在吃掉食物后食物刷新前食物的位置,判断头可以出现在该位置
    if(drt_x[0]!=fx || drt_y[0]!=fy) {
        numMap[drt_x[tail-1]][drt_y[tail-1]]=0;//蛇尾巴标记为 0
    }

    else {
        tail++;
        score+=10;
        numMap[fx][fy]=1;//这里设置是为了防止画的食物和身体(也就是头)重合
        draw();
    }
    for(int i=tail-1; i>0; i--) { //蛇身体坐标集体移动一格
        drt_x[i]=drt_x[i-1];
        drt_y[i]=drt_y[i-1];

    }
    switch(drt1) { //蛇头位移方向
        case 1:
            if(numMap[drt_x[0]][drt_y[0]+1]==0 || drt_y[0]+1==tem_fy ) {
                drt_y[0]+=1;
                numMap[drt_x[0]][drt_y[0]]=1;
            } else {
                if(numMap[drt_x[0]][drt_y[0]+1]==2 && WallThroughMode == 1) {
                    drt_y[0] = 1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else if(numMap[drt_x[0]][drt_y[0]+1]==1 && BodyThroughMode == 1) {
                    drt_y[0]+=1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式
            }
            break;
        case 2:
            if(numMap[drt_x[0]+1][drt_y[0]]==0 || drt_x[0]+1==tem_fx) {
                drt_x[0]+=1;
                numMap[drt_x[0]][drt_y[0]]=1;
            } else {
                if(numMap[drt_x[0]+1][drt_y[0]]==2 && WallThroughMode == 1) {
                    drt_x[0] = 1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else if(numMap[drt_x[0]+1][drt_y[0]]==1 && BodyThroughMode == 1) {
                    drt_x[0]+=1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式
            }
            break;
        case 3:
            if(numMap[drt_x[0]][drt_y[0]-1]==0 || drt_y[0]-1==tem_fy) {
                drt_y[0]-=1;
                numMap[drt_x[0]][drt_y[0]]=1;
            } else {
                if(numMap[drt_x[0]][drt_y[0]-1]==2 && WallThroughMode == 1) {
                    drt_y[0] = MAXNY-2;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else if(numMap[drt_x[0]][drt_y[0]-1]==1 && BodyThroughMode == 1) {
                    drt_y[0]-=1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式
            }
            break;
        case 4:
            if(numMap[drt_x[0]-1][drt_y[0]]==0 || drt_x[0]-1==tem_fx) {
                drt_x[0]-=1;
                numMap[drt_x[0]][drt_y[0]]=1;
            } else {
                if(numMap[drt_x[0]-1][drt_y[0]]==2 && WallThroughMode == 1) {
                    drt_x[0] = MAXNX-2;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else if(numMap[drt_x[0]-1][drt_y[0]]==1 && BodyThroughMode == 1) {
                    drt_x[0]-=1;
                    numMap[drt_x[0]][drt_y[0]]=1;
                } else flag=1;//移动的地方不是空地或者食物 并且不符合穿墙、穿身体模式
            }
    }


}
void draw() { //导致吃完食物后的卡顿
    while(fx<=0 || fy<=0 || fx>=MAXNX-1 || fy>=MAXNY-1 || numMap[fx][fy]!=0) {
        srand(time(NULL));
        fx=rand()%MAXNX;
        fy=rand()%MAXNY;
    }
    numMap[fx][fy]=-1;
}
void rank() {
    int tem;
    char s[1000];
    FILE *fp_rank;
    fp_rank=fopen("排行榜.text","r+");
    fscanf(fp_rank,"%s",s);
    for(int i=1; i<=10; i++) fscanf(fp_rank,"%d %d",&tem,&rank1[i]);
    fclose(fp_rank);
}
void n_rank() {
    FILE *fp_n_rank;
    if(score>rank1[10]) {
        int i;
        for(i=10; i>0 &&rank1[i]<score; i--);
        if(i==0) {
            for(int j=10; j>=2; j--) rank1[j]=rank1[j-1];
            rank1[1]=score;
        } else {
            for(int j=10; j>i+1; j--) rank1[j]=rank1[j-1];
            score=rank1[i+1];
        }
        fp_n_rank=fopen("排行榜.text","w");
        fprintf(fp_n_rank,"游戏得分排行榜\n");
        for(int i=1; i<=10; i++) fprintf(fp_n_rank,"%d %d\n",i,rank1[i]);
        fclose(fp_n_rank);
    }

}
void Gameover() { //游戏结束
    char stringScore[10];
    toString(score,stringScore);
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(gameOverPrint[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(gameOverPrint[i][j] == '|' || gameOverPrint[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                red_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, gameOverPrint[i],sizeof(gameOverPrint[i]), menuCoord, &bytes);
    }
    SetConsoleActiveScreenBuffer(Menu);
    menuCoord = {38,9};
    WriteConsoleOutputCharacterA(Menu, stringScore,sizeof(stringScore), menuCoord, &bytes);
    flag=0;
    stop=0;
    n_rank();
    rank();
    Sleep(3000);
    ff3();
    showMenu();
}
void Initial() {
    //设置、排行榜初始化
    fp=fopen("排行榜.text","r");
    if(fp==NULL) {
        fclose(fp);
        fp=fopen("排行榜.text","w+");
        fprintf(fp,"游戏得分排行榜\n");
        for(int i=1; i<=10; i++) fprintf(fp,"%d 0\n",i);
        fclose(fp);
        fp=fopen("游戏设置.text","w+");
        fprintf(fp,"RefreshRate:250&WallThroughMode:0&BodyThroughMode:0");
        fclose(fp);
    } else {
        fclose(fp);
        fp = fopen("游戏设置.text","r+");
        fscanf(fp,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",&times,&WallThroughMode,&BodyThroughMode);
        fclose(fp);
    }

    //缓冲区初始化
    hOutBuffer = CreateConsoleScreenBuffer(
                     GENERIC_WRITE,//定义进程可以往缓冲区写数据
                     FILE_SHARE_WRITE,//定义缓冲区可以共享写入权限
                     NULL,
                     CONSOLE_TEXTMODE_BUFFER,
                     NULL
                 );
    hOutput = CreateConsoleScreenBuffer(
                  GENERIC_WRITE,
                  FILE_SHARE_WRITE,
                  NULL,
                  CONSOLE_TEXTMODE_BUFFER,
                  NULL
              );
    Menu = CreateConsoleScreenBuffer(
               GENERIC_WRITE,
               FILE_SHARE_WRITE,
               NULL,
               CONSOLE_TEXTMODE_BUFFER,
               NULL
           );
    //隐藏缓冲区光标
    CONSOLE_CURSOR_INFO cci;
    cci.bVisible = 0;
    cci.dwSize = 1;
    SetConsoleCursorInfo(hOutBuffer, &cci);
    SetConsoleCursorInfo(hOutput, &cci);
}
void Show_Double_Buffer() {
    int i;
    char scoreString [10];
    char ModY[4] = "";
    char ModN[4] = "";
    memset(scoreString,'\0',sizeof(scoreString));
    toString(score,scoreString);
    if(flag != 1) {
        updateTheMap();
        if (flagBufferSwap == false) {
            flagBufferSwap = true;
            for (i = 0; i < MAXNX; i++) {
                coord.Y = i,coord.X = 0;
                WriteConsoleOutputCharacterA(hOutBuffer, Map[i], MAXNY, coord, &bytes);
                if(i == MAXNX/2-2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutBuffer, "得分:", strlen("得分:"), coord, &bytes);
                    coord = {strlen(Map[i])+6,i};
                    WriteConsoleOutputCharacterA(hOutBuffer, scoreString, strlen(scoreString), coord, &bytes);
                } else if(i == MAXNX/2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutBuffer, "穿墙模式:", strlen("穿墙模式:"), coord, &bytes);
                    coord = {strlen(Map[i])+10,i};
                    if(WallThroughMode == 1) WriteConsoleOutputCharacterA(hOutBuffer, ModY, strlen( ModY), coord, &bytes);
                    else WriteConsoleOutputCharacterA(hOutBuffer, ModN, strlen( ModY), coord, &bytes);
                } else if(i == MAXNX/2+2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutBuffer, "穿身体模式:", strlen("穿身体模式:"), coord, &bytes);
                    coord = {strlen(Map[i])+12,i};
                    if(BodyThroughMode == 1) WriteConsoleOutputCharacterA(hOutBuffer, ModY, strlen( ModY), coord, &bytes);
                    else WriteConsoleOutputCharacterA(hOutBuffer, ModN, strlen( ModY), coord, &bytes);
                }
            }
            for(int j=0; j<MAXNY; j++) {
                int i = MAXNX+1;
                red_Map
            }
            coord = {20,MAXNX+1};
            WriteConsoleOutputCharacterA(hOutBuffer, "按住空格键加速", strlen( "按住空格键加速"), coord, &bytes);
            SetConsoleActiveScreenBuffer(hOutBuffer);
        } else {
            flagBufferSwap = false;
            for (i = 0; i < MAXNX; i++) {
                coord.Y = i,coord.X = 0;
                WriteConsoleOutputCharacterA(hOutput, Map[i], MAXNY, coord, &bytes);
                if(i == MAXNX/2-2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutput, "得分:", strlen("得分:"), coord, &bytes);
                    coord = {strlen(Map[i])+6,i};
                    WriteConsoleOutputCharacterA(hOutput, scoreString, strlen(scoreString), coord, &bytes);
                } else if(i == MAXNX/2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutput, "穿墙模式:", strlen("穿墙模式:"), coord, &bytes);
                    coord = {strlen(Map[i])+10,i};
                    if(WallThroughMode == 1) WriteConsoleOutputCharacterA(hOutput, ModY, strlen( ModY), coord, &bytes);
                    else WriteConsoleOutputCharacterA(hOutput, ModN, strlen( ModY), coord, &bytes);
                } else if(i == MAXNX/2+2) {
                    coord = {strlen(Map[i])+1,i};
                    WriteConsoleOutputCharacterA(hOutput, "穿身体模式:", strlen("穿身体模式:"), coord, &bytes);
                    coord = {strlen(Map[i])+12,i};
                    if(BodyThroughMode == 1) WriteConsoleOutputCharacterA(hOutput, ModY, strlen( ModY), coord, &bytes);
                    else WriteConsoleOutputCharacterA(hOutput, ModN, strlen( ModY), coord, &bytes);
                }
            }
            for(int j=0; j<MAXNY; j++) {
                int i = MAXNX+1;
                red_Map
            }
            coord = {20,MAXNX+1};
            WriteConsoleOutputCharacterA(hOutput, "按住空格键加速", strlen( "按住空格键加速"), coord, &bytes);
            SetConsoleActiveScreenBuffer(hOutput);
        }
    } else Gameover();
}
void showMenu() {

    fp=fopen("游戏设置.text","r");//初始化游戏刷新率
    fscanf(fp,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",&times,&WallThroughMode,&BodyThroughMode);
    fclose(fp);
    cleanMenu();
    for(int i=0; i<24; i++) {
        for(int j=0; j<74; j++) {
//            if((MenuPrint[i][j] >= 'a' && MenuPrint[i][j] <= 'z' ) ||(MenuPrint[i][j] >= 'A' && MenuPrint[i][j] <= 'Z' )){
//            }//字母变色
            if(i >0 && i < 22 && j > 0 && j < 10 ) { //SNAKE金色
                Golden_Menu
            } else if(MenuPrint[i][j] == '|' || MenuPrint[i][j] == '_') { //金色边框
                Golden_Menu
            } else if(MenuPrint[i][j] == '@') { //蓝色蛇
                lightBlue_Menu
            } else if(MenuPrint[i][j] == '*') { //绿色眼睛
                green_Menu
            } else {
                white_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, MenuPrint[i],sizeof(MenuPrint[i]), menuCoord, &bytes);
    }
    COORD temMenu = {18 , 23};
    SetConsoleCursorPosition(Menu, temMenu);
    SetConsoleActiveScreenBuffer(Menu);
//    int choose = -1;
//    scanf("%d",&choose);
    char choose = ' ';
    while(true) {
        if(_kbhit()) { //如果按了按键
            char choose = _getch();
            int flag = 0;
            if( choose =='1' || choose=='2' || choose=='3' || choose == '4' || choose== '5' ) {
                flag = 1;
                switch(choose) {
                    case '1':
                        stop = 1;
                        startGame();
                        break;
                    case '2':
                        catchRank();
                        break;
                    case '3':
                        clearRank();
                        break;
                    case '4':
                        gameSetting();
                        break;
                    case '5':
                        cleanMenu();
                        menuCoord= {0,22};
                        WriteConsoleOutputCharacterA(Menu, "游戏结束,感谢游玩。",strlen("游戏结束,感谢游玩。"), menuCoord, &bytes);
                        SetConsoleActiveScreenBuffer(Menu);
                        Sleep(2000);
                        exit(0);
                }
            }

            else {//错误输入 
                cleanMenu();
                for(int i=0; i<22; i++) {//打印提示 
                    for(int j=0; j<75; j++) {
                        if(ErrorPrint[i][j] == '*') { // * 蓝色
                            lightBlue_Menu
                        } else if(ErrorPrint[i][j] == '|' || ErrorPrint[i][j] == '_') { //金色边框
                            Golden_Menu
                        } else {
                            red_Menu
                        }
                    }
                    menuCoord.Y = i,menuCoord.X = 0;
                    WriteConsoleOutputCharacterA(Menu, ErrorPrint[i],sizeof(ErrorPrint[i]), menuCoord, &bytes);
                }
                Sleep(2000);
                ff3();//清空输入缓冲区 
                showMenu();
            }
        }
        if(flag) break;
    }
}
void cleanMenu() {
    for(int i=0; i<30; i++) {
        menuCoord= {0,i};
        WriteConsoleOutputCharacterA(Menu, "                                                                           ",75, menuCoord, &bytes);
    }
    SetConsoleActiveScreenBuffer(Menu);
}
void toString(int num,char* s) {
    memset(s,'\0',sizeof(s));
    if(num == 0) s[0] = '0';
    else {
        for(int i=0; num; i++) {
            s[i] = '0'+num%10;
            num /= 10;
        }
        strrev(s);
    }
}
void SpaceAcceleration(char c) { //空格加速
    if(c == ' ') {
        while(true) {
            if(_kbhit()) { //如果按了按键
                char c = _getch();
                drt(c);
            }
            int SpaceDown = GetKeyState(VK_SPACE);
            if( SpaceDown < 0 ) {    
                move();
                Show_Double_Buffer();
                Sleep(times>200?times-180:1);
            } else break;
        }
    }
}
void gameSpeedSetting() {
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(Setting1Print[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(Setting1Print[i][j] == '|' || Setting1Print[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                green_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, Setting1Print[i],sizeof(Setting1Print[i]), menuCoord, &bytes);
    }
    COORD temSetting = {31 , 16};
    SetConsoleCursorPosition(Menu, temSetting );
    int temTimes;
    scanf("%d",&temTimes);
    if(temTimes > 0 && temTimes < 10000) {
        times = temTimes;
        FILE *fpGameSpeedSetting;
        fpGameSpeedSetting = fopen("游戏设置.text","w");
        fprintf(fpGameSpeedSetting,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",times,WallThroughMode,BodyThroughMode);
        fclose(fpGameSpeedSetting);
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(SetupSucceeded[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(SetupSucceeded[i][j] == '|' || SetupSucceeded[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, SetupSucceeded[i],sizeof(SetupSucceeded[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(3000);
        ff3();
        showMenu();
        //储存
    } else {
        ff2();//清空输入缓冲区
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(ErrorPrint[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(ErrorPrint[i][j] == '|' || ErrorPrint[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, ErrorPrint[i],sizeof(ErrorPrint[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(2000);
        gameSpeedSetting();
    }
}
void gameWallThroughModeSetting() {
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(Setting2Print[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(Setting2Print[i][j] == '|' || Setting2Print[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                green_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, Setting2Print[i],sizeof(Setting2Print[i]), menuCoord, &bytes);
    }
    COORD temSetting = {31 , 16};
    SetConsoleCursorPosition(Menu, temSetting );
    int temMod;
    scanf("%d",&temMod);
    if(temMod == 0 || temMod == 1) {
        WallThroughMode = temMod;
        FILE *fpGameSpeedSetting;
        fpGameSpeedSetting = fopen("游戏设置.text","w");
        fprintf(fpGameSpeedSetting,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",times,WallThroughMode,BodyThroughMode);
        fclose(fpGameSpeedSetting);
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(SetupSucceeded[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(SetupSucceeded[i][j] == '|' || SetupSucceeded[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, SetupSucceeded[i],sizeof(SetupSucceeded[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(3000);
        ff3();
        showMenu();
        //储存
    } else {
        ff2();//清空输入缓冲区
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(ErrorPrint[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(ErrorPrint[i][j] == '|' || ErrorPrint[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, ErrorPrint[i],sizeof(ErrorPrint[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(2000);
        gameWallThroughModeSetting();
    }
}
void gameBodyThroughModeSetting() {
    cleanMenu();
    for(int i=0; i<22; i++) {
        for(int j=0; j<75; j++) {
            if(Setting3Print[i][j] == '*') { // * 蓝色
                lightBlue_Menu
            } else if(Setting3Print[i][j] == '|' || Setting3Print[i][j] == '_') { //金色边框
                Golden_Menu
            } else {
                green_Menu
            }
        }
        menuCoord.Y = i,menuCoord.X = 0;
        WriteConsoleOutputCharacterA(Menu, Setting3Print[i],sizeof(Setting3Print[i]), menuCoord, &bytes);
    }
    COORD temSetting = {31 , 19};
    SetConsoleCursorPosition(Menu, temSetting );
    int temMod;
    scanf("%d",&temMod);
    if(temMod == 0 || temMod == 1) {
        BodyThroughMode = temMod;
        FILE *fpGameSpeedSetting;
        fpGameSpeedSetting = fopen("游戏设置.text","w");
        fprintf(fpGameSpeedSetting,"RefreshRate:%d&WallThroughMode:%d&BodyThroughMode:%d",times,WallThroughMode,BodyThroughMode);
        fclose(fpGameSpeedSetting);
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(SetupSucceeded[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(SetupSucceeded[i][j] == '|' || SetupSucceeded[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, SetupSucceeded[i],sizeof(SetupSucceeded[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(3000);
        ff3();
        showMenu();
    } else {
        ff2();//清空输入缓冲区
        cleanMenu();
        for(int i=0; i<22; i++) {
            for(int j=0; j<75; j++) {
                if(ErrorPrint[i][j] == '*') { // * 蓝色
                    lightBlue_Menu
                } else if(ErrorPrint[i][j] == '|' || ErrorPrint[i][j] == '_') { //金色边框
                    Golden_Menu
                } else {
                    red_Menu
                }
            }
            menuCoord.Y = i,menuCoord.X = 0;
            WriteConsoleOutputCharacterA(Menu, ErrorPrint[i],sizeof(ErrorPrint[i]), menuCoord, &bytes);
        }
        SetConsoleActiveScreenBuffer(Menu);
        Sleep(2000);
        gameBodyThroughModeSetting();
    }
}

应该是完结了??

 

posted @ 2022-01-06 20:13  m2on  阅读(50)  评论(0编辑  收藏  举报