使用JSON格式的分支对话

48次阅读
没有评论

共计 3046 个字符,预计需要花费 8 分钟才能阅读完成。

使用 JSON 格式的分支对话

使用 JSON 格式的分支对话

使用 JSON 格式的分支对话
Download now

欢迎来到这些 JSON 对话教程的最后一篇。在本教程中,我们将探讨如何添加分支对话和事件对话。

本教程包含的项目文件是在之前教程中使用的文件基础上进一步开发的,不过 JSON 文件和非玩家角色(NPC)代码已经经历了一些改动。这些改动将在 项目概述部分 进行更详细的介绍,但请您注意,如果您一直将这些概念逐步融入到一个统一的项目中,那么您可能需要做出一些相应的调整!

项目概况

您首先会注意到,在这个项目中,NPC 系统的规模要大得多。这是因为这个项目源于对我在主游戏文件中使用的 NPC 代码进行重构的需求。我本可以将它移除,但我还是保留了下来,作为使用家族等功能的示例。

NPC 动力的基础设计是在很久以前就完成的,坦白说,当时相当混乱。它们是可行的,但事件重复很多,整个系统比必要的要庞大。对于展示每个 NPC 在本教程中 的工作方式来说,这没问题,但并不适合大型游戏。所以,如果您想磨练自己的重构和利用家族的技巧,为什么不尝试将原始教程中的 NPC 事件提取出来,并将它们整理成更类似于本教程中包含的样子呢。

无论如何,抛开这些枝节,让我们回到手头的项目上来。

本项目使用了与之前项目相同的大量 JSON 功能。因此,您仍然有 CurScene、CurDialogue 和 GameState 这些全局变量,但本项目还需要一些额外的变量:

  • InteractionID:存储正在与之交谈的 NPC 的 ID 号,有助于选择
  • Question:一个布尔值,告诉游戏是否正在显示问题
  • ChosenAnswer:存储玩家当前选择的答案的 ID 号
  • CurLine:仅用于调试,显示从 JSON 文件中提取的当前文本行

在事件方面,我们将使用很多在之前项目中已有的事件。会有一些额外的函数,以及一些现有函数的改动,但我们会随着讲解逐步介绍。

JSON 文件的结构也发生了一些变化,增加了一些不同的字符串用于 类型 键,以便系统能够执行结束检查。通过在 JSON 中使用“end”作为类型,我们不再需要 GetNumLines 函数,因为每当类型读作“end”时,EndDialogue 函数就会被调用。

使用 JSON 格式的分支对话

事件互动

在这个系统中,我将事件对话定义为连接事件的对话——在这个例子中,是与 NPC 的“战斗”。所以,想法是这样的:你与 NPC 交谈,进行“战斗”(在这个例子中是一个简单的布局切换),然后当战斗结束后,NPC 会说出完全不同的话。这是通过在对话文件中使用 nextscene 键来实现的。

我们先来看看这个键在标准对话中的作用。就像按下 Z 键时我们会检查类型以确定是否调用了一行文本或一个函数一样,当调用 EndDialogue 函数时,我们现在会检查当前场景是否有名为 nextscene 的键,如果有,我们就将我们正在与之互动的 NPC 的 SceneID 改变为 nextscene 的值。

使用 JSON 格式的分支对话

这意味着,下一次我们再次与那个 NPC 交谈时,它会说不同的话。在示例项目中,你可以看到这一点在第一个 NPC 身上是如何实现的,就是那个问你问题的 NPC。

以“战斗”为例,当你与 NPC(示例项目中最右边的一个)交谈时,我们会看到 NPC 挑战玩家的初始对话。然后布局发生变化,当我们返回时,NPC 会说出不同的话。这同样是通过 nextscene 键来实现的,但处理方式略有不同。

这是因为,在 JSON 文件中,与训练师相关的对话行没有 end 键来关闭对话。它被 fight 替代了。当对话系统遇到 fight 键时,它不会调用 EndDialogue 函数,而是调用 NPCFight 函数来触发“战斗”的开始。为了确保 NPC 在我们返回时仍然会说不同的话,SceneID 的更改被添加到 NPCFight 函数的开始部分:

使用 JSON 格式的分支对话

现在,当你返回到主布局时,NPC 会说出它的下一行——这就是示例中的场景 1 和 12。nextscene 键是一个创建对话链的绝佳方式,这样你的角色就可以说出多组对话,而无需存储大量的 ID 作为实例变量。

分枝对话

nextscene 的另一个用途在于系统的分支对话部分。也就是说,你可以让玩家选择一个选项,然后根据所选内容显示不同的行。这个示例在这个想法上没有深入太多,但它确实允许 NPC 提出一个问题,然后根据玩家的选择给出不同的回答。

在 JSON 文件中启动这个过程的场景 ID 是 2。你会看到该场景的最后一行有很多额外的内容:

使用 JSON 格式的分支对话

最后一行被标记为 问题 类型,然后接下来的几个键都与回答系统有关。首先,nbanswers 表示给定问题的答案数量,在这个例子中是 3。然后,每个答案都被列出,并带有自己的 nextscene 标签。

但这些问题如何与事件相契合呢?

当玩家按下 Z 键并且对话系统发现 问题 键时,会调用 DialogueQuestion 函数。

这个函数与 DialogueLine 函数有许多相同的操作——显示对话层、设置文本等等。但它还会将 Question 布尔值设为 true,创建一个数组来存储我们答案的下一个场景的 ID 号,并显示答案框。然后,它会遍历 JSON 文件中列出的答案数量,为每个答案创建文本对象,为它们分配一个 AnswerID,并相应地设置它们的文本。来自 JSON 文件的每个答案的 nextscene ID 随后被加载到数组(NxtScenes)中。

使用 JSON 格式的分支对话

现在 Question 布尔值为 true,一些额外的控制被启用,并且在答案框中会出现一个新的选择箭头。

每当 Question 为 true 时,这个新选择箭头的位置都会被设置为与玩家当前选择的答案对齐。它通过检查分配给每个答案框的 AnswerID 实例变量,并将其与 ChosenAnswer 全局变量进行比较来实现。如果变量匹配,箭头就会被设置到那个特定框的位置。

玩家显然需要一种改变选择的方法,他们可以使用上下箭头键来实现。当 question 布尔值被设为 true 时,上下箭头会改变 ChosenAnswer 的值。按上键会从变量中减去 1,而按下键会给它加上 1。这很棒,但需要添加限制以防止玩家超出可用的答案值。

要做到这一点,我们只需检查 ChosenAnswer 变量,如果它满足某些条件,我们就重置它:

条件

系统▶︎ ChosenAnswer = -1

操作

系统▶︎ 将 ChosenAnswer 设置为 JSONDialoge.Get(“scene.”& CurScene &“.dialogs.”& CurDialogue &“.nbanswers”) – 1

这个事件表示,一旦 ChosenAnswer 达到 -1,那么它就需要被重置为(.nbanswers – 1)的值——所以比可用答案的数量少 1,以考虑基于 0 的索引。

同样的事情也需要在另一端完成,所以如果 ChosenAnswer 等于.nbanswers,那么将 ChosenAnswer 重新设置为 0。这将允许玩家不断滚动浏览所有的答案框,并只是不断循环回到顶部或底部。

使用 JSON 格式的分支对话

下一次我们的玩家按下 Z 键,我们的 Else 事件就会触发并调用 PickAnswer 函数。这个函数只是隐藏答案框并销毁文本实例,然后根据玩家选择的答案设置对话。从而允许对话继续:

使用 JSON 格式的分支对话

通过为每个答案分配自己的“nextscene”,你可以根据玩家的选择改变对话的进展方式。随着你的对话变得更大,可能值得将其存储在类似电子表格的东西中,或者如果你更注重可视化,存储在流程图中,这样你就可以看到你所有的对话场景是如何相互作用的。但这取决于个人偏好!

所以这就是在你的游戏中使用 JSON 实现分支对话的一种方式。感谢 Kyatric 想出了这个逻辑的大部分内容,这样我就可以根据自己的需要稍作调整。希望你们觉得有用!

正文完
 0
评论(没有评论)