我的自制OO设计遇到了这个特殊问题:
Entity = {}
function Entity:new(o)
o = o or {}
return setmetatable(o, {__index = Entity})
end
function Entity:init() end
function Entity:think() end
function Entity:spawn()
--put in entity pool and begin drawing/logic
self:init()
end
Block = Entity:new{
x = 0,
y = 0,
color = {255, 255, 255, 255},
}
function Block:getPos()
return self.x, self.y
end
--setPos, getColor, setColor etc
function Block:init()
self:setColor(math.random(255), math.random(255), math.random(255))
end
a = Block:new()
a:spawn() --a new block with a random color
--a few seconds later...
b = Block:new()
b:spawn() --all blocks change to new color
所有原型和实例共享color
表。如何使该表的行为类似于字符串:
a = {table}
b = a
print(b[1]) -->table
a[1] = "object"
print(a[1], b[1]) -->object, table
与对象相反:
a = {table}
b = a
print(b[1]) -->table
a[1] = "object"
print(a[1], b[1]) -->object, object
TL; DR:我需要创建一个新的数据类型。
答案 0 :(得分:2)
有三种方法可以解决您的问题:
Entity.color
对象初始化期间初始化Entity
表 - 将其放入Entity:new()
函数。Entity.color
表替换为代表其内容的四个变量 - Entity.colorred
,Entity.colorgreen
,Entity.colorblue
,Entity.coloralpha
。Entity:setColor()
创建一个包含新值的新self.color
表,而不是直接修改这些值。 self.color = {red, green, blue, alpha}
代替self.color[1] = red; self.color[2] = green; self.color[3] = blue; self.color[4] = alpha
。答案 1 :(得分:0)
如何使该表的行为类似于字符串:
您的示例涉及将Lua变量赋值更改为复制值而不是引用。即使你能够影响Lua中的这种变化(你也不能),这将是一个难以形容的可怕想法。
所有原型和实例共享颜色表。
因为你把它放在原型中(例如"类"),所以它等同于OOP语言中的静态成员,由所有实例共享。如果您希望它是实例变量,那么它需要是实例构造的一部分,而不是类构造。您也需要对x
和y
执行相同的操作,否则它们也会被所有Block
个实例共享。
function Block:new()
local instance = { x = 0, y = 0 }
instance:setColor(math.random(255), math.random(255), math.random(255))
return setmetatable(instance, {__index = self})
end
您可以对构造函数进行增强,例如传入参数(例如初始化x
,y
等),但重要的部分是实例带有自己的状态
让Entity:spawn
简单地调用init本身是没有意义的。您显示的示例代码表明它实际上应该生成新实例,但实现不会这样做。