2010-08-29 52 views
4

我真的很想將Lua腳本添加到我的遊戲引擎中。我正在與Lua合作並使用Luabind將其綁定到C++,但我需要幫助來設計我將使用Lua構建我的遊戲實體的方式。集成Lua在我的遊戲引擎中構建我的GameEntities?

發動機信息:

面向組件,基本上每個GameEntity是在一ΔT的間隔更新的components列表。基本上Game Scenes由遊戲實體的集合組成。

所以,這裏的兩難境地:

比方說,我有這樣的Lua文件中定義GameEntity,它的成分:正如你所看到的,這GameEntity由2個組件定義

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}, 
    }, 
    }, 
}, 
} 

compHealth「和」compAnimatedSprite「。這兩個完全不同的組件需要完全不同的初始化參數需要一個整數和一個浮點數(總數和再生)的健康狀況,另一方面,需要精靈圖表名稱的動畫,以及定義所有動畫(幀,持續時間等)。

我很想用某種虛擬初始化方法創建某種抽象類,它可以被所有需要使用Lua綁定的組件使用,以便於從Lua初始化,但似乎很難,因爲虛擬類不是將有一個虛擬的init方法。這是因爲所有組件初始化程序(或其中大多數)都需要不同的初始化參數(健康組件需要與動畫Sprite組件或AI組件不同的初始化程序)。

你建議如何使Lua綁定到這個組件的構造函數更容易?或者你會怎麼做? PS:我必須在這個項目中使用C++。

回答

5

我建議使用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)