不到断气不罢休 发表于 2024-10-31 10:02:14

使用C语言实现经典贪吃蛇游戏

一、项目概述

我们的目的是创建一个根本的贪吃蛇游戏,它具有以下功能:
蛇能够根据玩家的键盘输入改变方向。
当蛇吃到食物时,蛇的长度增长,同时分数增长。
蛇可以在窗口边缘“穿墙”移动。
游戏界面包括一个蛇和一个随机出现的食物。
支持游戏暂停功能。
https://i-blog.csdnimg.cn/direct/a4a257c8b4d7428493c04a7a33426aea.png
二、情况配置

为了实现这个项目,我们需要准备以下开发工具:

[*] Visual Studio Code 或其他任何C/C++ IDE。
[*] Turbo C++ 或者安装了相应库的当代IDE,由于代码中使用了graphics.h,该头文件通常与Turbo C++一起使用。
[*] MinGW 或者其他编译器,用来编译C代码。
注意:graphics.h库不是标准C库的一部门,在某些当代情况中大概不可用。如果不能使用graphics.h,可以思量使用如SDL、OpenGL等其他图形库来替换。
三、代码详解

1. 数据布局定义

首先,定义了两个布局体:snake 和 Food。其中snake包含蛇的位置信息和方向等属性;Food则表现食物的位置和颜色等信息。
struct snake {
        int size;
        int dir;
        int speed;
        POINT coor;
};

struct Food {
        int score;
        int x;
        int y;
        int r;
        bool flag;
        DWORD color;
}; 2. 初始化游戏

初始化函数GameInit()负责设置游戏的根本参数,如图形窗口的大小、蛇的初始位置和速度等。
void GameInit() {
        initgraph(640, 480, SHOWCONSOLE);
        srand(GetTickCount());
        snake.size = 3;
        snake.speed = 10;
        snake.dir = RIGHT;
        ...
} 3. 绘制游戏画面

GameDraw()函数负责绘制当前的游戏状态,包括配景色、蛇和食物的位置。
void GameDraw() {
        BeginBatchDraw();
        setbkcolor(RGB(28, 115, 119));
        cleardevice();
        // 绘制蛇和食物
        ...
        EndBatchDraw();
} 4. 控制蛇的移动

snakeMove()函数根据当前的方向更新蛇的位置,并实现了蛇穿过屏幕边缘的功能。
void snakeMove() {
        for (int i = snake.size - 1; i > 0; i--) {
                snake.coor = snake.coor;
        }
        switch (snake.dir) {
                case UP: ...
                case DOWN: ...
                case LEFT: ...
                case RIGHT: ...
        }
} 5. 用户输入处置处罚

keyControl()函数监听键盘输入并改变蛇的方向。
void keyControl() {
        if (_kbhit()) {
                switch (_getch()) {
                        case 'w': ...
                        case 's': ...
                        case 'a': ...
                        case 'd': ...
                        case ' ': // 暂停游戏
                                while (1) {
                                        if (_getch() == ' ') return;
                                }
                }
        }
} 6. 吃食物逻辑

Eatfood()函数查抄蛇是否吃到了食物,如果是,则增长蛇的长度和玩家的分数。
void Eatfood() {
        if (food.flag && ... && ...) {
                food.flag = false;
                snake.size++;
        }
        if (!food.flag) {
                food.x = rand() % 640;
                ...
                food.flag = true;
        }
        if (!food.flag) {
                food.score++;
                printf("得分: %d", food.score);
        }
} 四、主循环

末了,在main()函数中创建了一个无限循环,用于不断更新游戏状态和渲染画面。
int main() {
        GameInit();
        GameDraw();

        while (1) {
                GameDraw();
                snakeMove();
                keyControl();
                Eatfood();
                Sleep(100);
        }

        return 0;
} 完整代码:

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
#define SNAKE_NUM 500 //蛇的最大节数
enum DIR //蛇的方向
{
        UP,
        DOWN,
        LEFT,
        RIGHT,
};
//蛇的结构
struct snake
{
        int size;//蛇的节数
        int dir;//蛇的方向
        int speed;//蛇的速度
        POINT coor;//坐标
}snake;
//食物结构
struct Food
{
        int score;
        int x;
        int y;
        int r; //食物大小
        bool flag;//食物是否被吃
        DWORD color;

}food;
//数据初始化
void GameInit()
{                                                //显示控制台
        initgraph(640, 480,SHOWCONSOLE);//图形窗口
        //设置随机数种子
        srand(GetTickCount());
        //初始化蛇 一开始有三节
        snake.size = 3;
        snake.speed = 10;
        snake.dir = RIGHT;
        for (int i = 0; i < snake.size ; i++)
        {
                snake.coor.x = 40-10*i;
                snake.coor.y = 10;
        }
        //初始化食物 rand()随机生产一个整数
        //随机数种子需要头文件stdlib.h
                food.x = rand() % 640;
                food.y = rand() % 480;
                food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
                food.r = rand() % 10 + 5;
                food.flag = true;

}
void GameDraw()
{
        //双缓冲绘图
        BeginBatchDraw();
        setbkcolor(RGB(28, 115, 119));//设置背景颜色
        cleardevice();
        //绘制蛇
        setfillcolor(YELLOW);
        for (int i = 0; i < snake.size; i++)
        {
                solidcircle(snake.coor.x, snake.coor.y, 5);
        }
        //绘制食物
        if (food.flag)
        {
                solidcircle(food.x, food.y, food.r);
        }
        EndBatchDraw();
}
//移动蛇
void snakeMove()
{
        //移动即蛇头改变
        //让身体跟随蛇头移动
        for (int i = snake.size-1; i > 0; i--)
        {
                snake.coor = snake.coor;
        }
                switch (snake.dir)
                {
                case UP:
                        snake.coor.y-=snake.speed;
                        if (snake.coor.y + 10 <= 0)//超出上面的边界
                        {
                                snake.coor.y = 480;
                        }
                        break;
                case DOWN:
                        snake.coor.y+=snake.speed;
                        if (snake.coor.y - 10 >= 480)
                        {
                                snake.coor.y = 0;
                        }
                        break;
                case LEFT:
                        snake.coor.x-=snake.speed;
                        if (snake.coor.x + 10 <= 0)
                        {
                                snake.coor.x = 640;
                        }
                        break;
                case RIGHT:
                                snake.coor.x+=snake.speed;
                                if (snake.coor.x - 10 >= 640)
                                {
                                        snake.coor.x = 0;
                                }
                                break;
                }
       
}
//通过按键改变蛇的方向
void keyControl()
{
        //判断有没有按键,如果有按键就返回真
        if (_kbhit())
        {
                //72 80 75 77上下左右键值
                switch (_getch())
                {
                case 'w':
                case 'W':
                case 72:
                        //改变方向
                        if (snake.dir != DOWN)
                        {
                                snake.dir = UP;
                        }
                        break;
                case 's':
                case 'S':
                case 80:
                        if (snake.dir != UP)
                        {
                                snake.dir = DOWN;
                        }
                        break;
                case 'a':
                case 'A':
                case 75:
                        if (snake.dir !=RIGHT)
                        {
                                snake.dir = LEFT;
                        }
                        break;
                case 'd':
                case 'D':
                case 77:
                        if (snake.dir != LEFT)
                        {
                                snake.dir = RIGHT;
                        }
                        break;
                case' '://游戏暂停逻辑
                        while (1)
                        {
                                if (_getch() == ' ')
                                        return;
                        }
                        break;
          }
        }
}
void Eatfood()
{                //判断食物是否存在
        if (food.flag && snake.coor.x >=food.x-food.r && snake.coor.x<= food.x+food.r&&
                snake.coor.y>=food.y-food.r && snake.coor.y<=food.y+food.r)
        {
                food.flag = false;
                snake.size++;
        }//若食物消失,则重新生成
        if (!food.flag)
        {
                food.x = rand() % 640;
                food.y = rand() % 480;
                food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
                food.r = rand() % 10 + 5;
                food.flag = true;
        }
        //吃食物加分
        if (!food.flag)
        {
                food.score++;
                printf("得分:", food.score);
        }
}
int main()
{
        GameInit();
        GameDraw();

        while (1)
        {
                GameDraw();
                snakeMove();
                keyControl();
                Eatfood();
                Sleep(100);
        }

        return 0;
}  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 使用C语言实现经典贪吃蛇游戏