为什么这个lua函数会修改它不应该修改的表格?

我有一个函数在我的代码中来加载和设置精灵的大小。

function aux.Sprite:setTexture(renderer,imgPath)
     ... -- 对于这个问题来说不重要
     img = loadImage(renderer,imgPath)
     self.texture = img.texture
     self.rect.w = img.w
     self.rect.h = img.h
end

(这里的 loadImage 函数是在 C 中实现的,并且返回正确的值)

使用它应该很容易

bg = aux.Sprite:new()
bg:setTexture(R, "testfiles/bg.png")
ship = aux.Sprite:new()
ship:setTexture(R, "testfiles/testship.png")

但问题在于,在第二次调用 setTexture 后,第一个精灵的值发生了改变!

例如

bg = aux.Sprite:new()
bg:setTexture(R, "testfiles/bg.png")
print(bg.rect.w)
ship = aux.Sprite:new()
ship:setTexture(R, "testfiles/testship.png")
print(bg.rect.w)

应该返回 1920 1920 因为我打印了 bg 的宽度两次

但我得到的是 1920 300 也就是说,第二次 setTexture 改变了“bg”而不仅仅是“ship”的值。

我猜测 self.rect.w = img.w 设置了一个“指针”,或者在 lua 中叫做其他什么东西,指向 img.w,当我之后使用函数时,这个指针在所有引用中更新了吗?

我在这里做错了什么?这是正确的 lua 行为吗?

PS:在此定义 Sprite:new 函数

function aux.Sprite:new(o)
     o = o or {}
     setmetatable(o, self)
     self.__index = self
     return o
end
点赞
用户1236045
用户1236045

提供的代码中没有实际创建 rect(或 aux.Sprite)的内容。 我猜这意味着它是通过类似于

aux.Sprite = { rect = {} }

完成的。

这是一个问题,因为这意味着所有精灵都共享相同的 rect

aux.Sprite:new() 返回一个新的 表,它的元表和__index都被设置为Sprite。因此,在setTexture中搜索self.rect在这个空表中会通过 __index返回Sprite中的 rect

您需要确保每个精灵都有自己独特的 rect

我不太清楚这里的典型 Lua 对象模式是什么,但是您可以在 setTexture 中使用 self.rect = { w = img.w, h = img.h } 或者在 new 中使用 o.rect = {} 这样的语句 - 以实际将 rect 设置为新的表,以用于这个特定的精灵。

2020-12-14 15:39:45