撰写了文章 发布于 2019-11-27 11:16:07
《斧头人(Axe Man)》十一月开发日志
游戏简介
《斧头人(Axe Man)》(Github 页面,英文博客)是一款正在开发的单人回合制 Unity Roguelike 游戏,目前版本是 0.0.2。上个月 以来制作了四个界面:
- 左上角的游戏进度。
- 右上角的按键提示。
- 左下角的滚动日志。
- 按 `m` 键在左侧屏幕显示完整日志。
这次专门谈谈如何设计日志系统。以下内容翻译自 这篇文章,另外请参考三份文件:
图 1:演示动画,十一月。
图 2:演示动画,十月。
日志系统的初始结构
游戏流程中发生某个事件时,日志系统负责在屏幕上输出文本。并非所有的 Roguelike 游戏都需要该系统。HyperRogue 和 Sproggiwood 利用动画展现了玩家行动的结果,但是 DCSS 必须依靠一行行文本描述战斗过程。最简单的日志系统包括两部分:
- 触发事件。
- 打印字符串。
这套系统将对大量事件作出反应,但是输出的渠道是有限的,所以我们不妨先考虑打印环节。《斧头人》的日志有两种显示方式:显示在屏幕右下角的若干条最新日志,以及按 `m` 键后在左侧屏幕显示的完整日志。
图 3:完整日志。
由于只有按键才能查看完整日志,所以需要设法保存日志文本,而不是直接输出到屏幕上。因此我们给日志系统添加第三个组件:
- 触发事件。
- 保存字符串。
- 打印字符串。
打印文本不是本文重点。它涉及到日志系统和 UI 对象之间的交互,具体实现方法取决于每个游戏的实际情况。接下来,我们看看如何保存和读取字符串。
保存和读取文本
我们把文本保存在 `private List<string> fullLog` 里面,然后设计一个接口 `ILogManager`:
图 4:ILogManager。
假如我们希望 `GetLog(0)` 返回最新日志,`GetLog(1)` 返回倒数第二条日志,可以这样实现 `GetLog()`:
图 5:GetLog()。
我们可以调用 `ILogManager.Add(string message)` 把需要添加的字符串直接写入代码,但更好的做法是读取来自外部文件的数据——如何读取文件详见 十月开发日志。为了读取外部数据,日志系统需要一个新功能:
- 触发事件。
- 获取字符串。
- 保存字符串。
- 打印字符串。
我们使用 `LogData.GetStringData()` 获取数据,同时更新一下 `ILogManager`。请注意 `LogMessage` 是一个自定义对象,它包含两个和 `logData.xml` 有关的数据标签。
图 6:获取数据。
包含占位符的文本
现在讨论日志系统第五个、也是最后一个模块。输出的文本有时候包含特定数据,比如怪物名字或者伤害值。换句话说,日志系统需要处理获取的文本:
- 触发事件。
- 获取字符串。
- 处理字符串。
- 保存字符串。
- 打印字符串。
简单地说,处理字符串包含两个任务:
- 获取带有占位符的字符串。
- 把占位符替换成实际数据。
实际解决方案视游戏而定,这里提供一个解决思路。《斧头人》使用类似 `%ACTOR%` 的字符串作为占位符,比如“%ACTOR% 命中了你。”上文提到的自定义对象 `LogMessage` 还有一个构造器,接受三个参数。在 `LogData.GetStringData()` 内部,我们调用 `TryReplacePlaceholder()` 修改文本。
图 7:替换文本。
_
目录