3

私はコロナ/ルアでゲームに取り組んでおり、ゲーム内の武器、鎧、お守りなどを表す「アイテム」と呼ばれるクラスを実装しています。オブジェクト指向のルアは初めてです。

クラスの新しいインスタンスを作成した後、オブジェクトの特定のプロパティを設定すると、オブジェクト自体ではなく、クラスのメタテーブルに設定されているように見えることがわかりました。

クラスとコンストラクタは次のとおりです。

local Item = {
    name = nil,
    itemType = nil,
    scarcity = "basic",
    baseDamage = 0, -- Bow only
    bonuses = {
        damageBonus = 0,
        speedBonus = 0,
        critBonus = 0,
        dropBonus = 0,
        rechargeBonus = 0,
        xpBonus = 0
    }
}

-- Creates a simple blank instance of the Item class.
function Item:new(o)
    local item = o or {}
    setmetatable(item, self)
    self.__index = self
    return item
end

ここで、このプロトタイプに基づいて 2 つのオブジェクトを作成するとします。

local bow = Item:new()
bow.itemType = "bow"
starterBow.baseDamage = 5

local ring = Item:new()
ring.itemType = "ring"
ring.bonuses.damageBonus = 0.25

残念なことに、「bonuses.damageBonus」プロパティがメタテーブル内で設定され、すべてのアイテムに適用されているようです (つまり、弓もダメージ ボーナスを受け取り、リングとスタックします)。ただし、動作は「ボーナス」プロパティに限定されているようです。「itemType」プロパティを設定すると、予想どおり、クラスではなくオブジェクトに関連付けられます。

私が見たい動作は、「ボーナス」テーブルのフィールドを個々のアイテムに設定できることです。私が間違っていることは何か分かりますか?ありがとう!

4

2 に答える 2

7

__index存在しないテーブルからフィールドを「取得」しようとすると、メタフィールドがトリガーされます 。ring.bonuses.damageBonus = 0.25リングからボーナスを「取得」しようとしていますが、存在しないため、メタテーブルに移動してボーナス テーブルを返し、その DamageBonus インデックスが 0.25 に設定されます。

Item テーブルで変数を宣言するだけでは、Item インスタンスがそれらをインスタンス変数として継承するわけではないことを理解してください。そのためには、 Item:new() 関数でそれらを宣言/初期化する必要があります。

function Item:new(o)
    local item = o or {}
    setmetatable(item, self)
    self.__index = self
    item.bonuses={} -- create instance bonuses table and give default values
    for k,v in pairs(self.bonuses) do 
        item.bonuses[k]=v
    end
    return item
end
于 2014-05-07T18:57:51.327 に答える
3

テーブルはbonusesインスタンスに存在しないため、ルックアップはメタテーブルを検索し、__indexテーブルで見つけます。その後、そのテーブルでルックアップを続行します。同様に、割り当ても同じことを行います。ただし、ボーナス テーブルは 1 つだけであり、これが重要です。これは、コピーすることはなく、存在する唯一のコピーはクラス内のコピーであり、メタテーブル ルックアップItemを介して検出されるためです。__index

インスタンスごとに作成__indexするテーブルにメタテーブル マジックを追加するか(デフォルトではあるがローカルからインスタンスへの割り当ての場合)、インスタンスごとに新しいテーブルをコピー/作成する必要があります。bonusesbonuses

于 2014-05-07T18:51:59.137 に答える