3

我正处于使用 Lua 脚本编写 C++ 游戏的设计/骨架编码阶段,但我遇到了设计问题:

游戏将有许多相同类型实体的副本,其行为由相同的脚本控制。有没有一种简单的方法可以在单个 lua_state 中在相同类型的实体之间共享脚本?我只能在互联网上找到这个问题被问过几次;我已经阅读了关于在不同的 lua_state 中加载相同的脚本是否是一个好主意的混合反馈,而不是关于替代方案的深入反馈。

它简单且防弹,但我认为在创建相同实体类型的每个实例时加载、编译和存储相同字节码的附加副本是一种悲惨的浪费,所以我想找出一个更聪明的解决方案。

这是我想到的两个解决方案。我对编程或 C 或 OO 概念并不陌生,但我仍在学习 Lua,尤其是 Lua/C API。我认为我的想法是合理的,但我什至不确定我将如何实施它们。:

  1. 在 Lua 脚本中实现 OO,并让每个实体由一个 Lua 对象表示;所有 Lua 逻辑都将作用于该对象。这也将具有允许任何单一实体改变全球环境的好处(或“好处”)。

  2. 使用 setfenv 将每个实体封装在其自己的环境中,并从全局空间复制所有函数的引用。据我了解,env 只是一个与默认全局不同的表,但我已经研究了 setfenv 但我不知道我会怎么做。

4

1 回答 1

4

1和2只是同一枚硬币的不同面,或多或少。这只是对象去哪里的问题。在类型 1 中,对象是 Lua 脚本的显式部分。这意味着脚本决定了它想如何设置它的对象。

在类型 2 中,对象是环境。它仍然是一个 Lua 表,但它是由外部代码为其创建的。脚本无法摆脱该对象的限制,除非以外部代码允许的方式。

我实现类型 1 的最简单方法是使用Luabind。我有一个 AI 对象作为 C++ 类,Lua 可以从中派生。为该 AI 运行“主脚本”将创建该类的一个实例。您将传递脚本参数,例如它控制的实体的名称,也许它可以用来控制它的引用等。

类型 2 相当简单。首先,您通过创建一个空表并使用您希望用户能够访问的全局变量填充它来创建新环境。这些将用于与游戏状态对话(在场景中查找其他对象等)、移动相关实体的方式等。您可以使用一些可转换的技巧来有效地使这些值不可变和恒定,因此用户以后无法修改它们。

lua_loadstring然后,您使用or加载脚本lua_loadfile。这会在表示该 Lua 脚本的 Lua 堆栈上放置一个函数。然后将此表应用为该脚本函数的环境,并使用lua_setfenv. 然后,您可以运行该脚本,传递您希望的任何变量(实体名称等)。

于 2011-11-04T01:42:28.183 回答