C++贪吃蛇---详细步骤

软件准备:

一、游戏窗口绘制

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;

int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();

    // 游戏主循环
    while (true) {
        
    }
    return 0;
}

二、蛇

1、初始化数据

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
}


int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        
    }
    return 0;
}

2、画蛇

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
}

// 画蛇 
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }
}


int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
    }
    return 0;
}

3、让蛇自己动起来

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
}

// 画蛇
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }
}

// 让蛇动起来
void GameMove() {

    // 循环部分 - 控制蛇身移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.coor[i].x = snake.coor[i - 1].x;
        snake.coor[i].y = snake.coor[i - 1].y;
    }

    // switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]
    switch (snake.dir) {
    case UP:
        snake.coor[0].y -= snake.speed;
        break;
    case DOWN:
        snake.coor[0].y += snake.speed;
        break;
    case LEFT:
        snake.coor[0].x -= snake.speed;
        break;
    case RIGHT:
        snake.coor[0].x += snake.speed;
        break;
    }
}


int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
    }
    return 0;
}

4、用键盘控制蛇的方向

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
}

// 画蛇
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }
}

// 让蛇动起来
void GameMove() {

    // 循环部分 - 控制蛇身移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.coor[i].x = snake.coor[i - 1].x;
        snake.coor[i].y = snake.coor[i - 1].y;
    }

    // switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]
    switch (snake.dir) {
    case UP:
        snake.coor[0].y -= snake.speed;
        break;
    case DOWN:
        snake.coor[0].y += snake.speed;
        break;
    case LEFT:
        snake.coor[0].x -= snake.speed;
        break;
    case RIGHT:
        snake.coor[0].x += snake.speed;
        break;
    }
}

//控制蛇的方向
void GameController() {
    // 获取键盘
    char key = _getch();

    // 控制蛇不能往回走
    switch (key) {
        case 72: if (snake.dir != DOWN) snake.dir = UP; break;
        case 80: if (snake.dir != UP) snake.dir = DOWN; break;
        case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;
        case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;
    }
    //cout << (int)key << endl;
}
int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
        // 如果按了键盘就会执行
        if (_kbhit()) {
            GameController();
        }
        
    }
    return 0;
}

三、食物

1、初始化数据

cpp 复制代码
struct Food {
    int x;
    int y;
    DWORD color;
    bool flag; // 是否被吃掉
} food;
cpp 复制代码
// 初始化食物 随机分布
food.x = rand() % (WIDTH / 10) * 10;
food.y = rand() % (HEIGHT / 10) * 10;
food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
food.flag = true;

2、画食物

在GameDraw函数添加以下代码:

cpp 复制代码
// 绘制食物
if (food.flag)
{
    setfillcolor(food.color);
    solidellipse(food.x, food.y, food.x + 10, food.y + 10);
}

完整代码:

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

struct Food {
    int x;
    int y;
    DWORD color;
    bool flag; // 是否被吃掉
} food;

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
    // 初始化食物 随机分布
    food.x = rand() % (WIDTH / 10) * 10;
    food.y = rand() % (HEIGHT / 10) * 10;
    food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
    food.flag = true;
}

// 画蛇 画食物
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }

    // 绘制食物
    if (food.flag)
    {
        setfillcolor(food.color);
        solidellipse(food.x, food.y, food.x + 10, food.y + 10);
    }
}

// 让蛇动起来
void GameMove() {

    // 循环部分 - 控制蛇身移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.coor[i].x = snake.coor[i - 1].x;
        snake.coor[i].y = snake.coor[i - 1].y;
    }

    // switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]
    switch (snake.dir) {
    case UP:
        snake.coor[0].y -= snake.speed;
        break;
    case DOWN:
        snake.coor[0].y += snake.speed;
        break;
    case LEFT:
        snake.coor[0].x -= snake.speed;
        break;
    case RIGHT:
        snake.coor[0].x += snake.speed;
        break;
    }
}

//控制蛇的方向
void GameController() {
    // 获取键盘
    char key = _getch();

    // 控制蛇不能往回走
    switch (key) {
        case 72: if (snake.dir != DOWN) snake.dir = UP; break;
        case 80: if (snake.dir != UP) snake.dir = DOWN; break;
        case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;
        case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;
    }
    //cout << (int)key << endl;
}
int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
        // 如果按了键盘就会执行
        if (_kbhit()) {
            GameController();
        }
        
    }
    return 0;
}

3、碰撞检测(是否吃到食物)

cpp 复制代码
void EatFood() {
    // 碰撞检测
    if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y)
    {
        // 吃到了
        food.flag = false;
        snake.num++;
        snake.score += 10;
        snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);
        // 吃完了 在重新创建一个新的食物
        food.x = rand() % (WIDTH / 10) * 10;
	    food.y = rand() % (HEIGHT / 10) * 10;
	    food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
	    food.flag = true;
    }
}
cpp 复制代码
    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
        // 如果按了键盘就会执行
        if (_kbhit()) {
            GameController();
        }
        EatFood();     
    }

这里可以发现,食物被吃完后, 需要随机生成,可以把生成食物的代码封装为一个函数。

cpp 复制代码
// 创建新食物的函数
void createFood() {
    food.x = rand() % (WIDTH / 10) * 10;
    food.y = rand() % (HEIGHT / 10) * 10;
    food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
    food.flag = true;
}

完整代码:

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

struct Food {
    int x;
    int y;
    DWORD color;
    bool flag; // 是否被吃掉
} food;

// 创建新食物的函数
void createFood() {
    food.x = rand() % (WIDTH / 10) * 10;
    food.y = rand() % (HEIGHT / 10) * 10;
    food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
    food.flag = true;
}

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
    // 初始化食物 随机分布
    createFood();
}

// 画蛇 画食物 画分数
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }

    // 绘制食物
    if (food.flag)
    {
        setfillcolor(food.color);
        solidellipse(food.x, food.y, food.x + 10, food.y + 10);
    }
}

// 让蛇动起来
void GameMove() {

    // 循环部分 - 控制蛇身移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.coor[i].x = snake.coor[i - 1].x;
        snake.coor[i].y = snake.coor[i - 1].y;
    }

    // switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]
    switch (snake.dir) {
    case UP:
        snake.coor[0].y -= snake.speed;
        break;
    case DOWN:
        snake.coor[0].y += snake.speed;
        break;
    case LEFT:
        snake.coor[0].x -= snake.speed;
        break;
    case RIGHT:
        snake.coor[0].x += snake.speed;
        break;
    }
}

//控制蛇的方向
void GameController() {
    // 获取键盘
    char key = _getch();

    // 控制蛇不能往回走
    switch (key) {
        case 72: if (snake.dir != DOWN) snake.dir = UP; break;
        case 80: if (snake.dir != UP) snake.dir = DOWN; break;
        case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;
        case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;
    }
    //cout << (int)key << endl;
}




void EatFood() {
    // 碰撞检测
    if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y)
    {
        // 吃到了
        food.flag = false;
        snake.num++;
        snake.score += 10;
        snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);
        // 吃完了 在重新创建一个新的食物
        createFood();
    }
}


int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
        // 如果按了键盘就会执行
        if (_kbhit()) {
            GameController();
        }
        EatFood();     
    }
    return 0;
}

四、添加分数

cpp 复制代码
 // 绘制分数
 char temp[20] = "";
 sprintf(temp, "分数: %d", snake.score);
 outtextxy(10, 10, temp);

这个函数outtextxy添加后,需要设置一下才能使用,操作如下:


五、项目完整代码

cpp 复制代码
// 导入图形界面库 EasyX
#include <graphics.h>
//控制键盘的头文件
#include<conio.h>
#include<iostream>
using namespace std;

// 定义游戏区域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500  // 常量

struct Pos {
    int x;
    int y;
    DWORD color;//DWORD 是 Windows API 中定义的数据类型
};

struct Snake {
    int num;      // 蛇身体的节数
    int dir;      // 蛇的方向
    int score;    // 分数
    int size;     // 蛇的宽和高
    int speed;    // 蛇的速度
    // 记录蛇的坐标数组
    struct Pos coor[MAX_SNAKE];
};

struct Snake snake;//结构体变量

enum DIR
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

struct Food {
    int x;
    int y;
    DWORD color;
    bool flag; // 是否被吃掉
} food;

// 创建新食物的函数
void createFood() {
    food.x = rand() % (WIDTH / 10) * 10;
    food.y = rand() % (HEIGHT / 10) * 10;
    food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
    food.flag = true;
}

// 初始化一下数据
void GameInit() {

    //蛇的身体的颜色随机变化
    srand(GetTickCount());

    snake.num = 3;
    snake.dir = RIGHT;
    snake.score = 0;
    snake.size = 10;
    snake.speed = 10;

    // 初始化蛇身位置和颜色
    for (int i = 0; i < snake.num; i++) {
        snake.coor[i].x = 20 - i * 10;
        snake.coor[i].y = 0;
        snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
    // 初始化食物 随机分布
    createFood();
}

// 画蛇 画食物 画分数
void GameDraw() {
    cleardevice();

    for (int i = 0; i < snake.num; i++)
    {
        // 填充一下颜色
        setfillcolor(snake.coor[i].color);
        // 画矩形(修正后的)
        fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    }

    // 绘制食物
    if (food.flag)
    {
        setfillcolor(food.color);
        solidellipse(food.x, food.y, food.x + 10, food.y + 10);
    }

    // 绘制分数
    char temp[20] = "";
    sprintf(temp, "分数: %d", snake.score);
    outtextxy(10, 10, temp);
}

// 让蛇动起来
void GameMove() {

    // 循环部分 - 控制蛇身移动
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.coor[i].x = snake.coor[i - 1].x;
        snake.coor[i].y = snake.coor[i - 1].y;
    }

    // switch部分 - 控制蛇头移动 [蛇头控制方向,蛇身跟随前一个位置]
    switch (snake.dir) {
    case UP:
        snake.coor[0].y -= snake.speed;
        break;
    case DOWN:
        snake.coor[0].y += snake.speed;
        break;
    case LEFT:
        snake.coor[0].x -= snake.speed;
        break;
    case RIGHT:
        snake.coor[0].x += snake.speed;
        break;
    }
}

//控制蛇的方向
void GameController() {
    // 获取键盘
    char key = _getch();

    // 控制蛇不能往回走
    switch (key) {
        case 72: if (snake.dir != DOWN) snake.dir = UP; break;
        case 80: if (snake.dir != UP) snake.dir = DOWN; break;
        case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;
        case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;
    }
    //cout << (int)key << endl;
}




void EatFood() {
    // 碰撞检测
    if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y)
    {
        // 吃到了
        food.flag = false;
        snake.num++;
        snake.score += 10;
        snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);
        // 吃完了 在重新创建一个新的食物
        createFood();
    }
}


int main() {
    // 初始化图形窗口
    initgraph(WIDTH, HEIGHT);
    // 设置背景色为浅蓝灰色
    setbkcolor(RGB(207, 214, 229));
    //清屏再重新绘制所有内容
    cleardevice();
    // 初始化蛇的数据
    GameInit();

    // 游戏主循环
    while (true) {
        GameDraw();
        GameMove();
        Sleep(100);//游戏每0.1秒更新一次画面,相当于游戏以10帧/秒的速度运行,不添加的话是看不到蛇的
        // 如果按了键盘就会执行
        if (_kbhit()) {
            GameController();
        }
        EatFood();     
    }
    return 0;
}

六、改进建议

  1. 添加碰撞检测 - 检测撞墙和自身碰撞
  2. 改进输入处理 - 使用Windows API处理方向键
  3. 添加游戏状态 - 游戏开始、暂停、结束状态优化
  4. 食物生成 - 避免食物生成在蛇身上添
  5. 加音效 - 吃食物和游戏结束的音效