我正在使用Lua脚本编写我的C ++游戏的设计/骨架编码阶段,但我遇到了一个设计问题:
游戏将拥有相同类型实体的许多副本,其行为由同一脚本控制。有没有一种简单的方法可以在单个lua_state中共享相同类型的实体之间的脚本?我只能在互联网上找几次问这个问题;我已经阅读了关于在不同的lua_state中加载相同脚本是否是个好主意的混合反馈,而不是对替代方案的深入反馈。
它简单且防弹,但我认为加载,编译和存储相同字节代码的附加副本与创建的相同实体类型的每个实例是一个悲剧性的浪费,所以我想找出一个更智能的解决方案
这是我想到的两个解决方案。我不是编程或C或OO概念的新手,但我还在学习Lua,特别是Lua / C API。我认为我的想法很合理,但我甚至不确定如何实施它们。:
在Lua脚本中实现OO并让每个实体由Lua对象表示;所有Lua逻辑都会对该对象起作用。这也有利于(或“好处”)允许任何单个实体改变全球环境。
使用setfenv将每个实体封装在自己的环境中,并复制全局空间中所有函数的引用。据我所知,env只是一个与默认全局不同的表,但我已经研究过setfenv,但我不知道我会怎么做。
答案 0 :(得分:4)
1和2只是同一枚硬币的不同侧面,或多或少。这只是对象去向的问题。在类型1中,该对象是Lua脚本的显式部分。这意味着脚本决定如何设置其对象。
在类型2中,对象是环境。它仍然是一个Lua表,但是由外部代码为它创建的表。除了外部代码允许的方式之外,脚本不能摆脱这个对象的限制。
我实现类型1的最简单方法是使用Luabind。我有一个AI对象作为C ++类,Lua可以从中派生出来。运行该AI的“主脚本”将创建该类的实例。您可以传递脚本参数,例如它控制的实体的名称,也可以使用它来控制它的引用等。
类型2相当简单。首先,通过创建一个空表并使用您希望用户能够访问的全局变量填充它来创建新环境。这些将用于与游戏状态交谈(在场景中查找其他对象等),移动有问题的实体的方法,等等。您可以使用可元化的技巧来有效地使这些值不可变且不变,因此用户以后无法修改它们。
然后,您使用lua_loadstring
或lua_loadfile
加载脚本。这将函数放在表示Lua脚本的Lua堆栈上。然后将此表应用为具有lua_setfenv
的脚本函数环境。然后,您可以运行该脚本,传递您希望的任何变量(实体名称等)。