Lua 元表:类字段与实例字段

Aar*_*ron 3 lua metatable coronasdk

我正在用 Corona/Lua 开发一个游戏,并实现一个名为“Item”的类,它代表游戏中的武器、盔甲、护身符等。我是面向对象的 Lua 的新手。

创建类的新实例后,我发现设置对象的某些属性似乎是在类元表中设置它们,而不是在对象本身中。

这是类和构造函数:

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
Run Code Online (Sandbox Code Playgroud)

现在假设我基于这个原型创建了两个对象:

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

local ring = Item:new()
ring.itemType = "ring"
ring.bonuses.damageBonus = 0.25
Run Code Online (Sandbox Code Playgroud)

令我沮丧的是,“bonuses.damageBonus”属性似乎被设置在元表中,因此适用于每个项目(即弓也获得伤害加成,并与戒指叠加)。然而,这种行为似乎仅限于“奖金”属性。如果我设置了“itemType”属性,它会按预期附加到对象,而不是类。

我希望看到的行为是可以为单个项目设置“奖金”表的字段。知道我做错了什么吗?谢谢!

Odo*_*oth 7

__index当您尝试“得到”一个从表中字段不存在metafield被触发。 ring.bonuses.damageBonus = 0.25正在尝试从 ring 中“获取”奖金,由于它不存在,因此转到元表并返回您的奖金表,然后将其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
Run Code Online (Sandbox Code Playgroud)