使用easyX+C/C++制作贪吃蛇小游戏

初始化游戏参数/绘制地图

#include <easyx.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define HEIGHT 30 //地图高度
#define WIDTH 40 //地图宽度
#define SIZE 30 //每个格子尺寸
int count;//当前得分
int foodX, foodY;//食物的坐标
int snake[HEIGHT][WIDTH] = {0};
char derection;//当前蛇头的方向

void initGame();//游戏初始化+地图打印函数
void createFood();//创建食物

//主函数
int main(){
    initGame();
    
    _getch();
    return 0;
}
void createFood(){
    foodX = rand()%(WIDTH-2)+1;//得到1~WIDTH-2
    foodY = rand()%(HEIGHT-2)+1;//得到1~HEIGHT-2
    for(int i=0;i<HEIGHT;i++){//如果食物生成到了蛇的身上就执行递归调用重新生成直到不满足
        for(int j=0;j<WIDTH;j++){
            if(foodX == j && foodY == i && snake[i][j]){
                createFood();
            }
        }
    }
}
void initGame(){
    initgraph(WIDTH*SIZE, HEIGHT*SIZE);//设置窗口宽和高
    setbkcolor(LIGHTGRAY);//设置背景色为亮灰色
    cleardevice();//清空所有元素 只保留背景色
    setlinecolor(WHITE);//设置格子线为白色
    //填充横线
    for(int i=0;i<HEIGHT;i++){
        line(0, i*SIZE, WIDTH*SIZE, i*SIZE);
    }
    //填充竖线
    for(int i=0;i<WIDTH;i++){
        line(i*SIZE, 0, i*SIZE, HEIGHT*SIZE);
    }
    //初始化游戏积分
    count = 0;
    //初始化蛇信息
    //3、2、1 其中1代表着蛇头
    for(int i=0;i<3;i++){
        snake[HEIGHT/2][WIDTH/2-1+i] = i+1;
    }
    createFood();
    derection = 'a';
}


绘制蛇和食物

#include <easyx.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define HEIGHT 30 //地图高度
#define WIDTH 40 //地图宽度
#define SIZE 30 //每个格子尺寸
int count;//当前得分
int foodX, foodY;//食物的坐标
int snake[HEIGHT][WIDTH] = {0};
char derection;//当前蛇头的方向

void initGame();//游戏初始化+地图打印函数
void createFood();//创建食物
void update();//绘制蛇和食物

//主函数
int main(){
    initGame();
    while(1){
        update();
    }

    _getch();
    return 0;
}
void createFood(){
    foodX = rand()%(WIDTH-2)+1;//得到1~WIDTH-2
    foodY = rand()%(HEIGHT-2)+1;//得到1~HEIGHT-2
    for(int i=0;i<HEIGHT;i++){//如果食物生成到了蛇的身上就执行递归调用重新生成直到不满足
        for(int j=0;j<WIDTH;j++){
            if(foodX == j && foodY == i && snake[i][j]){
                createFood();
            }
        }
    }
}
void initGame(){
    initgraph(WIDTH*SIZE, HEIGHT*SIZE);//设置窗口宽和高
    setbkcolor(LIGHTGRAY);//设置背景色为亮灰色
    cleardevice();//清空所有元素 只保留背景色
    setlinecolor(WHITE);//设置格子线为白色
    //填充横线
    for(int i=0;i<HEIGHT;i++){
        line(0, i*SIZE, WIDTH*SIZE, i*SIZE);
    }
    //填充竖线
    for(int i=0;i<WIDTH;i++){
        line(i*SIZE, 0, i*SIZE, HEIGHT*SIZE);
    }
    //初始化游戏积分
    count = 0;
    //初始化蛇信息
    //3、2、1 其中1代表着蛇头
    for(int i=0;i<3;i++){
        snake[HEIGHT/2][WIDTH/2-1+i] = i+1;
    }
    createFood();
    derection = 'a';
}

void update(){
    //遍历蛇状态数组 如果为非空则设置成绿色 如果为食物坐标则设置成红色 其余设置成灰色
    for(int i=0;i<HEIGHT;i++){
        for(int j=0;j<WIDTH;j++){
            if(snake[i][j]){
                setfillcolor(LIGHTGREEN);
            }else if(i == foodY && j== foodX){
                setfillcolor(LIGHTRED);
            }else{
                setfillcolor(LIGHTGRAY);
            }
            //绘制矩形 需要填写左上角坐标和右下角坐标
            fillrectangle(j*SIZE, i*SIZE, (j+1)*SIZE, (i+1)*SIZE);
        }
    }
    Sleep(300);
}

移动蛇身体、读取输入、碰撞检测、食物检测

#include <easyx.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define HEIGHT 30 //地图高度
#define WIDTH 40 //地图宽度
#define SIZE 30 //每个格子尺寸
int gameStatus;
int count;//当前得分
int foodX, foodY;//食物的坐标
int snake[HEIGHT][WIDTH];
char derection;//当前蛇头的方向

void initGame();//游戏初始化+地图打印函数
void createFood();//创建食物
void update();//绘制蛇和食物
void moveSnake();//移动蛇身体函数
void getInput();//根据输入改变当前蛇头的方向

//主函数
int main(){
    initGame();
    while(1){
        update();
        moveSnake();
        getInput();
        if(!gameStatus){
            system("pause");
            initGame();
        }
    }

    _getch();
    return 0;
}
void createFood(){
    foodX = rand()%(WIDTH-2)+1;//得到1~WIDTH-2
    foodY = rand()%(HEIGHT-2)+1;//得到1~HEIGHT-2
    for(int i=0;i<HEIGHT;i++){//如果食物生成到了蛇的身上就执行递归调用重新生成直到不满足
        for(int j=0;j<WIDTH;j++){
            if(foodX == j && foodY == i && snake[i][j]){
                createFood();
            }
        }
    }
}
void initGame(){
    initgraph(WIDTH*SIZE, HEIGHT*SIZE);//设置窗口宽和高
    setbkcolor(LIGHTGRAY);//设置背景色为亮灰色
    cleardevice();//清空所有元素 只保留背景色
    setlinecolor(WHITE);//设置格子线为白色
    memset(snake, 0, WIDTH*HEIGHT*sizeof(int));

    //填充横线
    for(int i=0;i<HEIGHT;i++){
        line(0, i*SIZE, WIDTH*SIZE, i*SIZE);
    }
    //填充竖线
    for(int i=0;i<WIDTH;i++){
        line(i*SIZE, 0, i*SIZE, HEIGHT*SIZE);
    }
    //初始化游戏积分
    count = 0;
    //初始化蛇信息
    //3、2、1 其中1代表着蛇头
    for(int i=0;i<3;i++){
        snake[HEIGHT/2][WIDTH/2-1+i] = i+1;
    }
    createFood();
    derection = 'a';
    gameStatus = 1;
}

void update(){
    //遍历蛇状态数组 如果为非空则设置成绿色 如果为食物坐标则设置成红色 其余设置成灰色
    for(int i=0;i<HEIGHT;i++){
        for(int j=0;j<WIDTH;j++){
            if(snake[i][j]){
                setfillcolor(LIGHTGREEN);
            }else if(i == foodY && j== foodX){
                setfillcolor(LIGHTRED);
            }else{
                setfillcolor(LIGHTGRAY);
            }
            //绘制矩形 需要填写左上角坐标和右下角坐标
            fillrectangle(j*SIZE, i*SIZE, (j+1)*SIZE, (i+1)*SIZE);
        }
    }
    Sleep(150);
}

void moveSnake(){
    int headX, headY, tailX, tailY, tail = 0;

    for(int i=0;i<HEIGHT;i++){
        for(int j=0;j<WIDTH;j++){
            if(snake[i][j]){
                if(snake[i][j] == 1){//找到头
                    headX = j;
                    headY = i;
                }
                if(snake[i][j] > tail){//如果当前遍历的蛇身体值大于存储的值则记录尾巴
                    tailX = j;
                    tailY = i;
                    tail = snake[i][j];
                }
                snake[i][j]++;
            }
        }
    }
    //根据当前方向计算出下一次头的坐标
    switch(derection){
        case 'a':headX--;break;
        case 'd':headX++;break;
        case 'w':headY--;break;
        case 's':headY++;break;
    }
    //判断坐标是否越界以及是否和蛇身重叠
    if(headX < 0 || headX == WIDTH || headY <0 || headY == HEIGHT || snake[headY][headX]){
        gameStatus = 0;
        return ;
    }

    //设置新的头
    snake[headY][headX] = 1;
    //移除尾巴
    snake[tailY][tailX] = 0; 
    if(headX == foodX && headY == foodY){//如果吃到食物则还原尾巴
        snake[tailY][tailX] = ++tail;
        createFood();
    }
}
void getInput(){
    if(_kbhit()){
        char ch = _getch();
        switch(ch){
            case 'w':
            case 'a':
            case 's':
            case 'd':derection = ch;break;
        }
    }
}

游戏结束积分显示

#include <easyx.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define HEIGHT 30 //地图高度
#define WIDTH 40 //地图宽度
#define SIZE 30 //每个格子尺寸
int gameStatus;
int count;//当前得分
int foodX, foodY;//食物的坐标
int snake[HEIGHT][WIDTH];
char derection;//当前蛇头的方向

void initGame();//游戏初始化+地图打印函数
void createFood();//创建食物
void update();//绘制蛇和食物
void moveSnake();//移动蛇身体函数
void getInput();//根据输入改变当前蛇头的方向
void gameOver();//显示游戏结束

//主函数
int main(){
    initGame();
    while(1){
        update();
        moveSnake();
        getInput();
        if(!gameStatus){
            gameOver();
            system("pause");
            initGame();
        }
    }

    _getch();
    return 0;
}
void createFood(){
    foodX = rand()%(WIDTH-2)+1;//得到1~WIDTH-2
    foodY = rand()%(HEIGHT-2)+1;//得到1~HEIGHT-2
    for(int i=0;i<HEIGHT;i++){//如果食物生成到了蛇的身上就执行递归调用重新生成直到不满足
        for(int j=0;j<WIDTH;j++){
            if(foodX == j && foodY == i && snake[i][j]){
                createFood();
            }
        }
    }
}
void initGame(){
    initgraph(WIDTH*SIZE, HEIGHT*SIZE);//设置窗口宽和高
    setbkcolor(LIGHTGRAY);//设置背景色为亮灰色
    cleardevice();//清空所有元素 只保留背景色
    setlinecolor(WHITE);//设置格子线为白色
    memset(snake, 0, WIDTH*HEIGHT*sizeof(int));

    //填充横线
    for(int i=0;i<HEIGHT;i++){
        line(0, i*SIZE, WIDTH*SIZE, i*SIZE);
    }
    //填充竖线
    for(int i=0;i<WIDTH;i++){
        line(i*SIZE, 0, i*SIZE, HEIGHT*SIZE);
    }
    //初始化游戏积分
    count = 0;
    //初始化蛇信息
    //3、2、1 其中1代表着蛇头
    for(int i=0;i<3;i++){
        snake[HEIGHT/2][WIDTH/2-1+i] = i+1;
    }
    createFood();
    derection = 'a';
    gameStatus = 1;
}

void update(){
    //遍历蛇状态数组 如果为非空则设置成绿色 如果为食物坐标则设置成红色 其余设置成灰色
    for(int i=0;i<HEIGHT;i++){
        for(int j=0;j<WIDTH;j++){
            if(snake[i][j]){
                setfillcolor(HSVtoRGB(snake[i][j]*10, 0.9, 1));
            }else if(i == foodY && j== foodX){
                setfillcolor(LIGHTGREEN);
            }else{
                setfillcolor(LIGHTGRAY);
            }
            //绘制矩形 需要填写左上角坐标和右下角坐标
            fillrectangle(j*SIZE, i*SIZE, (j+1)*SIZE, (i+1)*SIZE);
        }
    }
    Sleep(150);
}

void moveSnake(){
    int headX, headY, tailX, tailY, tail = 0;

    for(int i=0;i<HEIGHT;i++){
        for(int j=0;j<WIDTH;j++){
            if(snake[i][j]){
                if(snake[i][j] == 1){//找到头
                    headX = j;
                    headY = i;
                }
                if(snake[i][j] > tail){//如果当前遍历的蛇身体值大于存储的值则记录尾巴
                    tailX = j;
                    tailY = i;
                    tail = snake[i][j];
                }
                snake[i][j]++;
            }
        }
    }
    //根据当前方向计算出下一次头的坐标
    switch(derection){
        case 'a':headX--;break;
        case 'd':headX++;break;
        case 'w':headY--;break;
        case 's':headY++;break;
    }
    //判断坐标是否越界以及是否和蛇身重叠
    if(headX < 0 || headX == WIDTH || headY <0 || headY == HEIGHT || snake[headY][headX]){
        gameStatus = 0;
        return ;
    }

    //设置新的头
    snake[headY][headX] = 1;
    //移除尾巴
    snake[tailY][tailX] = 0; 
    if(headX == foodX && headY == foodY){//如果吃到食物则还原尾巴
        snake[tailY][tailX] = ++tail;
        createFood();
        count++;//得分加一
    }
}
void getInput(){
    if(_kbhit()){
        char ch = _getch();
        switch(ch){
            case 'w':
            case 'a':
            case 's':
            case 'd':derection = ch;break;
            case 'W':
            case 'A':
            case 'S':
            case 'D':derection = ch+32;break;
        }
    }
}

void gameOver(){
    TCHAR message[100];
    _stprintf(message, _T("游戏结束 score:%d"), count);
    settextstyle(SIZE, SIZE, _T("宋体"));
    settextcolor(LIGHTRED);
    setbkmode(0);
    outtextxy((WIDTH*SIZE-8*SIZE)/2-4*SIZE, HEIGHT*SIZE/2, message);
}

游戏画面

image-20250502001109513

image-20250502001119823