C语言大作业之贪吃蛇大作战(高清高帧率)


前言

新手第一次发文,可能有各种bug,请多多见谅,如果有大佬发现了bug欢迎指出


(代码是菜鸡写的,想直接抄的就算了吧,直接拿来交作业的小心过程淘汰


我回来更新了,这次更新到贪吃蛇大作战2.2.1版本,修复了一些bug,新增最高分,修改昵称等功能。我会写的更加详细,欢迎大家讨论。

一、项目目标

设计一款贪吃蛇大作战游戏,包括图形化输出等基本操作,要求编程实现如下的贪吃蛇大作战游戏
(1)贪吃蛇的移动操作;
(2)贪吃蛇受键盘控制转向
(3)贪吃蛇受键盘控制加速
(4)自动生成食物
(5)贪吃蛇吃食物并变长
(6)AI贪吃蛇自动移动及转向
(7)AI贪吃蛇吃食物
(8)贪吃蛇与AI贪吃蛇作战
(9)贪吃蛇死亡判定
(10)AI贪吃蛇复活
(11)计分系统
(12)游戏结束判定
(13)游戏控制图形化界面及鼠标操作
(14)最高分记录
要求程序显示游戏说明,开始游戏,退出游戏界面,暂停界面
然后根据用户鼠标指令执行相应操作。

二、项目效果

直接上图片
开始界面

游戏说明
修改昵称
游戏中

暂停界面
结束界面
结束界面

三、开发环境

操作系统:Windows 10 专业工作站版
集成开发环境:Visual Studio 2019
外部库:easyx图形库
音乐需要下载,播放的音乐为在debug文件夹下的1.bgm.mp3,2.bgm.mp3,3.bgm.mp3(可以根据自己的喜好下载音乐更改名称后放进去)

四、使用步骤

1.引入库

代码如下:

#include <stdio.h>//基础库
#include <stdlib.h>//rand种子
#include <graphics.h>//图形库
#include <conio.h>//getch
#include <time.h>//时间,rand种子
#include <math.h>//log函数
#include<windows.h>//放音乐
#include <mmsystem.h>//放音乐
#include <process.h>//多线程
#pragma comment(lib,"winmm.lib")//放音乐

2.定义各种常量和宏定义

代码如下:

#define SNAKE_NUM 1000//最大蛇节数
#define Graph_x 1280//显示屏x
#define Graph_y 720//显示屏y
#define StartSpeed 10//蛇初始速度
#define QuickSpeed 100//蛇加速速度
#define StartSize 30//初始蛇长度
#define BasicSpeed 2//基础格率
#define AINUMBER 4//AI数量
#define MAXFOODNUMBER 100//最大食物数量
#define FOODCREATTIME 1000//食物生成及AI复活等待时间
#define GODTIME 1000//出生无敌时间
#define LEN sizeof(struct Music)//宏定义节点长度得命名
#define TYPE struct Music//宏定义结构体变量命名

3.函数名初始化

代码如下:

void keyControl();//按键改变方向
void CreateFood(void*);//生成食物&&复活AI蛇
void GameInit();//初始化
void eatfood(void*);//吃食物
void eatsnake_ai1(void*);
void eatsnake_ai2(void*);
void eatsnake_player(void*);
void eatsnake();//吃蛇
void snakebodyFollow();//蛇身跟随
void snakeheadMove(void*);//移动蛇头
void GameDraw();//绘制蛇
void AIsetup();//AI初始化
void AImove0(void*);
void AImove1(void*);
void AImove2(void*);
void AImove3(void*);
void AImove();//AI行动
void shortsnake(void*);//蛇随时间变短
void turn(int x0, int y0, int x, int y, int i);//AI方向
void artificial0(void*);
void artificial1(void*);
void artificial2(void*);
void artificial3(void*);
void artificial();//AI行动
void mousetest(void*);//鼠标检测
void startmenu();//游戏初始菜单
void over(void*);//结束判定
void gameshow();//游戏说明
void gameover();//结束界面
void GAME();//游戏
void music();//音乐
void sort();//给蛇排名
void gamepause();//游戏暂停

4.程序主体部分

4.1函数名

代码如下:

void keyControl();//按键改变方向
void CreateFood(void*);//生成食物&&复活AI蛇
void GameInit();//初始化
void eatfood(void*);//吃食物
void eatsnake_ai1(void*);
void eatsnake_ai2(void*);
void eatsnake_player(void*);
void eatsnake();//吃蛇
void snakebodyFollow();//蛇身跟随
void snakeheadMove(void*);//移动蛇头
void GameDraw();//绘制蛇
void AIsetup();//AI初始化
void AImove0(void*);
void AImove1(void*);
void AImove2(void*);
void AImove3(void*);
void AImove();//AI行动
void shortsnake(void*);//蛇随时间变短
void turn(int x0, int y0, int x, int y, int i);//AI方向
void artificial0(void*);
void artificial1(void*);
void artificial2(void*);
void artificial3(void*);
void artificial();//AI行动
void mousetest(void*);//鼠标检测
void startmenu();//游戏初始菜单
void over(void*);//结束判定
void gameshow();//游戏说明
void gameover();//结束界面
void GAME();//游戏
void music();//音乐
void sort();//给蛇排名
void gamepause();//游戏暂停
void getname(void*);//获取昵称
void delname(void*);//删除昵称
void flicker(void*);//光标闪烁

4.2一些结构体和判断多线程执行用的全局变量

代码如下:

struct Judge
{
    int judge1;
    int judge2_0;
    int judge2_1;
    int judge2_2;
    int judge2_3;
    int judgecreatfood;
    int judgeeatfood;
    int judgedraw;
    int judgeeatsnake_ai1;
    int judgeeatsnake_ai2;
    int judgeeatsnake_player;
    int judgegodtime;
    int judgeshortsnake;
    int shortsnaketime;
    int judgeai;
    int judgeai0;
    int judgeai1;
    int judgeai2;
    int judgeai3;
    int finalscore;
    int judgemouse;
    int judgemenu;
    int judgegame;
    int judgegameover;
    int judgepause;
    int judgementmusic;
    int judgekeycontrol;
    int judgehigh;
    int judgename;
    int judgegetname;
    int judgedelname;
    int judgeflicker;
    int judgetwinkling;
}judge;//多线程判断

//音乐链表
struct Music
{
    char data[50];
    struct Music* next;
}a,b,c;
//蛇结构
struct Snake
{
    char name[12] = "玩家";
    int size=0;//蛇的节数
    int dir=0;//蛇的方向
    int speed=StartSpeed;//移动方向
    int thickness=0;//蛇粗细
    bool flag=false;
    POINT coor[SNAKE_NUM] = {-1,-1};//坐标

}snake;

//实时分数
struct Realtimescore
{
    int num;//记录这是哪条蛇
    int score;//记录分数
    char name[12];//蛇名称
    char strscore[20];//分数转char类型输出
}realtimescore[7];

//方向枚举
enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT,
};

//初始蛇头位置
struct Snakexy
{
    int x;
    int y;
}snakexy;

//计分
struct Score
{
    int kill;
    int eat;
}score;

//食物结构
struct Food
{
    int x;//食物位置
    int y;
    int r;//食物大小
    bool flag;//食物是否被吃
    DWORD color; //食物颜色
}food[MAXFOODNUMBER];

//AI蛇结构
struct AISnake
{
    int size;
    int dir;
    int thickness;
    int speed = StartSpeed;
    struct Snakexy snakexy;
    struct Score score;
    bool flag;
    POINT coor[SNAKE_NUM];

};
struct AISnake* aisnake = NULL;

4.3主函数

代码如下:

int main()
{
    initgraph(Graph_x, Graph_y);//初始化graph图形窗口,SHOWCONSOLE显示控制台
    while (0 == judge.judgegame)
    {
        startmenu();
        switch (judge.judgemenu)
        {
        case 1: gameshow();break;
        case 2: GAME();break;
        case 3:judge.judgegame = 1;break;
        case 4: gameover();break;
        default : break;
        }
    }
    return 0;
}


4.4鼠标与键盘的检测函数

均为多线程同步运行,实时监测鼠标和键盘的操作,以达到灵敏控制蛇的目的

代码如下:

//鼠标检测
MOUSEMSG msg;//定义鼠标变量 mouse
void mousetest(void*)
{

    judge.judgemouse = 1;
    msg = GetMouseMsg();
    judge.judgemouse = 0;

    _endthread();
}

//按键改变方向
void keyControl(void*)
{
    judge.judgekeycontrol = 1;
    while (2 == judge.judgemenu)
    {
        if (GetAsyncKeyState(VK_SPACE) & 0x8000)
            snake.speed = QuickSpeed;
        else
            snake.speed = StartSpeed;
        if (GetAsyncKeyState(VK_UP) & 0x8000 || GetAsyncKeyState('W') & 0x8000)
        {
            if (snake.dir != DOWN)
                snake.dir = UP;
        }
        if (GetAsyncKeyState(VK_DOWN) & 0x8000 || GetAsyncKeyState('S') & 0x8000)
        {
            if (snake.dir != UP)
                snake.dir = DOWN;
        }
        if (GetAsyncKeyState(VK_LEFT) & 0x8000 || GetAsyncKeyState('A') & 0x8000)
        {
            if (snake.dir != RIGHT)
                snake.dir = LEFT;
        }
        if (GetAsyncKeyState(VK_RIGHT) & 0x8000 || GetAsyncKeyState('D') & 0x8000)
        {
            if (snake.dir != LEFT)
                snake.dir = RIGHT;
        }
        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
            judge.judgepause = 1;
        Sleep(1);
    }
    judge.judgekeycontrol = 0;
    _endthread();
};

4.5生成食物和复活AI蛇
判断食物和AI蛇的flag是否为true,如果不是就重新生成/复活。
涉及到随机数的问题,为了保证每次每局生成食物的位置不相同,用srand()函数根据时间定义种子生成随机数。
食物生成和AI复活有等待时间,即函数Sleep多久,这是一个单独的线程,所以它Sleep的时候不会导致主函数也卡死。

代码如下:

//生成食物&&复活AI蛇
void CreateFood(void *)
{
    srand(clock());
    judge.judgecreatfood = 1;
    if (snake.size <= 0)
        snake.flag = false;
    for (int i = 0; i < AINUMBER; i++)
    {
        if (aisnake[i].size <= 0)
            aisnake[i].flag = false;
    }
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if (food[i].flag == false)
        {
            food[i].x = rand() % Graph_x;
            food[i].y = rand() % Graph_y;
            food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            food[i].r = rand() % 5 + 5;
            food[i].flag = true;
            break;
        }
    }
    //复活蛇
    for (int i = 0; i < AINUMBER; i++)
    {
        if (aisnake[i].flag == false)
        {
            for (int j = 0; j < SNAKE_NUM; j++)
            {
                aisnake[i].coor[j].x = -2 - i;
                aisnake[i].coor[j].y = -2 - i;
            }
            aisnake[i].flag = true;
            aisnake[i].size = StartSize;
            aisnake[i].score.eat = 0;
            switch (rand() % 4)
            {
                
            case 0:
            {
                aisnake[i].coor[0].x = rand() % ((Graph_x - snake.coor[0].x + 1) + snake.coor[0].x);
                aisnake[i].coor[0].y = rand() % ((Graph_y - snake.coor[0].y + 1) + snake.coor[0].y);
                aisnake[i].dir = UP;
                for (int j = 1; j < aisnake[i].size; j++)
                {
                    aisnake[i].coor[j].x = aisnake[i].coor[0].x;
                    aisnake[i].coor[j].y = BasicSpeed * j + aisnake[i].coor[0].y;
                }
            }break;
            case 1:
            {
                aisnake[i].coor[0].x = rand() % (snake.coor[0].x + 2);
                aisnake[i].coor[0].y = rand() % ((Graph_y - snake.coor[0].y + 1) + snake.coor[0].y);
                aisnake[i].dir = DOWN;
                for (int j = 1; j < aisnake[i].size; j++)
                {
                    aisnake[i].coor[j].x = aisnake[i].coor[0].x;
                    aisnake[i].coor[j].y = -BasicSpeed * j + aisnake[i].coor[0].y;
                }
            }break;
            case 2:
            {
                aisnake[i].coor[0].x = rand() % (snake.coor[0].x + 2);
                aisnake[i].coor[0].y = rand() % (snake.coor[0].y + 2);
                aisnake[i].dir = LEFT;
                for (int j = 1; j < aisnake[i].size; j++)
                {
                    aisnake[i].coor[j].x = BasicSpeed * j + aisnake[i].coor[0].x;
                    aisnake[i].coor[j].y = aisnake[i].coor[0].y;
                }
            }break;
            case 3:
            {
                aisnake[i].coor[0].x = rand() % ((Graph_x - snake.coor[0].x + 1) + snake.coor[0].x);
                aisnake[i].coor[0].y = rand() % (snake.coor[0].y + 2);
                aisnake[i].dir = RIGHT;
                for (int j = 1; j < aisnake[i].size; j++)
                {
                    aisnake[i].coor[j].x = -BasicSpeed * j + aisnake[i].coor[0].x;
                    aisnake[i].coor[j].y = aisnake[i].coor[0].y;
                }
            }break;
            };
            
            break;
        }
    }
    Sleep(FOODCREATTIME);
    judge.judgecreatfood = 0;
    _endthread();
}

4.6昵称相关函数
关于删除昵称,因为中文字符是由ASCII码大于127的2个字节组成的,所以删除时需要判断其ASCII的值,确定这是一个中文字符之后将两个字节全部删除。

代码如下:

//获取昵称
void getname(void*)
{
    judge.judgegetname = 1;
    char name[20];
    fgets(name, 20, stdin);
    if (strlen(snake.name) + strlen(name) < 12)
    {
        strcat_s(snake.name, sizeof(name), name);
        snake.name[strlen(snake.name) - 1] = '\0';
    }
    judge.judgegetname = 0;
    _endthread();
}

//删除昵称
void delname(void*)
{
    judge.judgedelname = 1;
    if (GetAsyncKeyState(VK_BACK) & 0x8000)
    {
        if (snake.name[strlen(snake.name)-1] < 0)
        {
            snake.name[strlen(snake.name) - 1] = '\0';
            snake.name[strlen(snake.name) - 1] = '\0';
        }
        else
            snake.name[strlen(snake.name) - 1] = '\0';
        Sleep(500);
    }
    judge.judgedelname = 0;
    _endthread;
}

//光标闪烁
void flicker(void*)
{
    judge.judgeflicker = 1;
    while (0 == judge.judgename)
    {
        Sleep(500);
        judge.judgetwinkling = 0;
        Sleep(500);
        judge.judgetwinkling = 1;
    }
    judge.judgeflicker = 0;
    _endthread;
}

4.7初始化

代码如下:

//初始化
void GameInit()
{
    int high=0;
    judge.judgemouse = 0;
    judge.judgeai = 0;
    judge.judgecreatfood = 0;
    judge.judge1 = 0;
    judge.judgeeatfood = 0;
    judge.judgeshortsnake = 0;
    judge.judgegameover = 0;
    judge.judgekeycontrol = 0;
    judge.judgename = 0;
    judge.judgedelname = 0;
    judge.judgeflicker = 0;
    FILE* fp;
    if (errno_t err = fopen_s(&fp, "./data.txt", "ab+") != 0)
    {
        puts("要写入的文件出错,按任意键退出");
        Sleep(5000);
        exit(0);
    }
    while (1)
    {
        if (0 != fp)
        {
            fscanf_s(fp, "%d", &high);
            if (feof(fp))break;
        }
    }
    judge.judgehigh = high;//找到最高分
    fclose(fp);
    if (1 != judge.judgementmusic)
    {
        mciSendString("stop BGM2", 0, 0, 0);
        mciSendString("close BGM2", 0, 0, 0);
        mciSendString("stop BGM3", 0, 0, 0);
        mciSendString("close BGM3", 0, 0, 0);
        mciSendString(a.data, 0, 0, 0);
        mciSendString("play BGM1 repeat", 0, 0, 0);
        judge.judgementmusic = 1;
    }
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        food[i].flag = false;
    }
    srand(clock());//GetTickCount获取系统开机到现在毫秒数
    judge.judgegodtime = 0;
    judge.shortsnaketime = 1000;
    for (int i = 0; i < SNAKE_NUM; i++)
    {
        snake.coor[i].x = -1;
        snake.coor[i].y = -1;
    }
    snakexy.x = Graph_x / 2;
    snakexy.y = Graph_y / 2;
    snake.size = StartSize;//蛇一开始节数
    snake.speed = StartSpeed;//蛇开始速度
    score.eat = 0;
    score.kill = 0;
    snake.flag = true;
    switch (rand() % 4)
    {
    case 0:
    {
        for (int i = 0; i < snake.size; i++)
        {
            snake.dir = UP;
            snake.coor[i].x = snakexy.x;
            snake.coor[i].y = BasicSpeed * i + snakexy.y;
        }
    }break;
    case 1:
    {
        for (int i = 0; i < snake.size; i++)
        {
            snake.dir = DOWN;
            snake.coor[i].x = snakexy.x;
            snake.coor[i].y = -BasicSpeed * i + snakexy.y;
        }
    }break;
    case 2:
    {
        for (int i = 0; i < snake.size; i++)
        {
            snake.dir = LEFT;
            snake.coor[i].x = BasicSpeed * i + snakexy.x;
            snake.coor[i].y = snakexy.y;
        }
    }break;
    case 3:
    {
        for (int i = 0; i < snake.size; i++)
        {
            snake.dir = RIGHT;
            snake.coor[i].x = -BasicSpeed * i + snakexy.x;
            snake.coor[i].y = snakexy.y;
        }
    }break;
    };
    while(0==judge.judgename)
    {
        BeginBatchDraw();//双缓冲绘图开始
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        if (0 == judge.judgegetname) _beginthread(getname, 0, NULL);
        if (0 == judge.judgedelname) _beginthread(delname, 0, NULL);
        if (0 == judge.judgeflicker)_beginthread(flicker, 0, NULL);
        setbkcolor(RGB(28, 115, 119));//设置颜色
        cleardevice();//清空绘图设备
        setlinecolor(WHITE);
        if(0==judge.judgetwinkling) line(500+strlen(snake.name)*25,200, 500 + strlen(snake.name) * 25,250);
        setbkmode(TRANSPARENT);// 去掉文字背景
        settextstyle(50, 0, "楷体");
        settextcolor(RGB(255,227,132));
        outtextxy(200, 200, "请输入昵称:");
        settextstyle(30, 0, "楷体");
        settextcolor(RGB(25, 227, 255));
        outtextxy(200, 400, "支持中英文输入,输入英文时不要开启输入法,输入中文要开启输入法");
        outtextxy(200, 430, "完成输入后按回车会有显示,按退格键删除一个字,昵称最多6个中文");
        settextstyle(50, 0, "楷体");
        settextcolor(RGB(255, 97, 3));
        outtextxy(500, 200, snake.name);
        settextstyle(80, 0, "楷体");//设置文字大小 格式
        setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色
        fillrectangle(200, 500, 520, 580);
        fillrectangle(700, 500, 1020, 580);
        settextcolor(WHITE);
        outtextxy(200, 500, "清空输入");
        outtextxy(700, 500, "确认输入");
        if (msg.x >= 200 && msg.x <= 520 && msg.y >= 500 && msg.y <= 580)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(190, 490, 530, 590);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                for (int i = 0; i < 20; i++)
                {
                    snake.name[i] = '\0';
                }
            }
        }
        else if (msg.x >= 700 && msg.x <= 1020 && msg.y >= 500 && msg.y <= 580)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(690, 490, 1030, 590);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgename = 1;
            }
        }
        else
        {
            setlinecolor(RGB(28, 115, 119));
            rectangle(190, 490, 530, 590);
            rectangle(690, 490, 1030, 590);
        }
        EndBatchDraw();//双缓冲绘图结束
    }
};

4.8蛇吃东西的函数
计算蛇与食物中心的距离,距离如果小于两者圆的半径之和,则为接触,与图像相对应。

代码如下:

//吃食物
void eatfood(void *)
{
    judge.judgeeatfood = 1;
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if (snake.flag == true)
        {
            if ((food[i].r + snake.thickness) * (food[i].r + snake.thickness) >= ((snake.coor[0].x - food[i].x) * (snake.coor[0].x - food[i].x) + (snake.coor[0].y - food[i].y) * (snake.coor[0].y - food[i].y)))
            {
                if (food[i].flag != false)
                {
                    if (snake.size + food[i].r < SNAKE_NUM)
                    {
                        snake.size += food[i].r;

                    }
                    else snake.size = SNAKE_NUM;
                    score.eat += food[i].r;
                    food[i].flag = false;
                }

            }
        }
        for (int j=0; j < AINUMBER; j++)
        {
            if (aisnake[j].flag == true)
            {
                if ((food[i].r + aisnake[j].thickness) * (food[i].r + aisnake[j].thickness) >= ((aisnake[j].coor[0].x - food[i].x) * (aisnake[j].coor[0].x - food[i].x) + (aisnake[j].coor[0].y - food[i].y) * (aisnake[j].coor[0].y - food[i].y)))
                {
                    if (food[i].flag != false)
                    {
                        if (aisnake[j].size + food[i].r < SNAKE_NUM)
                        {
                            aisnake[j].size += food[i].r;

                        }
                        else aisnake[j].size = SNAKE_NUM;
                        aisnake[j].score.eat = aisnake[j].size;
                        food[i].flag = false;
                    }
                }
            }
        }
    }
    judge.judgeeatfood = 0;
    _endthread();
}

//吃蛇
void eatsnake_ai1(void*)
{
    judge.judgeeatsnake_ai1 = 1;
    if (0 == judge.judgegodtime)
    {
        Sleep(GODTIME);
    }
    for (int i = 0; i < AINUMBER; i++)
    {
        for (int j = AINUMBER - 1; j > i; j--)
        {
            if (aisnake[i].flag == true && aisnake[j].flag == true)
            {
                //AI吃AI
                if (((aisnake[j].coor[0].x - aisnake[i].coor[0].x) * (aisnake[j].coor[0].x - aisnake[i].coor[0].x) + (aisnake[j].coor[0].y - aisnake[i].coor[0].y) * (aisnake[j].coor[0].y - aisnake[i].coor[0].y)) <= (aisnake[j].thickness + aisnake[i].thickness) * (aisnake[j].thickness + aisnake[i].thickness))
                {
                    if (aisnake[j].size >= aisnake[i].size)
                    {
                        for (int k = 0; k < aisnake[i].size; k++)
                        {
                            aisnake[i].coor[k].x = -2 - i;
                            aisnake[i].coor[k].y = -2 - i;
                        }
                        if (aisnake[j].size+ aisnake[i].size < SNAKE_NUM) aisnake[j].size += aisnake[i].size;
                        else  aisnake[j].size = SNAKE_NUM;
                        aisnake[j].score.eat = aisnake[j].size;
                        aisnake[j].score.kill++;
                        aisnake[i].size = 0;
                        aisnake[i].score.kill = 0;
                        aisnake[i].flag = false;
                    }
                    else
                    {
                        for (int k = 0; k < aisnake[j].size; k++)
                        {
                            aisnake[j].coor[k].x = -2 - j;
                            aisnake[j].coor[k].y = -2 - j;
                        }
                        if (aisnake[i].size+ aisnake[j].size < SNAKE_NUM) aisnake[i].size += aisnake[j].size;
                        else  aisnake[i].size = SNAKE_NUM;
                        aisnake[i].score.eat = aisnake[i].size;
                        aisnake[j].score.eat = 0;
                        aisnake[i].score.kill++;
                        aisnake[j].size = 0;
                        aisnake[j].score.kill = 0;
                        aisnake[j].flag = false;
                    }
                }
            }
        }
    }
    judge.judgeeatsnake_ai1 = 0;
    _endthread();
}
void eatsnake_ai2(void*)
{
    judge.judgeeatsnake_ai2 = 1;
    if (0 == judge.judgegodtime)
    {
        Sleep(GODTIME);
    }
    for (int i = 0; i < AINUMBER; i++)
    {
        for (int j = AINUMBER - 1; j > i; j--)
        {
            if (aisnake[i].flag == true && aisnake[j].flag == true)
            {
                //AI吃AI蛇身
                if (aisnake[j].flag == true)
                {
                    if (aisnake[i].size > 5)
                    {
                        for (int m = 5; m < aisnake[i].size; m++)
                        {
                            if (((aisnake[j].coor[0].x - aisnake[i].coor[m].x) * (aisnake[j].coor[0].x - aisnake[i].coor[m].x) + (aisnake[j].coor[0].y - aisnake[i].coor[m].y) * (aisnake[j].coor[0].y - aisnake[i].coor[m].y)) <= (aisnake[i].thickness + aisnake[j].thickness) * (aisnake[i].thickness + aisnake[j].thickness))
                            {
                                for (int k = m - 1; k < aisnake[i].size; k++)
                                {
                                    aisnake[i].coor[k].x = -2 - i;
                                    aisnake[i].coor[k].y = -2 - i;
                                }
                                if (aisnake[j].size+ aisnake[i].size - m < SNAKE_NUM) aisnake[j].size += aisnake[i].size - m;
                                else  aisnake[j].size = SNAKE_NUM;
                                aisnake[j].score.eat = aisnake[i].size;
                                aisnake[i].score.eat = m;
                                aisnake[i].size = m;
                            }
                        }
                    }
                }
                if (aisnake[i].flag == true)
                {
                    if (snake.size > 5)
                    {
                        for (int m = 5; m < aisnake[j].size; m++)
                        {
                            if (((aisnake[i].coor[0].x - aisnake[j].coor[m].x) * (aisnake[i].coor[0].x - aisnake[j].coor[m].x) + (aisnake[i].coor[0].y - aisnake[j].coor[m].y) * (aisnake[i].coor[0].y - aisnake[j].coor[m].y)) <= (aisnake[i].thickness + aisnake[j].thickness) * (aisnake[i].thickness + aisnake[j].thickness))
                            {
                                for (int k = m - 1; k < aisnake[j].size; k++)
                                {
                                    aisnake[j].coor[k].x = -2 - j;
                                    aisnake[j].coor[k].y = -2 - j;
                                }
                                if (aisnake[i].size+ aisnake[j].size - m < SNAKE_NUM) aisnake[i].size += aisnake[j].size - m;
                                else  aisnake[i].size = SNAKE_NUM;
                                aisnake[i].score.eat = aisnake[i].size;
                                aisnake[j].score.eat = m;
                                aisnake[j].size = m;
                            }
                        }
                    }
                }
            }
        }
    }
    judge.judgeeatsnake_ai2 = 0;
    _endthread();
}
void eatsnake_player(void*)
{
    judge.judgeeatsnake_player = 1;
    if (0 == judge.judgegodtime)
    {
        Sleep(GODTIME);
        judge.judgegodtime = 1;
    }
    for (int k = 0; k < AINUMBER; k++)
    {
        if (snake.flag == true && aisnake[k].flag == true)
        {
            if (((snake.coor[0].x - aisnake[k].coor[0].x) * (snake.coor[0].x - aisnake[k].coor[0].x) + (snake.coor[0].y - aisnake[k].coor[0].y) * (snake.coor[0].y - aisnake[k].coor[0].y)) <= (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness))
            {
                if (snake.size >= aisnake[k].size)
                {
                    for (int i = 0; i < aisnake[k].size; i++)
                    {
                        aisnake[k].coor[i].x = -2 - k;
                        aisnake[k].coor[i].y = -2 - k;
                    }
                    if (snake.size+ aisnake[k].size < SNAKE_NUM) snake.size += aisnake[k].size;
                    else  snake.size = SNAKE_NUM;
                    score.eat += aisnake[k].score.eat;
                    score.kill++;
                    aisnake[k].score.eat = 0;
                    aisnake[k].size = 0;
                    aisnake[k].flag = false;
                }
                else
                {
                    for (int i = 0; i < snake.size; i++)
                    {
                        snake.coor[i].x = -1;
                        snake.coor[i].y = -1;
                    }
                    if (aisnake[k].size+ snake.size < SNAKE_NUM) aisnake[k].size += snake.size;
                    else  aisnake[k].size = SNAKE_NUM;
                    aisnake[k].score.eat = aisnake[k].size;
                    snake.size = 0;
                    snake.flag = false;
                }
            }
        }
    }
    for (int k = 0; k < AINUMBER; k++)
    {
        //人吃AI蛇身
        if (snake.flag == true)
        {
            if (aisnake[k].size > 5)
            {
                for (int m = 5; m < aisnake[k].size; m++)
                {
                    if (((snake.coor[0].x - aisnake[k].coor[m].x) * (snake.coor[0].x - aisnake[k].coor[m].x) + (snake.coor[0].y - aisnake[k].coor[m].y) * (snake.coor[0].y - aisnake[k].coor[m].y)) <= (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness))
                    {
                        for (int i = m - 1; i < aisnake[k].size; i++)
                        {
                            aisnake[k].coor[i].x = -2 - k;
                            aisnake[k].coor[i].y = -2 - k;
                        }
                        if (snake.size + aisnake[k].size - m < SNAKE_NUM) snake.size += aisnake[k].size - m;
                        else  snake.size = SNAKE_NUM;
                        score.eat += aisnake[k].size-m ;
                        aisnake[k].score.eat -= (aisnake[k].size - m);
                        aisnake[k].size = m;
                    }
                }
            }
        }
        //AI吃人蛇身
        if (aisnake[k].flag == true)
        {
            if (snake.size > 5)
            {
                for (int m = 5; m < snake.size; m++)
                {
                    if (((aisnake[k].coor[0].x - snake.coor[m].x) * (aisnake[k].coor[0].x - snake.coor[m].x) + (aisnake[k].coor[0].y - snake.coor[m].y) * (aisnake[k].coor[0].y - snake.coor[m].y)) <= (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness))
                    {
                        for (int i = m - 1; i < snake.size; i++)
                        {
                            snake.coor[i].x = -1;
                            snake.coor[i].y = -1;
                        }
                        if (aisnake[k].size+ snake.size - m < SNAKE_NUM) aisnake[k].size += snake.size - m;
                        else  aisnake[k].size = SNAKE_NUM;
                        aisnake[k].score.eat += score.eat ;
                        score.eat -= snake.size-m;
                        snake.size = m;
                    }
                }
            }
        }
    }
    judge.judgeeatsnake_player = 0;
    _endthread();
}
void eatsnake()
{
    if (0 == judge.judgeeatsnake_ai1) _beginthread(eatsnake_ai1, 0, NULL);
    if (0 == judge.judgeeatsnake_ai2) _beginthread(eatsnake_ai2, 0, NULL);
    if (0 == judge.judgeeatsnake_player) _beginthread(eatsnake_player, 0, NULL);

}

4.9移动蛇的相关操作

代码如下:

//蛇身跟随
void snakebodyFollow()
{
    for (int i = snake.size - 1; i > 0; i--)
    {
        snake.coor[i] = snake.coor[i - 1];
    };
}

//移动蛇头
void snakeheadMove(void*)
{
    judge.judge1 = 1;
    switch (snake.dir)
    {
    case UP:
    {
        snake.coor[0].y-= BasicSpeed;
        if (snake.coor[0].y <= 1)//蛇超出边界
        {
            snake.coor[0].y = Graph_y -1;//蛇回到下面边界
        }
    }break;
    case DOWN:
    {
        snake.coor[0].y+= BasicSpeed;
        if (snake.coor[0].y >= Graph_y - 1)
        {
            snake.coor[0].y = 1;
        };
    }break;
    case LEFT:
    {
        snake.coor[0].x-= BasicSpeed;
        if (snake.coor[0].x <= 1)
        {
            snake.coor[0].x = Graph_x -1;
        }
    }break;
    case RIGHT:
    {
        snake.coor[0].x+= BasicSpeed;
        if (snake.coor[0].x >= Graph_x - 1)
        {
            snake.coor[0].x = 1;
        }
    }break;
    }
    Sleep((int)((100+snake.size)/snake.speed));
    snakebodyFollow();
    judge.judge1 = 0;
    _endthread();
};

4.10排名表相关操作

代码如下:

//蛇排序
void sort()
{
    realtimescore[4].num = 4;
    realtimescore[4].score = snake.size;
    realtimescore[6].score = snake.size + score.kill * 200;
    _itoa_s(realtimescore[6].score, realtimescore[6].strscore, 10);
    strcpy_s(realtimescore[4].name,snake.name);
    for (int i = 0; i < AINUMBER; i++)
    {
        realtimescore[i].num = i;
        realtimescore[i].score = aisnake[i].size;
        strcpy_s(realtimescore[i].name,"AI");
    }

    //按照分数从大到小排序
    for (int i = 4; i > 0; i--)
    {
        for (int j = 0; j < i; j++)
        {
            if (realtimescore[j].score < realtimescore[j + 1].score)
            {
                realtimescore[5] = realtimescore[j];
                realtimescore[j] = realtimescore[j + 1];
                realtimescore[j + 1] = realtimescore[5];
            }
        }
    }
    for (int i = 0; i < 5; i++)
    {
        _itoa_s(realtimescore[i].score, realtimescore[i].strscore, 10);
    }
}

4.11画蛇

代码如下:

//绘制蛇
void GameDraw()
{
    BeginBatchDraw();//双缓冲绘图开始
    setbkcolor(RGB(28, 115, 119));//设置颜色
    cleardevice();//清空绘图设备
    setbkmode(TRANSPARENT);// 去掉文字背景
    settextstyle(30, 0, "楷体");
    settextcolor(0x0000ff);
    outtextxy(1100, 20, "排名表");
    sort();
    for (int i = 0; i < 5; i++)
    {
        if(4==realtimescore[i].num) settextcolor(RGB(255, 215, 0));
        else settextcolor(RGB(realtimescore[i].num*200, realtimescore[i].num*60, realtimescore[i].num*100));
        outtextxy(1050, 50+i*30, realtimescore[i].name);
        outtextxy(1200, 50+i*30, realtimescore[i].strscore);
    }
    
    for (int j = 0; j < snake.size; j++)
    {
        setfillcolor(RGB(180, j * 3, j * 5));
        if(snake.size>=0) snake.thickness = (int)log(snake.size);
        solidcircle(snake.coor[j].x, snake.coor[j].y, snake.thickness);
        
    }
    for (int i=0; i < AINUMBER; i++)
    {
        for (int k = 0; k < aisnake[i].size; k++)
        {
            setfillcolor(RGB(200 * i, i * 60, i * 100));
            if(aisnake[i].size>=0) aisnake[i].thickness = (int)log(aisnake[i].size);
            solidcircle(aisnake[i].coor[k].x, aisnake[i].coor[k].y, aisnake[i].thickness);
        }
    }
    for (int k = 0; k < MAXFOODNUMBER; k++)
    {
        if (food[k].flag)
        {
            setfillcolor(food[k].color);
            solidcircle(food[k].x, food[k].y, food[k].r);
        }
    }
    EndBatchDraw();//双缓冲绘图结束
};

4.12人工智障蛇
重复的部分比较多,还可以再优化
代码如下:

//AI初始化
void AIsetup()
{
    srand(clock());
    for (int i = 0; i < AINUMBER; i++)
    {
        aisnake[i].flag = true;
        aisnake[i].size = StartSize;//蛇一开始节数
        aisnake[i].speed = StartSpeed;
        aisnake[i].score.eat = 0;
        aisnake[i].score.kill = 0;
        for (int j=0; j < SNAKE_NUM; j++)
        {
            aisnake[i].coor[j].x = -2 - i;
            aisnake[i].coor[j].y = -2 - i;
        }
        switch (rand() % 4)
        {
        case 0:
        { 
            aisnake[i].snakexy.x = rand() % ((Graph_x - snakexy.x + 1) + snakexy.x);
            aisnake[i].snakexy.y = rand() % ((Graph_y - snakexy.y + 1) + snakexy.y);
            aisnake[i].dir = UP;
            for (int j = 0; j < aisnake[i].size; j++)
            {
                aisnake[i].coor[j].x = aisnake[i].snakexy.x;
                aisnake[i].coor[j].y = BasicSpeed * j + aisnake[i].snakexy.y;
            }
        }break;
        case 1:
        {
            aisnake[i].snakexy.x = rand() % (snakexy.x + 1);
            aisnake[i].snakexy.y = rand() % ((Graph_y - snakexy.y + 1) + snakexy.y);
            aisnake[i].dir = DOWN;
            for (int j = 0; j < aisnake[i].size; j++)
            {
                aisnake[i].coor[j].x = aisnake[i].snakexy.x;
                aisnake[i].coor[j].y = -BasicSpeed * j + aisnake[i].snakexy.y;
            }
        }break;
        case 2:
        {
            aisnake[i].snakexy.x = rand() % (snakexy.x + 1);
            aisnake[i].snakexy.y = rand() % (snakexy.y + 1);
            aisnake[i].dir = LEFT;
            for (int j = 0; j < aisnake[i].size; j++)
            {
                aisnake[i].coor[j].x = BasicSpeed * j + aisnake[i].snakexy.x;
                aisnake[i].coor[j].y = aisnake[i].snakexy.y;
            }
        }break;
        case 3:
        {
            aisnake[i].snakexy.x = rand() % (Graph_x - snakexy.x + 1) + snakexy.x;
            aisnake[i].snakexy.y = rand() % (snakexy.y + 1);
            aisnake[i].dir = RIGHT;
            for (int j = 0; j < aisnake[i].size; j++)
            {
                aisnake[i].coor[j].x = -BasicSpeed * j + aisnake[i].snakexy.x;
                aisnake[i].coor[j].y = aisnake[i].snakexy.y;
            }
        }break;
        };
    }
}

//AI行动
void AImove0(void*)
{
    judge.judge2_0 = 1;
    int i = 0;
    switch (aisnake[i].dir)
    {
    case UP:
    {
        aisnake[i].coor[0].y -= BasicSpeed;
        if (aisnake[i].coor[0].y <= 1)//蛇超出边界
        {
            aisnake[i].coor[0].y = Graph_y - 1;//蛇回到下面边界
        }
    }break;
    case DOWN:
    {
        aisnake[i].coor[0].y += BasicSpeed;
        if (aisnake[i].coor[0].y >= Graph_y - 1)
        {
            aisnake[i].coor[0].y = 1;
        }; 
    }break;
    case LEFT:
    {
        aisnake[i].coor[0].x -= BasicSpeed;
        if (aisnake[i].coor[0].x <= 1)
        {
            aisnake[i].coor[0].x = Graph_x - 1;
        }
    }break;
    case RIGHT:
    {
        aisnake[i].coor[0].x += BasicSpeed;
        if (aisnake[i].coor[0].x >= Graph_x - 1)
        {
            aisnake[i].coor[0].x = 1;
        }
    }break;
    };
    for (int j = aisnake[i].size - 1; j > 0; j--)
    {
        aisnake[i].coor[j] = aisnake[i].coor[j - 1];
    };
    Sleep((int)((100+aisnake[i].size)/ aisnake[0].speed));
    judge.judge2_0 = 0;
    _endthread();
}
void AImove1(void*)
{
    judge.judge2_1 = 1;
    int i = 1;
    switch (aisnake[i].dir)
    {
    case UP:
    {
        aisnake[i].coor[0].y -= BasicSpeed;
        if (aisnake[i].coor[0].y <= 1)//蛇超出边界
        {
            aisnake[i].coor[0].y = Graph_y - 1;//蛇回到下面边界
        }
    }break;
    case DOWN:
    {
        aisnake[i].coor[0].y += BasicSpeed;
        if (aisnake[i].coor[0].y >= Graph_y - 1)
        {
            aisnake[i].coor[0].y = 1;
        };
    }break;
    case LEFT:
    {
        aisnake[i].coor[0].x -= BasicSpeed;
        if (aisnake[i].coor[0].x <= 1)
        {
            aisnake[i].coor[0].x = Graph_x - 1;
        }
    }break;
    case RIGHT:
    {
        aisnake[i].coor[0].x += BasicSpeed;
        if (aisnake[i].coor[0].x >= Graph_x - 1)
        {
            aisnake[i].coor[0].x = 1;
        }
    }break;
    };
    for (int j = aisnake[i].size - 1; j > 0; j--)
    {
        aisnake[i].coor[j] = aisnake[i].coor[j - 1];
    };
    Sleep((int)((100 + aisnake[i].size) / aisnake[0].speed));
    judge.judge2_1 = 0;
    _endthread();
}
void AImove2(void*)
{
    judge.judge2_2 = 1;
    int i = 2;
    switch (aisnake[i].dir)
    {
    case UP:
    {
        aisnake[i].coor[0].y -= BasicSpeed;
        if (aisnake[i].coor[0].y <= 1)//蛇超出边界
        {
            aisnake[i].coor[0].y = Graph_y - 1;//蛇回到下面边界
        }
    }break;
    case DOWN:
    {
        aisnake[i].coor[0].y += BasicSpeed;
        if (aisnake[i].coor[0].y >= Graph_y - 1)
        {
            aisnake[i].coor[0].y = 1;
        };
    }break;
    case LEFT:
    {
        aisnake[i].coor[0].x -= BasicSpeed;
        if (aisnake[i].coor[0].x <= 1)
        {
            aisnake[i].coor[0].x = Graph_x - 1;
        }
    }break;
    case RIGHT:
    {
        aisnake[i].coor[0].x += BasicSpeed;
        if (aisnake[i].coor[0].x >= Graph_x - 1)
        {
            aisnake[i].coor[0].x = 1;
        }
    }break;
    };
    for (int j = aisnake[i].size - 1; j > 0; j--)
    {
        aisnake[i].coor[j] = aisnake[i].coor[j - 1];
    };
    Sleep((int)((100 + aisnake[i].size) / aisnake[0].speed));
    judge.judge2_2 = 0;
    _endthread();
}
void AImove3(void*)
{
    judge.judge2_3 = 1;
    int i = 3;
    switch (aisnake[i].dir)
    {
    case UP:
    {
        aisnake[i].coor[0].y -= BasicSpeed;
        if (aisnake[i].coor[0].y <= 1)//蛇超出边界
        {
            aisnake[i].coor[0].y = Graph_y - 1;//蛇回到下面边界
        }
    }break;
    case DOWN:
    {
        aisnake[i].coor[0].y += BasicSpeed;
        if (aisnake[i].coor[0].y >= Graph_y - 1)
        {
            aisnake[i].coor[0].y = 1;
        };
    }break;
    case LEFT:
    {
        aisnake[i].coor[0].x -= BasicSpeed;
        if (aisnake[i].coor[0].x <= 1)
        {
            aisnake[i].coor[0].x = Graph_x - 1;
        }
    }break;
    case RIGHT:
    {
        aisnake[i].coor[0].x += BasicSpeed;
        if (aisnake[i].coor[0].x >= Graph_x - 1)
        {
            aisnake[i].coor[0].x = 1;
        }
    }break;
    };
    for (int j = aisnake[i].size - 1; j > 0; j--)
    {
        aisnake[i].coor[j] = aisnake[i].coor[j - 1];
    };
    Sleep((int)((100 + aisnake[i].size) / aisnake[0].speed));
    judge.judge2_3 = 0;
    _endthread();
}
void AImove()
{
    if (0 == judge.judge2_0)  _beginthread(AImove0, 0, NULL);
    if (0 == judge.judge2_1)  _beginthread(AImove1, 0, NULL);
    if (0 == judge.judge2_2)  _beginthread(AImove2, 0, NULL);
    if (0 == judge.judge2_3)  _beginthread(AImove3, 0, NULL);
}
//AI方向
void turn(int x0,int y0,int x,int y,int i)//x0,y0为蛇头位置,x,y为目标点
{
    if (abs(x - x0) > abs(y - y0))
    {
        if (x >= x0/*&& aisnake[i].dir != LEFT*/) aisnake[i].dir = RIGHT;
        if(x<x0/*&& aisnake[i].dir != RIGHT*/) aisnake[i].dir = LEFT;
    }
    else
    {
        if (y >= y0/*&& aisnake[i].dir != UP*/) aisnake[i].dir = DOWN;
        if(y<y0/*&& aisnake[i].dir != DOWN*/) aisnake[i].dir = UP;
    }
}

//人工智能
void artificial0(void *)
{
    judge.judgeai0 = 1;
    int k = 0;
    int targetx=0;
    int targety=0;
    //寻找最近的可吃物体
    int d= Graph_x* Graph_x,d0 = Graph_x* Graph_x;
    
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if(food[i].flag==true)
        { 
            d = -(food[i].r + aisnake[k].thickness) * (food[i].r + aisnake[k].thickness) + ((aisnake[k].coor[0].x - food[i].x) * (aisnake[k].coor[0].x - food[i].x) + (aisnake[k].coor[0].y - food[i].y) * (aisnake[k].coor[0].y - food[i].y));
            if (d < d0)
            {
                d0 = d;
                targetx = food[i].x;
                targety = food[i].y;
            }
        }
        
    }
    int j;
    j = 1;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if(aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 2;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 3;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }

    for (int m = 5; m < snake.size; m++)
    {
        d = ((aisnake[k].coor[0].x - snake.coor[m].x) * (aisnake[k].coor[0].x - snake.coor[m].x) + (aisnake[k].coor[0].y - snake.coor[m].y) * (aisnake[k].coor[0].y - snake.coor[m].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = snake.coor[m].x;
            targety = snake.coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - snake.coor[0].x) * (aisnake[k].coor[0].x - snake.coor[0].x) + (aisnake[k].coor[0].y - snake.coor[0].y) * (aisnake[k].coor[0].y - snake.coor[0].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < snake.size)
        {
            targetx = -snake.coor[0].x;
            targety = -snake.coor[0].y;
        }
        else
        {
            targetx = snake.coor[0].x;
            targety = snake.coor[0].y;
        }
    }
    turn(aisnake[k].coor[0].x, aisnake[k].coor[0].y, targetx, targety, k);
    judge.judgeai0 = 0;
    _endthread();

}
void artificial1(void*)
{
    judge.judgeai1 = 1;
    int k = 1;
    int targetx=0;
    int targety=0;
    //寻找最近的可吃物体
    int d = Graph_x* Graph_x, d0 = Graph_x* Graph_x;
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if (food[i].flag == true)
        {
            d = -(food[i].r + aisnake[k].thickness) * (food[i].r + aisnake[k].thickness) + ((aisnake[k].coor[0].x - food[i].x) * (aisnake[k].coor[0].x - food[i].x) + (aisnake[k].coor[0].y - food[i].y) * (aisnake[k].coor[0].y - food[i].y));
            if (d < d0)
            {
                d0 = d;
                targetx = food[i].x;
                targety = food[i].y;
            }
        }

    }
    int j;
    j = 0;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 2;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 3;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }

    for (int m = 5; m < snake.size; m++)
    {
        d = ((aisnake[k].coor[0].x - snake.coor[m].x) * (aisnake[k].coor[0].x - snake.coor[m].x) + (aisnake[k].coor[0].y - snake.coor[m].y) * (aisnake[k].coor[0].y - snake.coor[m].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = snake.coor[m].x;
            targety = snake.coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - snake.coor[0].x) * (aisnake[k].coor[0].x - snake.coor[0].x) + (aisnake[k].coor[0].y - snake.coor[0].y) * (aisnake[k].coor[0].y - snake.coor[0].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < snake.size)
        {
            targetx = -snake.coor[0].x;
            targety = -snake.coor[0].y;
        }
        else
        {
            targetx = snake.coor[0].x;
            targety = snake.coor[0].y;
        }
    }
    turn(aisnake[k].coor[0].x, aisnake[k].coor[0].y, targetx, targety, k);
    judge.judgeai1 = 0;
    _endthread();
}
void artificial2(void*)
{
    judge.judgeai2 = 1;
    int k = 2;
    //寻找最近的可吃物体
    int targetx=0;
    int targety=0;
    int d = Graph_x* Graph_x, d0 = Graph_x* Graph_x;
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if (food[i].flag == true)
        {
            d = -(food[i].r + aisnake[k].thickness) * (food[i].r + aisnake[k].thickness) + ((aisnake[k].coor[0].x - food[i].x) * (aisnake[k].coor[0].x - food[i].x) + (aisnake[k].coor[0].y - food[i].y) * (aisnake[k].coor[0].y - food[i].y));
            if (d < d0)
            {
                d0 = d;
                targetx = food[i].x;
                targety = food[i].y;
            }
        }

    }
    int j;
    j = 1;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 0;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 3;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }

    for (int m = 5; m < snake.size; m++)
    {
        d = ((aisnake[k].coor[0].x - snake.coor[m].x) * (aisnake[k].coor[0].x - snake.coor[m].x) + (aisnake[k].coor[0].y - snake.coor[m].y) * (aisnake[k].coor[0].y - snake.coor[m].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = snake.coor[m].x;
            targety = snake.coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - snake.coor[0].x) * (aisnake[k].coor[0].x - snake.coor[0].x) + (aisnake[k].coor[0].y - snake.coor[0].y) * (aisnake[k].coor[0].y - snake.coor[0].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < snake.size)
        {
            targetx = -snake.coor[0].x;
            targety = -snake.coor[0].y;
        }
        else
        {
            targetx = snake.coor[0].x;
            targety = snake.coor[0].y;
        }
    }
    turn(aisnake[k].coor[0].x, aisnake[k].coor[0].y, targetx, targety, k);
    judge.judgeai2 = 0;
    _endthread();
}
void artificial3(void*)
{
    judge.judgeai3 = 1;
    int k = 3;
    //寻找最近的可吃物体
    int targetx=0;
    int targety=0;
    int d = Graph_x* Graph_x, d0 = Graph_x* Graph_x;
    for (int i = 0; i < MAXFOODNUMBER; i++)
    {
        if (food[i].flag == true)
        {
            d = -(food[i].r + aisnake[k].thickness) * (food[i].r + aisnake[k].thickness) + ((aisnake[k].coor[0].x - food[i].x) * (aisnake[k].coor[0].x - food[i].x) + (aisnake[k].coor[0].y - food[i].y) * (aisnake[k].coor[0].y - food[i].y));
            if (d < d0)
            {
                d0 = d;
                targetx = food[i].x;
                targety = food[i].y;
            }
        }

    }
    int j;
    j = 1;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 2;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }
    j = 0;
    for (int m = 5; m < aisnake[j].size; m++)
    {
        d = ((aisnake[k].coor[0].x - aisnake[j].coor[m].x) * (aisnake[k].coor[0].x - aisnake[j].coor[m].x) + (aisnake[k].coor[0].y - aisnake[j].coor[m].y) * (aisnake[k].coor[0].y - aisnake[j].coor[m].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = aisnake[j].coor[m].x;
            targety = aisnake[j].coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - aisnake[j].coor[0].x) * (aisnake[k].coor[0].x - aisnake[j].coor[0].x) + (aisnake[k].coor[0].y - aisnake[j].coor[0].y) * (aisnake[k].coor[0].y - aisnake[j].coor[0].y)) - (aisnake[k].thickness + aisnake[j].thickness) * (aisnake[k].thickness + aisnake[j].thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < aisnake[j].size)
        {
            targetx = -aisnake[j].coor[0].x;
            targety = -aisnake[j].coor[0].y;
        }
        else
        {
            targetx = aisnake[j].coor[0].x;
            targety = aisnake[j].coor[0].y;
        }
    }

    for (int m = 5; m < snake.size; m++)
    {
        d = ((aisnake[k].coor[0].x - snake.coor[m].x) * (aisnake[k].coor[0].x - snake.coor[m].x) + (aisnake[k].coor[0].y - snake.coor[m].y) * (aisnake[k].coor[0].y - snake.coor[m].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
        if (d < d0)
        {
            d0 = d;
            targetx = snake.coor[m].x;
            targety = snake.coor[m].y;
        }
    }
    d = ((aisnake[k].coor[0].x - snake.coor[0].x) * (aisnake[k].coor[0].x - snake.coor[0].x) + (aisnake[k].coor[0].y - snake.coor[0].y) * (aisnake[k].coor[0].y - snake.coor[0].y)) - (aisnake[k].thickness + snake.thickness) * (aisnake[k].thickness + snake.thickness);
    if (d < d0)
    {
        d0 = d;
        if (aisnake[k].size < snake.size)
        {
            targetx = -snake.coor[0].x;
            targety = -snake.coor[0].y;
        }
        else
        {
            targetx = snake.coor[0].x;
            targety = snake.coor[0].y;
        }
    }
    turn(aisnake[k].coor[0].x, aisnake[k].coor[0].y, targetx, targety, k);
    judge.judgeai3 = 0;
    _endthread();
}
void artificial(void*)
{
    judge.judgeai = 1;
    while (judge.judgemenu == 2)
    {
        if (0 == judge.judgeai0)  _beginthread(artificial0, 0, NULL);
        if (0 == judge.judgeai1)  _beginthread(artificial1, 0, NULL);
        if (0 == judge.judgeai2)  _beginthread(artificial2, 0, NULL);
        if (0 == judge.judgeai3)  _beginthread(artificial3, 0, NULL);
        Sleep(5);
    }
    judge.judgeai = 0;
    _endthread();
}

4.13蛇随时间变短

代码如下:

//蛇随时间变短
void shortsnake(void*)
{
    judge.judgeshortsnake = 1;
    for (int i = 0; i < AINUMBER; i++)
    {
        
        if (0 == aisnake[i].size)
        {
            aisnake[i].flag = false;
            for (int k = 0; k < aisnake[i].size; k++)
            {
                aisnake[i].coor[k].x = -2 - i;
                aisnake[i].coor[k].y = -2 - i;
            }
        }
        else
        {
            aisnake[i].coor[aisnake[i].size-1].x = -2-i;
            aisnake[i].coor[aisnake[i].size-1].y = -2-i;
            aisnake[i].size--;
            aisnake[i].score.eat--;
        }
    }
    if (judge.shortsnaketime > 100)
        judge.shortsnaketime--;
    if (0 == snake.size)
    {
        snake.flag = false;
        for (int k = 0; k < snake.size; k++)
        {
            snake.coor[k].x = -1;
            snake.coor[k].y = -1;
        }
    }
    else 
    {
        if (snake.speed == StartSpeed)
        {
            snake.coor[snake.size - 1].x = -1;
            snake.coor[snake.size - 1].y = -1;
            snake.size--;
            score.eat--;
        }
        else
        {
            snake.coor[snake.size - 1].x = -1;
            snake.coor[snake.size - 1].y = -1;
            snake.coor[snake.size - 2].x = -1;
            snake.coor[snake.size - 2].y = -1;
            snake.coor[snake.size - 3].x = -1;
            snake.coor[snake.size - 3].y = -1;
            snake.size-=3;
            score.eat-=3;
        }
    }
    Sleep(judge.shortsnaketime);
    judge.judgeshortsnake = 0;
    _endthread();
}

4.14游戏菜单

代码如下:

//游戏初始菜单
void startmenu()
{
    music();
    if (3 != judge.judgementmusic)
    {
        mciSendString("stop BGM2", 0, 0, 0);
        mciSendString("close BGM2", 0, 0, 0);
        mciSendString("stop BGM1", 0, 0, 0);
        mciSendString("close BGM1", 0, 0, 0);
        mciSendString(c.data, 0, 0, 0);
        mciSendString("play BGM3 repeat", 0, 0, 0);
        judge.judgementmusic = 3;
    }
    while (judge.judgemenu == 0)
    {
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        BeginBatchDraw();//双缓冲绘图开始
        cleardevice();//清空绘图设备
        setbkcolor(RGB(28, 115, 119));//设置颜色
        setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色
        fillrectangle(400, 250, 800, 350);
        fillrectangle(400, 400, 800, 500);
        fillrectangle(400, 550, 800, 650);
        setbkmode(TRANSPARENT);// 去掉文字背景
        settextstyle(160, 0, "楷体");
        settextcolor(RGB(255,97,3));
        outtextxy(180, 50, "贪吃蛇大作战");
        settextstyle(30, 0, "楷体");//设置文字大小 格式
        settextcolor(RGB(0, 255,0));
        outtextxy(1080, 650, "作者:绿螳螂");
        settextstyle(100, 0, "楷体");
        settextcolor(WHITE);
        outtextxy(400, 250, "游戏说明");
        outtextxy(400, 400, "开始游戏");
        outtextxy(400, 550, "退出游戏");
        if (msg.x >= 400 && msg.x <= 800 && msg.y >= 250 && msg.y <= 350) 
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 240, 810, 360);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 1;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 400 && msg.y <= 500)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 390, 810, 510);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 2;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 550 && msg.y <= 650)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 540, 810, 660);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 3;
            }
        }
        //一旦鼠标不在相应位置 将画出白色边框 覆盖之前的红色边框
        else 
        {
            setlinecolor(RGB(28, 115, 119));
            rectangle(390, 140, 810, 260);
            rectangle(390, 290, 810, 410);
            rectangle(390, 440, 810, 560);
        }
        EndBatchDraw();//双缓冲绘图结束
    }
}

//结束判定
void over(void*)
{
    judge.judgegameover = 1;
    if (snake.flag == false||snake.size<=0)  judge.judgemenu = 4;
    judge.judgegameover = 0;
    _endthread();
}

//游戏说明
void gameshow()
{
    
    while (1 == judge.judgemenu)
    {
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        BeginBatchDraw();//双缓冲绘图开始
        cleardevice();//清空绘图设备
        setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色
        fillrectangle(180, 200, 1080, 520);
        fillrectangle(180, 550, 580, 650);
        fillrectangle(680, 550, 1080, 650);
        setbkmode(TRANSPARENT);// 去掉文字背景
        settextstyle(150, 0, "楷体");
        settextcolor(RGB(160, 32, 240));
        outtextxy(320, 30, "游戏说明");
        settextstyle(30, 0, "楷体");
        settextcolor(RGB(255, 255, 0));
        outtextxy(190, 210, "欢迎来到贪吃蛇大作战,你是屏幕中间彩色的蛇");
        outtextxy(190, 240, "在这个游戏中你将同人工智障战斗,右边是各个蛇的长度的排名表");
        outtextxy(190, 270, "不要担心,你不会撞墙也不会吃掉自己");
        outtextxy(190, 300, "你可能饿死或者被人工智障干掉,被干掉可以重新开始");
        outtextxy(190, 330, "WASD以及方向键都可以控制蛇的方向,刚开始可能比较难以控制");
        outtextxy(190, 360, "按住空格键加速,加速的同时也会加速饥饿,ESC键可以暂停游戏");
        outtextxy(190, 390, "吃食物可以增加得分以及蛇的长度,蛇越长跑的越慢");
        outtextxy(190, 420, "你可以轻易吃掉人工智障的蛇身,但同样它们也能吃你");
        outtextxy(190, 450, "如果蛇头相撞,大蛇会整个吃掉小蛇,吃掉一条蛇得200分");
        outtextxy(190, 480, "适度游戏益脑,沉迷游戏伤身,千万不要上头哦,祝你游戏愉快");
        settextstyle(100, 0, "楷体");//设置文字大小 格式
        settextcolor(WHITE);
        outtextxy(180, 550, "开始游戏");
        outtextxy(680, 550, "退出游戏");
        if (msg.x >= 180 && msg.x <= 580 && msg.y >= 550 && msg.y <= 650)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(170, 540, 590, 660);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 2;
            }
        }
        else if (msg.x >= 680 && msg.x <= 1080 && msg.y >= 550 && msg.y <= 650)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(670, 540, 1090, 660);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 3;
            }
        }
        EndBatchDraw();//双缓冲绘图结束
    }
}

//结束界面
void gameover()
{
    int judgehigh=0;
    FILE* fp;
    char high[20];
    if (errno_t err = fopen_s(&fp, "./data.txt", "ab+") != 0)
    {
        puts("要写入的文件出错,按任意键退出");
        Sleep(5000);
        exit(0);
    }
    if (realtimescore[6].score > judge.judgehigh)
    {
        fprintf(fp, "%d\n", realtimescore[6].score);
        judgehigh = 1;
    }
    fclose(fp);
    _itoa_s(judge.judgehigh, high, 10);
    while (judge.judgemenu == 4)
    {
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        if (2 != judge.judgementmusic)
        {
            mciSendString("stop BGM1", 0, 0, 0);
            mciSendString("close BGM1", 0, 0, 0);
            mciSendString("stop BGM3", 0, 0, 0);
            mciSendString("close BGM3", 0, 0, 0);
            mciSendString(b.data, 0, 0, 0);
            mciSendString("play BGM2 repeat", 0, 0, 0);
            judge.judgementmusic = 2;
        }
        BeginBatchDraw();//双缓冲绘图开始
        cleardevice();//清空绘图设备
        setbkcolor(RGB(28, 115, 119));//设置颜色
        setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色
        fillrectangle(400, 250, 800, 350);
        fillrectangle(400, 400, 800, 500);
        fillrectangle(400, 550, 800, 650);
        setbkmode(TRANSPARENT);// 去掉文字背景
        settextstyle(120, 0, "楷体");
        settextcolor(RGB(255, 97, 3));
        outtextxy(380, 20, "游戏结束");
        if (0 == judgehigh)
        {
            settextstyle(60, 0, "楷体");
            settextcolor(RGB(255, 215, 0));
            outtextxy(300, 130, "最终得分:");
            outtextxy(800, 130, realtimescore[6].strscore);
            settextstyle(40, 0, "楷体");
            settextcolor(RGB(0, 215, 255));
            outtextxy(300, 190, "最高得分:");
            outtextxy(800, 190, high);
        }
        else
        {
            settextstyle(60, 0, "楷体");
            settextcolor(RGB(255, 215, 0));
            outtextxy(300, 130, "最终得分:");
            outtextxy(800, 130, realtimescore[6].strscore);
            settextstyle(40, 0, "楷体");
            settextcolor(RGB(255, 69, 0));
            outtextxy(300, 190, "恭喜你获得了历史最高分!");
        }
        settextstyle(100, 0, "楷体");//设置文字大小 格式
        settextcolor(WHITE);
        outtextxy(400, 250, "游戏说明");
        outtextxy(400, 400, "重新开始");
        outtextxy(400, 550, "退出游戏");
        if (msg.x >= 400 && msg.x <= 800 && msg.y >= 250 && msg.y <= 350)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 240, 810, 360);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 1;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 400 && msg.y <= 500)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 390, 810, 510);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 2;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 550 && msg.y <= 650)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 540, 810, 660);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 3;
            }
        }
        //一旦鼠标不在相应位置 将画出白色边框 覆盖之前的红色边框
        else
        {
            setlinecolor(RGB(28, 115, 119));
            rectangle(390, 140, 810, 260);
            rectangle(390, 290, 810, 410);
            rectangle(390, 440, 810, 560);
        }
        EndBatchDraw();//双缓冲绘图结束
    }
}

//暂停界面
void gamepause()
{
    while (1 == judge.judgepause)
    {
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        BeginBatchDraw();//双缓冲绘图开始
        cleardevice();//清空绘图设备
        setbkcolor(RGB(28, 115, 119));//设置颜色
        setfillcolor(LIGHTBLUE); //设置后面用函数画出方框的背景颜色 这里设置成了浅蓝色
        fillrectangle(400, 250, 800, 350);
        fillrectangle(400, 400, 800, 500);
        fillrectangle(400, 550, 800, 650);
        setbkmode(TRANSPARENT);// 去掉文字背景
        settextstyle(120, 0, "楷体");
        settextcolor(RGB(255, 97, 3));
        outtextxy(480, 20, "暂停");
        settextstyle(100, 0, "楷体");
        settextcolor(RGB(255, 215, 0));
        outtextxy(300, 130, "当前得分:");
        outtextxy(800, 130, realtimescore[6].strscore);
        settextstyle(100, 0, "楷体");//设置文字大小 格式
        settextcolor(WHITE);
        outtextxy(400, 250, "继续游戏");
        outtextxy(400, 400, "重新开始");
        outtextxy(400, 550, "退出游戏");
        if (msg.x >= 400 && msg.x <= 800 && msg.y >= 250 && msg.y <= 350)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 240, 810, 360);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 2;
                judge.judgepause = 0;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 400 && msg.y <= 500)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 390, 810, 510);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 0;
                judge.judgepause = 0;
            }
        }
        else if (msg.x >= 400 && msg.x <= 800 && msg.y >= 550 && msg.y <= 650)
        {//检测鼠标的位置 是否满足条件
            setlinecolor(RED);//满足后 设置新的边框为红色
            rectangle(390, 540, 810, 660);//画新的边框
            if (msg.uMsg == WM_LBUTTONDOWN) {
                judge.judgemenu = 3;
                judge.judgepause = 0;
            }
        }
        //一旦鼠标不在相应位置 将画出白色边框 覆盖之前的红色边框
        else
        {
            setlinecolor(RGB(28, 115, 119));
            rectangle(390, 140, 810, 260);
            rectangle(390, 290, 810, 410);
            rectangle(390, 440, 810, 560);
        }
        EndBatchDraw();//双缓冲绘图结束
    }
}

4.15音乐函数
主要存储音乐的地址(链表是假的,为了凑作业得分)
代码如下:

void music()
{
    TYPE* head, * p;
    strcpy_s(a.data, "open ./1.bgm.mp3 alias BGM1");
    strcpy_s(b.data, "open ./2.bgm.mp3 alias BGM2");
    strcpy_s(c.data, "open ./3.bgm.mp3 alias BGM3");
    head = &a;
    a.next = &b;
    b.next = &c;
    c.next = NULL;
    p = head;//把首地址给变量
}

4.16游戏函数
主要用于各种多线程函数的判断与调用
代码如下:

//游戏
void GAME()
{
    GameInit();
    aisnake = (struct AISnake*)malloc(sizeof(struct AISnake) * AINUMBER);//动态开辟aisnake
    if (aisnake == NULL)
    {
        printf("内存不足");
        exit(1);
    }
    AIsetup();
    while (judge.judgemenu == 2)
    {
        if (0 == judge.judgekeycontrol) _beginthread(keyControl, 0, NULL);
        gamepause();
        if (0 == judge.judgemouse) _beginthread(mousetest, 0, NULL);
        GameDraw();
        if (0 == judge.judgeai) _beginthread(artificial, 0, NULL);
        if (0 == judge.judgecreatfood) _beginthread(CreateFood, 0, NULL);
        AImove();
        if (0 == judge.judge1)  _beginthread(snakeheadMove, 0, NULL);
        if (0 == judge.judgeeatfood) _beginthread(eatfood, 0, NULL);
        eatsnake();
        if (0 == judge.judgeshortsnake) _beginthread(shortsnake, 0, NULL);
        if (0 == judge.judgegameover) _beginthread(over, 0, NULL);
    }
}

总结

优点:
完全图形化界面,鼠标操作,简单便捷
高清贪吃蛇,美观程度高
高反应速度,按键高容错率,程序不会崩溃
AI智能度高,游戏具有挑战性,有意思
蛇可以加速,玩家具有独特性
蛇会随时间缩短,蛇加速会加快缩短

创新之处:
打破传统意义上蛇撞墙和撞自己就会死,采用无边界对战模式,蛇撞不到自己也不会撞墙
打破传统贪吃蛇大作战模式,蛇头撞其他蛇身体会直接吃掉其他蛇
评分实时可见,加强了挑战性
可随时暂停并继续
加入大量鬼畜音乐,加强体验感

不足之处:
线程过多
优化有所欠缺
更多细节之处待完善

需要改进的地方:
无法调整难度,默认地狱难度,可能导致玩家砸电脑


参考文章

[1]https://blog.csdn.net/wyq_tc25/article/details/51577657?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162324908216780269819954%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162324908216780269819954&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-7-51577657.first_rank_v2_pc_rank_v29&utm_term=c%E8%AF%AD%E8%A8%80%E5%A4%9A%E7%BA%BF%E7%A8%8B&spm=1018.2226.3001.4187
[2]https://blog.csdn.net/chenaifeiwu99/article/details/80303936?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162324920716780366576077%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162324920716780366576077&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-80303936.first_rank_v2_pc_rank_v29&utm_term=c%E8%AF%AD%E8%A8%80%E6%94%BE%E9%9F%B3%E4%B9%90&spm=1018.2226.3001.4187
[3]https://www.bilibili.com/video/BV1LN41197zV?from=search&seid=1933684175862948802
[4]https://blog.csdn.net/weixin_44127339/article/details/104498559?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162429089216780274136646%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162429089216780274136646&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-104498559.first_rank_v2_pc_rank_v29&utm_term=c%E8%AF%AD%E8%A8%80%E4%B8%AD%E6%96%87%E5%AD%97%E7%AC%A6%E4%B8%B2&spm=1018.2226.3001.4187

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GREEN_MANTIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值