刚把寻宝猎人2.0的源码在 GitHub 上开源那会儿,一个朋友跑来问我:一个用 C++ 写的小型寻宝游戏,代码量不到三千行,凭什么敢标 2.0?这个问题其实问到了点子上。1.0 版是我早先用控制台字符硬拼出来的,能跑,但每想加一个新功能,都得到那个膨胀到六百行的 main 函数里翻半天,改完一处又怕碰坏另一处。2.0 并不是简单加了几张地图、多几种怪物,而是把整个项目从“能跑”重构成“能改”。整个过程踩了不少坑,也积累了很多值得沉淀的经验,这篇博文就当一次开源项目的完整技术复盘。如果你是刚学完 C++ 语法、背了不少八股却不知道怎么落地的人,或者写完过小游戏但总觉得代码改不动,这篇文章应该会给你一些实在的参考。
1. 为什么做2.0:1.0版本的痛点复盘
1.1 控制台版的“能跑”与“难改”
1.0 版本是典型的“能跑”项目。整个游戏用 std::cout 输出字符画地图,_getch() 接收键盘输入,while 循环里包一个巨大的 switch,从移动、踩怪、捡宝箱到胜利判定全塞在一个 main 函数里。玩家控制的 @ 在地图上移动,碰到 T 就能捡到宝藏,走到 X 就算通关。听上去很完整,但代码结构是灾难级的。
当时最容易出问题的就是“状态”和“数据”全混在一起。玩家坐标、怪物坐标、宝藏数量、地图数组全是全局变量,任何函数都能改,一旦某个分支忘了更新,Bug 就很难追。更致命的是地图本身是硬编码的二维数组,想换一张图就得改源码重编译。后来我试着加“敌人巡逻”功能,发现要在主循环的 switch 里再插一个分支,处理怪物移动和碰撞,结果改完以后玩家穿墙的问题又冒出来了。
后来我把这段经历讲给一个做游戏行业的朋友听,他说你这不是写游戏,是在写“一次性脚本”,这句话我记了很久。1.0 的价值只是验证了玩法本身是有意思的,但它离一个能持续迭代的项目差得太远。
1.2 2.0立下的三条军规
做 2.0 之前,我给自己立了三条硬性要求,后面所有设计和重构都没有脱离这三条:
- 数据和逻辑分离。地图不再是硬编码数组,改由程序化生成;物品、怪物属性全部用独立的配置表管理,而不是散落在代码里。
- 主循环要分层。输入、更新、渲染三段拆开,各自独立,方便后续加新玩法时不用全盘推翻。
- 跨平台可编译。不能再依赖 Windows 控制台 API,底层渲染和窗口改用跨平台库,工程用 CMake 搭,让 Windows、Linux 和 macOS 都能一把过。
这三条军规本质上就是“防自己”的,防止我又回到那种靠全局变量和堆代码解决问题的舒适区里。事实证明,前期多花两天搭结构,后期改功能时能省下两周都不止。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开工前的工程搭建:vscode + CMake + 跨平台编译
2.1 为什么不用一键New Project
很多人学 C++ 都是从 Visual Studio 新建控制台项目开始的,一键编译运行确实爽,但换到 2.0 我第一件事就是放弃这个流程。原因很简单:VS 的工程文件 .sln 和 .vcxproj 是 Windows 专属的,一旦想搬到 Linux 或者让别人用别的 IDE 打开,就会出现各种兼容问题。CMake 不是编译器,而是一个跨平台的构建系统生成器,它可以通过一份 CMakeLists.txt 生成出 MSVC 工程、Makefile 或者 Ninja 构建脚本,一套配置到处用。
这里多说一句,CMake 的学习成本没有想象中高。对单体小项目来说,核心命令就那么几条:cmake_minimum_required、project、add_executable 和 target_link_libraries。最基础的 CMakeLists.txt 我大概长这样:
cmake复制cmake_minimum_required(VERSION 3.16)
project(HunterGame)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 加载SDL2
find_package(SDL2 REQUIRED)
add_executable(hunter_game
src/main.cpp
src/Game.cpp
src/MapGenerator.cpp
src/Player.cpp
src/ItemSystem.cpp
)
target_include_directories(hunter_game PRIVATE include)
target_link_libraries(hunter_game PRIVATE SDL2::SDL2)
用 CMake 之后,换一台机器不再需要我手动去配一堆库的路径,只要对方机器上装了 SDL2 和 CMake,三条命令就能完成构建。这也是开源项目“能被人跑起来”的最基本前提。
2.2 vscode配置c/c++环境的关键细节
开发过程中我一直用 vscode 写代码,很多教程喜欢直接让你装 C/C++ 插件,然后配一个 launch.json 点 F5 运行。但对 CMake 项目来说,更省心的做法是保证 vscode 里的配置只是薄薄一层“转发”,把 Intellisense 的 include 路径交给 CMake Tools 插件的 compile_commands.json 去引导。
我踩过的坑是:第一次配置 vscode 时,明明代码在 CMake 里能编译过,编辑器里却到处是红色的波浪线。原因就是 c_cpp_properties.json 里没写 SDL2 的头文件路径。后来我直接启用 CMake Tools 插件的 CMake: Export Compile Commands,让配置工作交给构建系统本身,编辑器红色波浪线立刻消失了。这种“让构建系统统一管头文件搜索路径”的思路,比手工维护一份 JSON 可靠得多。
编译和调试之外,还有一个容易忽略的东西:运行目录。SDL2 默认的资源加载是相对路径,如果你的 assets 目录和可执行文件不在同一个工作目录,图片和音效就会加载失败。我在 vsco
