挂机放置类游戏开发学习历程

\(\Large \mathcal{ImGUI}\)

我准备以 \(C++\) 为核心(也只用 \(C++\) )来完成这一学习流程,先要学习的是 ImGUI 这一前端库。使用 AI 生成了一份可能需要的学习流程图。

阶段 学习目标(核心) 具体落地要求(适配挂机游戏)
环境搭建 完成 ImGUI + 图形库(SDL2/GLFW)环境配置;理解 ImGUI 渲染核心流程 编译运行官方 SDL2+ImGUI 示例;能独立写出 “空 ImGUI 窗口” 的完整代码
基础组件 编译运行官方 SDL2+ImGUI 示例; 能独立写出 “空 ImGUI 窗口” 的完整代码 用 Text 显示 “金币 / 等级 / 每秒收益”;用 Button 实现 “收取金币 / 升级建筑”;用 ProgressBar 展示挂机进度
UI 布局 掌握窗口、分组、行列布局;能固定 / 调整 UI 位置和样式 搭建 “挂机主面板 + 设置面板” 双窗口;整齐排版数值和按钮,适配游戏界面
逻辑联动 实现 UI 与游戏变量双向绑定;掌握定时器 + UI 实时刷新 点击按钮修改金币 / 收益数值,UI 即时更新;实现 “每秒自动加金币” 并刷新显示
进阶交互 掌握提示文本、禁用按钮、弹窗; 实现简单的存档 / 读档 UI 金币不足时按钮禁用 + 红色提示;点击 “存档” 弹出确认弹窗,显示存档成功 / 失败
项目整合 用 CMake 管理 ImGUI 项目编译;代码模块化拆分 编写 CMakeLists.txt 整合 ImGUI 源码 + 游戏逻辑;将 UI 绘制、游戏逻辑拆分为独立函数

环境搭建:

完成 ImGUI + SDL2(OpenGL3)的环境搭建,编译运行第一个 ImGUI 窗口,理解 “窗口创建→ImGUI 上下文初始化→帧循环渲染” 的核心流程。

前置准备:

SDL2 开发库:https://www.libsdl.org/download-2.0.php
ImGUI 源码:https://github.com/ocornut/imgui
CMake:https://cmake.org/download/

步骤 1:文件目录结构搭建

imgui_idle_game/         # 项目根目录
├── CMakeLists.txt        # CMake构建脚本
├── src/                  # 源码目录
│   └── main.cpp          # 主程序文件
└── third_party/          # 第三方库目录
    ├── imgui/            # ImGui源码(直接解压GitHub下载的文件)
    │   ├── imgui.h
    │   ├── imgui.cpp
    │   ├── imgui_draw.cpp
    │   ├── imgui_widgets.cpp
    │   ├── imgui_tables.cpp
    │   ├── imgui_sdl2.cpp  # 后续复制的绑定文件
    │   └── backends/       # ImGui官方后端(SDL2+OpenGL3)
    └── sdl2/               # SDL2开发库(Windows需解压,Linux无需)

将下载的 ImGUI 源码解压到 third_party/imgui,保留 backends 目录(核心是 imgui_impl_sdl2.h/.cppimgui_impl_opengl3.h/.cpp);
Windows 下将 SDL2 开发库解压到 third_party/sdl2,确保包含 include(头文件)和 lib(库文件)目录;Linux 下无需手动放置,通过包管理器安装后 CMake 可自动找到。

步骤 2:编写 CMakeLists.txt

# 指定CMake最低版本
cmake_minimum_required(VERSION 3.16)
# 项目名称(挂机游戏)
project(imgui_idle_game)
# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 1. 查找SDL2库(Linux自动找,Windows需指定路径)
if (WIN32)
    # Windows下SDL2的路径(根据自己的解压位置调整)
    set(SDL2_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/third_party/sdl2/include)
    set(SDL2_LIB_DIR ${CMAKE_SOURCE_DIR}/third_party/sdl2/lib/x64)
    include_directories(${SDL2_INCLUDE_DIR})
    link_directories(${SDL2_LIB_DIR})
else()
    # Linux下自动查找SDL2
    find_package(SDL2 REQUIRED)
    include_directories(${SDL2_INCLUDE_DIRS})
endif()

# 2. 包含ImGUI头文件目录
include_directories(${CMAKE_SOURCE_DIR}/third_party/imgui)
include_directories(${CMAKE_SOURCE_DIR}/third_party/imgui/backends)

# 3. 收集所有源码文件
set(SOURCE_FILES
    src/main.cpp
    # ImGui核心源码
    third_party/imgui/imgui.cpp
    third_party/imgui/imgui_draw.cpp
    third_party/imgui/imgui_widgets.cpp
    third_party/imgui/imgui_tables.cpp
    # ImGui与SDL2/OpenGL3的绑定文件
    third_party/imgui/backends/imgui_impl_sdl2.cpp
    third_party/imgui/backends/imgui_impl_opengl3.cpp
)

# 4. 生成可执行文件
add_executable(${PROJECT_NAME} ${SOURCE_FILES})

# 5. 链接库文件
if (WIN32)
    # Windows下链接SDL2和OpenGL
    target_link_libraries(${PROJECT_NAME} SDL2.lib SDL2main.lib opengl32.lib)
else()
    # Linux下链接SDL2和OpenGL
    target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES} GL)
endif()

步骤 3:编写 main.cpp

src/main.cpp 中写入以下代码(核心流程拆解,适配新手理解):

#include <SDL.h>
#include <gl/GL.h> // Windows
// #include <GL/gl.h> // Linux需替换此行
#include "imgui.h"
#include "imgui_impl_sdl2.h"
#include "imgui_impl_opengl3.h"

int main(int argc, char* argv[]) {
    // ========== 步骤1:初始化SDL2窗口 ==========
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
        printf("SDL初始化失败: %s\n", SDL_GetError());
        return -1;
    }

    // 设置OpenGL版本(3.2核心版,兼容大部分设备)
    const char* glsl_version = "#version 150"; // OpenGL 3.2
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

    // 创建SDL窗口
    SDL_Window* window = SDL_CreateWindow(
        "挂机游戏ImGUI测试",          // 窗口标题
        SDL_WINDOWPOS_CENTERED,       // 窗口位置
        SDL_WINDOWPOS_CENTERED,
        800, 600,                     // 窗口大小
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE // 启用OpenGL+可调整大小
    );
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, gl_context);
    SDL_GL_SetSwapInterval(1); // 开启垂直同步

    // ========== 步骤2:初始化ImGUI上下文 ==========
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // 启用键盘导航

    // 设置ImGUI样式(默认样式即可)
    ImGui::StyleColorsDark();

    // 初始化ImGUI与SDL2/OpenGL3的绑定
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
    ImGui_ImplOpenGL3_Init(glsl_version);

    // ========== 步骤3:主循环(核心) ==========
    bool running = true;
    while (running) {
        // 1. 处理SDL事件(窗口关闭、鼠标/键盘输入)
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                running = false;
        }

        // 2. 开始ImGUI帧(必须在绘制UI前调用)
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();

        // 3. 绘制ImGUI UI(核心:这里写挂机游戏的UI)
        ImGui::Begin("挂机游戏主面板"); // 创建一个窗口
        ImGui::Text("Hello, 挂机游戏!"); // 显示文本
        ImGui::Text("当前金币:0");       // 模拟挂机游戏数值
        ImGui::Button("收取金币");        // 模拟交互按钮
        ImGui::End(); // 结束窗口绘制

        // 4. 渲染ImGUI
        ImGui::Render();
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f); // 背景色
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        SDL_GL_SwapWindow(window); // 交换缓冲区(显示画面)
    }

    // ========== 步骤4:清理资源 ==========
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

步骤 4:编译运行

打开终端,进入项目根目录;
创建 build 目录并编译

mkdir build && cd build
cmake .. -G "MinGW Makefiles"
mingw32-make

SDL2 的动态库(SDL2.dll)复制到build目录(从third_party/sdl2/lib/x64复制);
运行程序:./imgui_idle_game.exe

步骤 5:验证与排错

运行程序后,弹出 800×600 的窗口,窗口内显示 “挂机游戏主面板”,包含文本和按钮,无报错。
SDL2 头文件未找到:检查 CMake 中 SDL2_INCLUDE_DIR 路径;
链接时找不到 SDL2.lib:确保 SDL2_LIB_DIR 指向 x64(或 x86)目录,且链接了 SDL2.lib 和 SDL2main.lib;
OpenGL 版本不兼容:修改 glsl_version 为对应版本(如 OpenGL 2.1 用#version 120);
ImGUI 函数未定义:检查 CMake 是否包含了所有 ImGUI 源码文件(如 imgui_draw.cpp).

posted @ 2026-01-12 12:26  Noivelist  阅读(15)  评论(0)    收藏  举报