如何使用 C++ 中的 LUA 脚本编写带有对话和菜单的交互式 NPC?

我正在开发一个 C++ 的 2D 游戏引擎,考虑将 NPC 的脚本(如对话和菜单选择项)移植到 LUA 中。但我很难想象如何等待用户/客户端的响应。我的场景如下 -

  1. 用户点击 NPC。
  2. NPC 启动对话窗口,玩家无法移动。读取并开始运行 LUA 脚本,例如:
mes("你好!" .. 玩家姓名)
next()
reply = select("你想做这个吗?", "还是那个?")
if reply == 1 then
   mes("你选择了:那个!")
   close()
end

现在,我想让脚本一次只发送一条消息 mes,而 next() 函数会向客户端发送下一个按钮。之后,脚本会暂停并等待用户输入。 一旦点击了下一个按钮,脚本会继续运行,并向客户端发送一个菜单。在选择后,它会进一步进入条件子句或不进入,这取决于选择。

所有这些都是服务器端的,对话被发送到客户端。我想实现的是在等待客户端响应时的暂停功能。

在 Lua 中如何实现这一点?如果您有最佳实践的建议,我将不胜感激。

点赞
用户4984564
用户4984564

我同意 @Blaze 的观点,我的答案是协程。那么问题就是,如何在 Lua 脚本中包装协程。

将每个脚本都包装成自己的协程可能会失去一些性能,但如果大多数脚本都比几行长,这应该不会非常明显。除了速度问题,你还需要记住,在 5.1 版本中,即使在脚本的顶层,coroutine.running() 也不会返回 nil,因为这也只是一个协程。在 5.3 版本中,这不是很大的问题,因为它总是返回一个线程加一个布尔值。

* 你需要进行基准测试,看看这是否有意义。

下一个重要的问题是,在 Lua 还是在 C++ 中进行包装。Lua 显然更灵活,更易于更改,但 C++ 可能会提高一些性能,这在开发游戏时很少发生。明显的缺点是 C API 使用起来更不方便。

最重要的问题是,你不能(或者不应该)只将 next() 实现为对 coroutine.yield('next') 的包装,因为你可能有嵌套的协程;所以你需要一些更多的逻辑,来通过你的 API 调用到达顶层,然后到达 C++。

我希望这能为你决定是否使用协程解决这个问题提供一个很好的概述。

2019-01-28 09:17:43