C++20 / SDL3 / Box2D 的学习型游戏框架
GameEngine 是一个基于 C++20 / SDL3 / Box2D 的学习型游戏项目,目前实现了超级玛丽的单人玩法与多人联机功能。项目介绍、架构说明、设计决策见上方详细文档;本 README 只讲构建、运行、部署。
./scripts/build.sh # 交互:选构建目标(默认服务器版),再问是否连 Web 版一起构
./scripts/start_server.sh # 一键开服:无头服务端 + websockify 桥(顺带发 WEB 页面)脚本的执行位已由 git 记录(
scripts/*.sh在索引里是100755),克隆/拉取后直接可跑。 若你手上是很早以前的克隆,执行位可能还是旧的,chmod +x scripts/*.sh一次即可。
build.sh 两个交互问题的含义:
| 提问 | 含义 |
|---|---|
| 构建目标 | 默认 server(无头服务端,服务器上跑这个);desktop 需要图形开发包(X11 等),一般本地开发机用 |
| 是否构建 Web 版本 | 选 y 则额外产出 WASM 版本,需已安装 emsdk——自动探测 EMSDK_ENV → ~/emsdk → /opt/emsdk,找不到会报错并给出安装命令 |
免交互写法:./scripts/build.sh server web(参数可任意组合 server / desktop / web)。
脚本内部就是调预设,等价于:
cmake --preset server && cmake --build --preset server --parallel "$(nproc)"单元测试(秒级、完全离线:跳过 SDL/Box2D,只编纯逻辑模块):
cmake --preset tests && cmake --build --preset tests && ctest --preset tests# 桌面版(CMake 会自动把 Asset/ 拷到 exe 旁)
cmake --preset client
cmake --build --preset client
.\build\bin\GameEngine.exe
# 无头服务端
cmake --preset server
cmake --build --preset server
# 单元测试(秒级、完全离线:跳过 SDL/Box2D,只编纯逻辑模块)
cmake --preset tests
cmake --build --preset tests
ctest --preset tests
# Web 版(WASM,需要 emsdk;产物 build-web\web\ 四件套:html/js/wasm/data)
.\scripts\build_web.ps1
# 一键开服(服务端 exe 菜单开服 + websockify 桥 + 发 WEB 页面)
.\scripts\start_bridge.ps1Important
Web 版预览必须走 http 服务器:python -m http.server 8000 -d build-web\web,浏览器访问 http://localhost:8000/GameEngine.html。
不能双击 html 用 file:// 打开——浏览器会拦截 wasm/data 的 fetch。
| 目标 | 产物路径 | 说明 |
|---|---|---|
桌面版(client 预设) |
build/bin/GameEngine |
全功能客户端,启动进菜单 |
服务器版(server 预设) |
build-server/server/GameEngineServer |
无头,启动即自动开服(无菜单无渲染);CMake 随构建自动在 exe 同级建 Asset/,拷入 config.json 与 maps/(服务端运行期只读这两样) |
Web 版(web 预设) |
build-web/web/ 四件套 |
WASM/Emscripten,资源打进 .data 虚拟盘 |
单元测试(tests 预设) |
build-tests/tests/GameEngineTests |
只编纯逻辑模块(Packet / ConfigManager),不依赖 SDL/Box2D |
每个构建目录该用什么开关,一律由预设决定,不再手敲 -D:
cmake --preset client|server|web|tests # 配置(自动选好 binaryDir 与各项开关)
cmake --build --preset <同名> # 编译
ctest --preset tests # 跑测试
cmake --list-presets # 看有哪些预设以 -D 形式下发,而 -D 每次配置都覆盖缓存——所以预设值即权威值,不会出现「旧 build 目录缓存压过文件默认值」的问题。
预设不指定生成器,用 CMake 的平台默认。Linux 上默认就是 Unix Makefiles;Windows 上默认取决于本机装了什么(本机 CMake 的默认是 Visual Studio,而本项目在 Windows 上只支持 MinGW),所以 Windows 上首次配置某个构建目录时要显式加 -G "MinGW Makefiles"——一旦该目录的缓存建好了,后续就不用再带。要换别的生成器同理,命令行加 -G 即可覆盖。
| 开关 | 默认 | 说明 |
|---|---|---|
BUILD_FOR_SERVER |
OFF |
ON 构建无渲染/音频的无头服务端(server 预设置 ON) |
BUILD_STATIC |
ON |
依赖全部静态链入 exe(单文件发布);OFF 动态链接 |
BUILD_TESTS |
OFF |
构建单元测试目标(tests 预设置 ON) |
BUILD_TESTS_ONLY |
OFF |
只配置测试,跳过全部游戏依赖与主目标(tests 预设置 ON) |
Note
依赖要求:C++20 编译器、CMake 3.26+、git 与网络。首次配置 FetchContent 自动拉取 SDL3 全家与 Box2D 静态编译,之后离线可用。
不用预设直接 cmake -S . -B build 也仍然可用,只是开关要自己带 -D。
三种角色:
| 你想干嘛 | 用什么 | 详细文档 |
|---|---|---|
| 🖥️ 服务器上开服(Linux) | ./scripts/build.sh + ./scripts/start_server.sh |
web-multiplayer-deploy.md |
| 🪟 Windows 朋友开服 | exe 菜单「超级玛丽 Server」+ .\scripts\start_bridge.ps1 |
同上(S1 节) |
| ☁️ 公网 VPS 长期部署 | nginx(TLS)+ systemd + websockify | 同上(S2 节) |
flowchart LR
subgraph Browser["浏览器"]
W["WASM 网页客户端"]
end
W -->|"ws://IP:8081"| B["websockify 桥"]
B -->|"TCP :6666"| S[("游戏服务端")]
D["桌面客户端"] -->|"直连 TCP :6666"| S
桥只服务网页玩家;桌面客户端 TCP 直连。服务端对两种玩家一视同仁。
Asset/config.json(构建时拷到 exe 旁 / Web 版打进 .data 包):
| 键 | 说明 |
|---|---|
window |
窗口宽高、标题、帧率上限 |
assets |
纹理 / 音频 / 字体 / 动画 JSON 的路径(./Asset/...,相对 exe 所在目录) |
network.serverIp |
服务器地址。桌面客户端直连用;Web 版三形态:auto(连页面自身来源,配合桥发页面的拓扑零配置)/ 完整 ws(s):// URL / IP(自动拼桥端口 webBridgePort) |
network.port |
游戏端口(默认 6666),桌面直连 & 桥的转发目标 |
network.webBridgePort |
桥监听端口(默认 8081) |
network.tickRate / timeout |
服务端同步频率 / 连接超时 |
game.levelMap |
当前关卡地图路径(默认 ./Asset/maps/level_1.json),换关改这里即可,无需重新编译 |
game.* |
重力、速度、跳跃力度、火球、Box2D 步长等参数 |
Tip
game.debug: true 可叠加物理调试图(也可在游戏内「设置」里用调试模式开关)。
改配置有两个入口:
- 游戏内「设置」界面——窗口/网络/游戏参数运行时可改,保存即生效(窗口尺寸等标注重启生效)
- 直接改 config.json 文件——桌面版改 exe 旁的
Asset/config.json即生效;Web 版该文件构建时打进 .data 包,改文件需重新构建
注意:Web 版「设置」的保存写入的是内存虚拟盘,刷新页面后丢失、不会写回 .data 包——需要长期变更仍走入口 2。
首次构建很慢
FetchContent 在拉依赖(SDL3 全家 + Box2D),需要网络,之后有缓存。
Linux 上脚本报 \r 错误
换行符被转成 CRLF 了。git add --renormalize . 后重新提交(.gitattributes 已强制 *.sh 用 LF)。
Web 页面白屏 / 打不开
必须走 http 服务器,不能 file://。按 F12 看控制台报错。
网页玩家连不上
桥没起 / 防火墙没放行 8081 / serverIp 与拓扑不匹配(auto 仅限页面与桥同端口)。
服务端启动报找不到 config.json
CMake 在服务端构建时会自动把 Asset/config.json 和 Asset/maps/ 拷到 exe 同级的 Asset/ 目录——重新构建一次即可自动补齐。手动兜底:把根目录 Asset/ 下的 config.json 与 maps/ 拷到服务端 exe 同级的 Asset/ 下。
| 文档 | 内容 |
|---|---|
| web-multiplayer-deploy.md | WEB 联机部署:组件职责、S1 朋友开服、S2 VPS(nginx/systemd)、排障 |
| websocket-net-plan.md | WebSocket 联机方案:选型(A′)、风险、N0-N5 全记录 |
| wasm-web-port-plan.md | WASM 移植:决策记录、Step 0-9、体积基线 |
| sdl3-migration-plan.md | SDL3 迁移(一):窗口/渲染/输入/音频由 SFML 换到 SDL3 |
| sdl3-net-migration-plan.md | SDL3 迁移(二):网络层换 SDL_net 3,SFML 全仓移除(终章) |
| box2d-integration-plan.md | Box2D 接入设计与决策 |
| settings-scene-plan.md | 游戏内设置界面(SettingsScene)方案 |
📄 MIT License · 详见 LICENSE