起因挺无聊的:某天想写个小游戏给家里小孩玩,又不想让他电脑上装一坨环境。Electron 打包出来太重,纯 Win32 画 UI 又嫌累,思来想去,用 WebView2 当渲染层、C++ 当逻辑层,TauriCPP最合适。
怎么把前端塞进 exe 的
前端就是普通的 HTML + Canvas + 一点 CSS。关键在构建阶段:把整个frontend/目录扫一遍,按路径生成一份资源表,再用 CMake 写进一个.rc资源文件里。程序启动时从 exe 自己的资源段把文件读出来,交给 WebView2 当虚拟路径加载。效果就是——前端代码一个字都不落在硬盘上,分发的时候只有一个 exe。
我给这套薄壳起了个名,叫 TauriCPP,就放在仓库的TauriCPP/里,纯 C++17 / Win32,没别的依赖。
游戏逻辑和画面是分开的
后端是一个 40ms 一次的 tick:刷怪、状态机、倒计时、连击窗口全在那儿算,算完把整局状态序列化成一个 JSON 快照推给前端。前端只管画和响应用户点击,点一下洞口就发个hit命令回去。
这么拆的好处是逻辑层能单独跑单元测试。我把game.cpp拎出来喂给一个不建窗口的测试程序,刷怪节奏、连击倍率、道具效果、暂停、结算这些一共写了 14 组断言,c++ 那边改坏了立刻能知道。
音效是算出来的,不是放的
最开始想找几段音效文件,后来发现 Web Audio 自带振荡器,干脆全程序化合成:敲中是方波加一点噪声,炸弹是低频轰鸣叠锯齿,倒计时最后五秒每秒滴答一声,开局还有段上行音。背景音乐也顺手写了段 I–V–vi–IV 的音乐盒循环,三角波琶音加正弦垫底,听着不闹。好处是零音频文件,exe 又轻一点。
右上角那个喇叭按钮能一键静音,静音的时候图标会画一道红杠,比之前单纯变灰清楚。
草地上的猫和狗
背景本来就是纯 Canvas 画的草地和木桩洞。后来觉得空荡荡的,又点了几丛花,角落蹲了只猫、一只狗,地上趴着蜗牛,天上飘俩蝴蝶。这些全是画在离屏静态层上的,只在布局时画一次,不占运行时的每帧开销——毕竟游戏里地鼠冒头才需要重绘,平时没必要一直刷。
一个提醒
炸弹是真的坑。我故意做成敲中扣 300 还清空连击,就是为了让小孩别乱点。结果我自己测试的时候也没少中招。
v1.0.0 已经推上去了。源码和构建脚本都在仓库里,clone 下来.\build.ps1一条命令就能出 exe(需要 VS2022 和 WebView2 静态 SDK):
- Gitee:https://gitee.com/masonwu21/WhackAMole
- GitHub:https://github.com/Emsoro/WhackAMole
顺手点个 star 不嫌弃。