整合Lua在我的游戏引擎中构建我的GameEntities?

Gol*_*les 4 c++ lua components game-engine

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

发动机信息:

面向组件,基本上每个都是在增量T间隔中更新GameEntity的列表components.基本上Game Scenes由游戏实体的集合组成.

所以,这就是困境:

假设我有这个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},
   },
  },
 },
}
Run Code Online (Sandbox Code Playgroud)

如您所见,此GameEntity由2个组件" compHealth"和" compAnimatedSprite"组成.这两个完全不同的组件需要完全不同的初始化参数 健康需要整数和浮点数(总计和再生),另一方面,需要精灵表名称的动画,以及定义所有动画(帧,持续时间等).

我希望用一些虚拟初始化方法制作某种抽象类,这些方法可以被我所有需要Lua绑定的组件使用,以便于从Lua初始化,但是看起来很难,因为虚拟类不会有一个虚拟init方法.这是因为所有组件初始化程序(或大多数组件)需要不同的init参数(运行状况组件需要与动画精灵组件或AI组件不同的初始化).

你有什么建议让Lua绑定到这个组件的构造函数更容易?或者你会怎么做?

PS:我必须在这个项目中使用C++.

Jud*_*den 5

我建议使用复合结构代替你的游戏实体.在解析Lua配置表时,在遇到它们时,将从公共游戏实体组​​件继承的对象添加到每个游戏实体.此任务是工厂方法的完美候选.请注意,以这种方式组合实体仍然需要在GameEntity类中实现所有方法,除非您使用消息传递之类的备用调度方法(请参阅访问者模式)

在Lua方面,我发现使用单个表参数的回调函数更方便,而不是在C/C++中遍历复杂的表结构.这是一个纯粹的Lua示例,我的意思是使用您的数据.

-- factory functions
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

-- game entity class prototype and constructor
GameEntity = {}
setmetatable(GameEntity, {
    __call = function(self, t)
        setmetatable(t, self)
        self.__index = self
        return t
    end,
})

-- example game entity definition
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},
            },
        },
    }
}

-- recursively walk the resulting table and print all key-value pairs
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)
Run Code Online (Sandbox Code Playgroud)