1

具有简单类的简单 Lua 游戏,如下所示:

creature = class({ 
name = "MONSTER BADDY!",

stats = { power = 10, agility = 10, endurance = 10, filters = {} },

other_things = ...
})

creatureA = creature.new()

creatureB = creature.new()

creatureA.name = "Frank"

creatureB.name = "Zappa"

creatureA.stats.agility = 20

creatureB.stats.power = 12

- 等等等等等等

非表值对每个实例都是单独的,但表值在所有实例之间共享,如果我在一个实例中修改 stats.X 值,所有其他实例都会看到相同的统计表。

Q1:我的 OO 实现有缺陷吗?我尝试了 LOOP 并出现了相同的结果,我的逻辑是否存在根本缺陷?

Q2:你如何让每个生物实例都有自己的统计表(和子表)?

PS。我无法展平我的类表,因为它比示例复杂一些,并且代码的其他部分通过这个嵌套表实现进行了简化。

4

4 回答 4

3

class不是 Lua 中的标准函数。你不会说你是从罗伯托那里借来的,还是自己滚的,或者什么。但我的猜测是,您想更改new方法,以便它对原型进行深拷贝而不是浅拷贝:

function deep_copy(v)
  if type(v) == 'table' then
    local u = { }
    for k, v in pairs(v) do
      u[k] = v
    end
    setmetatable(u, getmetatable(v))
    return u
  else
    return v
  end
end

(警告:我没有尝试编译这段代码,更不用说运行它了。)

于 2010-05-30T20:59:59.437 回答
3

它的工作原理是这样的,因为类实例__index在它们的元表中设置了类表(嗯,大多数实现都是这样工作的)所以如果你访问creatureA.stats(并且它无法找到statscreatureA因此落入__index)它会返回creature.stats。也许您应该阅读Lua 5.1 参考手册:元表

您将无法在类的表构造函数中声明每个实例的变量(除非您将类表中的所有内容深度复制到实例,这将非常昂贵)

您必须在类实现使用的任何初始化函数中执行此操作:

creature = class
{
     __init = function(self, ...)
         self.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
     end,
}
于 2010-05-30T10:20:26.270 回答
0

你的那个叫做 class的函数 看起来很可疑。我会选择最简单的代码。这是一个怪物类文件。没什么特别的,有些人会说它缺少一些绒毛,但至少我下周也可以自己阅读代码。

-- Class object

monster = {}
monster.__index = monster

-- Class methods

function monster.new(name)
    local o = {}
    o.name = name
    o.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
    setmetatable(o, monster)
    return o
end

function monster:shout()
    print('Aaaaaaa! My name is ' .. self.name .. '!')
end

这是输出:

> lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require 'monster'
> m = monster.new('Katla')
> m:shout()
Aaaaaaa! My name is Katla!
于 2010-05-31T14:44:10.427 回答
0

创建新表时,如果您不想共享它,creature您可以随时为其创建一个新表。stats

creature = class({ 
    name = "MONSTER BADDY!",
    stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }),
    other_things = ...
})

力量、敏捷性等将作为参数传递给stats.

于 2010-05-30T09:58:13.427 回答