4

私は本当にLuaスクリプトをゲームエンジンに追加したいと思っています。私はLuaを使用していて、luabindを使用してC ++にバインドしていますが、Luaを使用してゲームエンティティを構築する方法を設計するための支援が必要です。

エンジン情報:

コンポーネント指向、基本的にそれぞれはデルタT間隔で更新されるGameEntityリストです。components基本的Game Scenesに、ゲームエンティティのコレクションで構成されています。

だから、ここにジレンマがあります:

GameEntityとそのコンポーネントを定義するためのこのLuaファイルがあるとしましょう。

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」と「」の2つのコンポーネントで定義されていcompAnimatedSpriteます。これらの2つのまったく異なるコンポーネントには、まったく異なる初期化パラメーターが必要です。整数と浮動小数点数(合計と再生)を必要とするヘルス、および反対側では、スプライトシート名を必要とするアニメーション、およびすべてのアニメーション(フレーム、期間など)を定義するためのヘルス。

Luaからの初期化を容易にするためにLuaバインディングを必要とするすべてのコンポーネントで使用できる仮想初期化メソッドを使用して、ある種の抽象クラスを作成したいのですが、仮想クラスには1つがないため、難しいようです。仮想初期化メソッド。これは、すべてのコンポーネント初期化子(またはそれらのほとんど)が異なる初期化パラメーターを必要とするためです(ヘルスコンポーネントは、アニメーションスプライトコンポーネントまたはAIコンポーネントとは異なる初期化を必要とします)。

このコンポーネントのコンストラクターへのLuaバインディングを簡単にするために何を提案しますか?またはどのようにそれをしますか?

PS:このプロジェクトにはC++を使用する必要があります。

4

1 に答える 1

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)
于 2010-09-01T10:35:04.260 に答える