将Lua集成到我的游戏引擎中以构建我的游戏实体?

我真的想在我的游戏引擎中添加Lua脚本。我正在使用Lua,并使用luabind将其绑定到C ++,但我需要帮助来设计我将如何使用Lua构建我的游戏实体的方式。

引擎信息:

组件导向,基本上每个“游戏实体”是由在delta T间隔内更新的“组件”列表组成的。基本上,“游戏场景”由游戏实体的集合组成。

所以,这里是困境:

假设我有这个Lua文件来定义GameEntity及其组件:

GameEntity =
{
 -- Entity Name
 "ZombieFighter",

 -- All the components that make the entity.
 Components =
 {
  -- Component to define the health of the entity
  health =
  {
   "compHealth",  -- Component In-Engine Name
   100,    -- total health
   0.1,    -- regeneration rate
  },

  -- Component to define the Animations of the entity
  compAnimation =
  {
   "compAnimatedSprite",

   spritesheet =
   {
    "spritesheet.gif", -- Spritesheet file name.
    80,     -- Spritesheet frame width.
    80,     -- Spritesheet frame height.
   },

   animations =
   {
    -- Animation name, Animation spritesheet coords, Animation frame duration.
    {"stand", {0,0,1,0,2,0,3,0}, 0.10},
    {"walk", {4,0,5,0,6,0,7,0}, 0.10},
    {"attack",{8,0,9,0,10,0}, 0.08},
   },
  },
 },
}

正如您所看到的,这个GameEntity由两个组件" compHealth"和" compAnimatedSprite"定义。这两个完全不同的组件需要完全不同的初始化参数。 Health需要一个整数和一个浮点数(总和再生),而另一方面,动画需要一个精灵表名称,并定义所有动画(帧,持续时间等)。

我很想制作某种抽象类,其中包含一些虚拟初始化方法,可用于所有需要Lua绑定的组件,以便简化从Lua进行初始化,但这似乎很困难,因为虚拟类不会拥有一个虚拟init方法。这是因为所有组件初始值设定器(或其中大部分)要求不同的init参数(health组件需要不同的init和Animated Sprite组件一样,或AI组件)。

您建议如何使此组件的Lua绑定更容易?或您会如何做到这一点?

PS:我必须在此项目中使用C++。

原文链接 https://stackoverflow.com/questions/3593959

点赞
stackoverflow用户1491
stackoverflow用户1491

我建议你使用组合结构来管理游戏实体。在解析Lua配置表时,为每个游戏实体添加继承自通用游戏实体组件的对象。这个任务是工厂方法的完美应用案例。请注意,以这种方式组合实体仍需要在GameEntity类中实现所有方法,除非您使用另一种调度方法,如消息传递(请参见访问者模式)。

在Lua端,我发现使用带有单个表参数的回调函数比在C/C++中遍历复杂的表结构更方便。以下是使用您的数据的纯Lua示例。

-- 工厂函数
function Health(t) return { total = t[1], regeneration = t[2] } end
function Animation(t) return { spritesheet = t[1], animations = t[2] } end
function Spritesheet(t)
    return { filename = t[1], width = t[2], height = t[3] }
end
function Animations(t)
    return { name = t[1], coords = t[2], duration = t[3] }
end

-- 游戏实体类原型和构造函数
GameEntity = {}
setmetatable(GameEntity, {
    __call = function(self, t)
        setmetatable(t, self)
        self.__index = self
        return t
    end,
})

-- 示例游戏实体定义
entity = GameEntity{
    "ZombieFighter",
    Components = {
        Health{ 100, 0.1, },
        Animation{
            Spritesheet{ "spritesheet.gif", 80, 80 },
            Animations{
                {"stand",  {0,0,1,0,2,0,3,0}, 0.10},
                {"walk",   {4,0,5,0,6,0,7,0}, 0.10},
                {"attack", {8,0,9,0,10,0},    0.08},
            },
        },
    }
}

-- 递归遍历结果表并打印所有键值对
function print_table(t, prefix)
    prefix = prefix or ''
    for k, v in pairs(t) do
        print(prefix, k, v)
        if 'table' == type(v) then
            print_table(v, prefix..'\t')
        end
    end
end
print_table(entity)
2010-09-01 10:35:04