使用SDL库以及C++实现的简单的贪吃蛇:AI Fitten生成

简单使用AI代码生成器做了一个贪吃蛇游戏
设计的基本逻辑都是正确的,能流畅运行
免费+准确率高,非常不错!支持Visual Studio系列
Fitten:https://codewebchat.fittenlab.cn/

SDL 入门指南:安装配置https://blog.csdn.net/qq_72157449/article/details/130490332
SDL库:https://github.com/libsdl-org/SDL/releases/tag/release-2.30.5
SDL-ttf库(未用到):https://github.com/libsdl-org/SDL_ttf/releases
在这里插入图片描述
只需要i包含nclude文件,以及库目录lib文件进行编译

运行程序需要dll文件,可将该文件放到执行程序同一个目录下
或将dll文件夹添加到系统变量中
在这里插入图片描述

窗口乱码,以及添加链接库目录

//设置字体编码为 UTF - 8,避免乱码
//设置编译器在执行时使用的字符集为UTF-8
#pragma execution_character_set("utf-8")

//告诉编译器在链接阶段需要链接 SDL2 库
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")

#include <SDL.h>

游戏界面在这里插入图片描述

源代码

//设置字体编码为 UTF - 8,避免乱码
//设置编译器在执行时使用的字符集为UTF-8
#pragma execution_character_set("utf-8")

//告诉编译器在链接阶段需要链接 SDL2 库
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")

#include <SDL.h>
#include <iostream>
#include <vector>

//设置屏幕分辨率和网格大小。
//屏幕分辨率为 800x600,网格大小为 20x20。
//屏幕的网格大小决定了游戏的难度,越大则游戏越难。
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int GRID_SIZE = 10;
const int GRID_WIDTH = SCREEN_WIDTH / GRID_SIZE;
const int GRID_HEIGHT = SCREEN_HEIGHT / GRID_SIZE;
//帧率为 10,即每秒 10 帧,用于控制蛇的速度
const int frame_rate = 10;
const int frame_delay = 1000 / frame_rate;

//定义一个 Point 结构体,用于表示一个点的坐标。
struct Point {
    int x, y;
    bool operator==(const Point &other) const {
        return x == other.x && y == other.y;
    }
};

//游戏主函数。
//初始化 SDL,创建窗口和渲染器,创建蛇和食物,并开始游戏循环。
//游戏循环中,不断检查是否有事件发生,并根据事件更新蛇的移动方向。
//渲染蛇和食物,并刷新渲染器,并计算帧时间,如果超过了帧率,则延迟。
//游戏结束时,退出游戏循环。
//退出程序。
int main(int argc, char *argv[]) {
    //初始化 SDL。
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
        return 1;
    }
    //创建窗口。
    SDL_Window *window = SDL_CreateWindow("贪吃蛇游戏", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return 1;
    }
    //创建渲染器。
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == nullptr) {
        std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl;
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    //创建蛇和食物。
    std::vector<Point> snake = { {GRID_WIDTH / 2, GRID_HEIGHT / 2} };
    Point direction = { 0, 1 };
    Point food = { std::rand() % GRID_WIDTH, std::rand() % GRID_HEIGHT };

    bool game_over = false;
    SDL_Event e;
    bool running = true;
    Uint32 frame_start;
    int frame_time;

    while (running) {
        //获取当前时间(以毫秒为单位),用于计算帧时间。
        frame_start = SDL_GetTicks();
        //不断检查是否有事件发生。SDL_PollEvent 函数会从事件队列中获取一个事件,并将其存储在 e 变量中。如果有事件,循环会继续处理;如果没有事件,循环会退出。
        while (SDL_PollEvent(&e)) {
            //SDL_QUIT(通常是用户关闭窗口),则将 running 设置为 false,这将导致外层循环退出。
            //SDL_KEYDOWN(键盘按下事件),则根据按下的键来更新蛇的移动方向。
            if (e.type == SDL_QUIT) {
                running = false;
            } else if (e.type == SDL_KEYDOWN) {
                //按下上、下、左、右方向键时,更新蛇的移动方向。
                //如果按下其他键,则忽略。
                switch (e.key.keysym.sym) {
                    //如果当前方向不是向下(direction.y != 1),则将方向设置为向上({ 0, -1 })。
                case SDLK_UP: if (direction.y != 1) direction = { 0, -1 }; break;
                    //如果当前方向不是向上(direction.y != -1),则将方向设置为向下({ 0, 1 })。
                case SDLK_DOWN: if (direction.y != -1) direction = { 0, 1 }; break;
                    //如果当前方向不是向左(direction.x != 1),则将方向设置为向右({ 1, 0 })。
                case SDLK_LEFT: if (direction.x != 1) direction = { -1, 0 }; break;
                    //如果当前方向不是向右(direction.x != -1),则将方向设置为向左({ -1, 0 })。
                case SDLK_RIGHT: if (direction.x != -1) direction = { 1, 0 }; break;
                }
            }
        }

        //如果游戏结束,则退出循环。
        if (!game_over) {
            //移动蛇头。
            Point head = snake.front();
            Point new_head = { head.x + direction.x, head.y + direction.y };
            //如果蛇头移动到边界或与身体重合,则游戏结束。
            if (new_head.x < 0 || new_head.x >= GRID_WIDTH || new_head.y < 0 || new_head.y >= GRID_HEIGHT) {
                game_over = true;
            } else if (std::find(snake.begin(), snake.end(), new_head) != snake.end()) {
                game_over = true;
            } else {
                //如果蛇头没有与身体重合,则将蛇头插入到蛇的头部,并更新蛇的长度。
                snake.insert(snake.begin(), new_head);
                //如果蛇吃到了食物,则生成新的食物,否则删除最后一个蛇身体。
                if (new_head == food) {
                    food = { std::rand() % GRID_WIDTH, std::rand() % GRID_HEIGHT };
                    //如果食物跟蛇重叠,则重新生成食物。
                    while (std::find(snake.begin(), snake.end(), food) != snake.end()) {
                        food = { std::rand() % GRID_WIDTH, std::rand() % GRID_HEIGHT };
                    }
                } else {
                    snake.pop_back();
                }
            }
        }

        //设置渲染器的颜色为黑色。
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        //清除屏幕,并将背景设置为黑色。
        SDL_RenderClear(renderer);
        //设置蛇的颜色为绿色。
        SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
        //绘制蛇身体。
        for (const auto &segment : snake) {
            SDL_Rect rect = { segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE };
            //绘制矩形,参数为指向 SDL_Rect 结构体的指针。
            SDL_RenderFillRect(renderer, &rect);
        }
        //设置食物的颜色为红色,并绘制食物。
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_Rect food_rect = { food.x * GRID_SIZE, food.y * GRID_SIZE, GRID_SIZE, GRID_SIZE };
        SDL_RenderFillRect(renderer, &food_rect);
        //将渲染器缓冲区中的内容刷新到屏幕上,从而使之前通过 SDL_RenderClear、SDL_RenderDrawRect、SDL_RenderFillRect 等函数绘制的图形和颜色显示出来。
        SDL_RenderPresent(renderer);
        //计算帧时间,如果超过了帧率,则延迟。
        frame_time = SDL_GetTicks() - frame_start;
        if (frame_delay > frame_time) {
            SDL_Delay(frame_delay - frame_time);
        }
    }
    //自动弹出游戏结束窗口
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "游戏结束", "游戏结束!", window);
    //退出游戏循环。
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}
编写一个完整的基于C++SDL2的贪吃蛇小游戏涉及到相当复杂的代码结构和大量的细节,这里我将给出一个简化的框架和关键部分,你可以根据这个开始构建你的游戏。 首先,确保你已经安装了SDL2,并包含相应的头文件: ```cpp #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> // 如果需要加载图片资源 ``` 接下来,设置基本窗口和事件处理器: ```cpp int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("贪吃蛇", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 400, 400, SDL_WINDOW_SHOWN); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); // 其他初始化和事件循环... } ``` 创建蛇和食物的简单表示: ```cpp class SnakeSegment { public: int x, y; // 蛇的位置坐标 }; Snake snake(5); // 假设初始有5段蛇身 Food food; // 食物的位置随机生成 ``` 然后处理键盘输入,移动蛇: ```cpp void handleInput() { Uint8 keyState[SDL_SCANCODE_LAST + 1]; SDL_GetKeyboardState(keyState); if (keyState[SDL_SCANCODE_UP]) snake.move(Snake::Direction::UP); // 添加对其他方向键的支持 } void update() { handleInput(); // 更新蛇的身体位置... } ``` 最后,在渲染函数中绘制游戏画面: ```cpp void render() { SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); for (const auto& segment : snake.segments) { // 绘制蛇身 } SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); food.render(renderer); SDL_RenderPresent(renderer); } ``` 记得添加游戏的结束条件(例如蛇碰到墙或自身),并且循环运行`update()`和`render()`函数。 这是一个非常基础的框架,实际的游戏会有更复杂的逻辑,如碰撞检测、得分管理等。如果你是初学者,建议一步步学习并实践每个部分。在完成这个游戏后,你可以尝试优化它,比如使用多线程处理用户输入和游戏更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值