集成 Lua 以在我的游戏引擎中构建我的 GameEntities?

Posted

技术标签:

【中文标题】集成 Lua 以在我的游戏引擎中构建我的 GameEntities?【英文标题】:Integrating Lua to build my GameEntities in my Game Engine? 【发布时间】:2011-04-05 08:53:19 【问题描述】:

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

引擎信息:

面向组件,基本上每个GameEntity 都是components 的列表,这些components 在增量T 间隔内更新。基本上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,
   ,
  ,
 ,

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

我很想用一些虚拟初始化方法创建某种抽象类,我的所有需要​​ Lua 绑定的组件都可以使用它,以便从 Lua 进行初始化,但这似乎很困难,因为虚拟类不会有一个虚拟的初始化方法。这是因为所有组件初始化器(或大多数)都需要不同的初始化参数(健康组件需要的初始化与动画精灵组件或 AI 组件不同)。

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

PS:我必须为这个项目使用 C++。

【问题讨论】:

【参考方案1】:

我建议您使用 composite structure 代替您的游戏实体。当您在解析 Lua 配置表时遇到它们时,将继承自通用游戏实体组​​件的对象添加到每个游戏实体。此任务非常适合factory method。请注意,以这种方式组合实体仍然需要在 GameEntity 类中实现所有方法,除非您使用消息传递等备用调度方法(请参阅visitor pattern)

在 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)

【讨论】:

以上是关于集成 Lua 以在我的游戏引擎中构建我的 GameEntities?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保我的 iPhone 应用使用 Game Center 沙盒?

这个lua代码是否可以在我的GMOD服务器上下载某些文件

如何在 Cmake 中正确设置标题路径以在我的项目中构建 Box2D

多个 C++ .lib 项目到 .dll 项目,Lua 崩溃!

提高基于组件的游戏引擎的效率

我想在我的 Android 游戏中播放音乐以及分析声音数据。使用 Unity C#