程序设计小学期小计
昨天奋斗到晚 12 点,算是完成了小游戏的所有功能,小游戏的主体流程算是全部完成了。写一篇小计记录一下。
截至目前,这个项目已经有了 \(233\) 次提交,若干次的合并,构筑起了这个小游戏。
按组员意愿,项目仓库选择了不公开,就不放链接了。
过程
我们组当初提出制作 3D 的网页游戏,这是往届前所未有的,不能用 unity, ue 这些现成的高级引擎,只能自己找一些 npm 的 3D 库来玩。
最后我们使用了 three.js
和 rapier
,前者提供了 3D 场景的渲染,后者提供了物理世界,解决碰撞之类的问题。这两个包算是网页的基础了。
我们的故事设定是在一个时间静止的世界,因此光线是不需要的,正好省去了做模型贴图的成本。
扫描器
我们参考了 lidar
这个游戏的显示逻辑,实现了一个类似的扫描系统。扫描系统是全项目修改最多的地方:
- 扫描系统的前身是用 AI 实现的一个系统,作为 demo。
- 后来我用精灵模型写了一个扫描系统,但性能非常差劲,几百个点就撑不住了。
- 后面我们仔细分析了 demo 的实现,发现 demo 用的是网格模型 Points 绘制点阵,这个模型只需要一个 3D 元素,就能绘制一个高密度的点阵,并且性能开销几乎没有,连续写 200w 个点都不是问题。
- 后面我们发现实现的扫描逻辑不太正常,最后又参考球面散射做出了最终的扫描器。
终端和旁白
整个游戏的剧情提示由终端旁白引出,这里也下了一些功夫。组员提议制作一个类似 bash 的终端系统,不过是阉割的,只接受特定命令,没有参数之类。你可能在想接受命令后的逻辑怎么写,每个命令写一大堆不成史山了,别急,后面的架构会解答。
字幕上,我们不想做成文字剧情游戏那样单独的对话框,还需要按键确认,直接做成电影式的底栏文字,再配个音。配音我们模仿的 史丹利的预言
的旁白音色,用 ai 配了旁白的语音。
Layer 和 Script
游戏的主要逻辑由 Layer 层和 Script 层支撑。
游戏过程中我们会弹出许许多多的窗口,例如暂停,终端页面等等,每个层之间的逻辑关系很重要,例如:
- 这个层盖住了另一个层,那每个层的销毁都需要按顺序执行,直接写乱套了。
- 一个层添加时,输入就要管理,输入是给这个层还是给上一个层。
于是我们写了 Layer ,用栈存储当前存在的层,输入上从栈顶到栈底依次处理输入,若某一层接受了这个输入,那这个输入就不用再下传了。
并且这样实现,销毁也很容易,只需要在 Layer 中把对应层删了就行了。
再说到 Script ,这相当于一个脚本执行器,可以认为我们内嵌了一个控制台,在执行一些逻辑时,你可以像控制台那样把命令编码好,然后直接执行。这样每个方法的实现只需要写几个重要指令,很整洁。
一些感悟
一些 AI 合作
这个项目大规模使用了 Copilot。
小学期正真体会到了 AI 的强大,狂用 AI 以至于这个月的高级请求都用空了。
例如修 bug,写 css,甚至做一个具体的模块出来,AI 的第一版代码都能写的非常好,只需要提出一些要求,修改一些细节就可以了。
我印象比较深的是做结局页面,我是不会写 css 的,整个结局的模块逻辑全是 AI 写的,并且按照我的要求留下了接口和一些参数设计。
AI 写的页面已经有模有样了,他生成了能分多个章节隔章显示的文本显示,还附带了打字机特效,很震撼。
最让我刮目相看的,是 AI 可以自行阅读整个项目的框架,知道一个模块应该如何使用核心调用。例如这个结局框架,他会发现核心有一个 layer 层,需要实现向 layer 丢东西,析构,处理 input 等等核心要求,写出一个符合核心的页面出来,很厉害。
史山
最开始,我们组期望手搓一个引擎出来,但最后以失败告终。
核心的内容非常难设计,必须要有极其长远的打算,核心一旦写好,后面就不可能被更改了。
我们小组在第二周还重构了,全部推翻重来重写了核心。
所以工程开发是一个大学问,还需要很多的探索,像我这种打竞赛的就只会 “面多加水,水多加面”,最后造史了。
结语
开发的道路,道阻且长吧。
我现在都不想再看小学期那坨东西(雾),还有很多东西需要学习。