好的,所以我试图按照这里的说明进行操作:https://www.lua.org/pil/16.1.html在Lua(以及LOVE游戏框架)中做类似于OO编程的操作,但是它不起作用。这是我的代码的核心。我有一个通用的Object
类:
local Object = {}
function Object:load(arg)
end
function Object:update(dt)
end
function Object:draw()
end
function Object:new(arg)
o = {}
setmetatable(o, self)
self.__index = self
o:load(arg)
return o
end
return Object
和一个继承自它的Ship
类:
Object = require('objects.object')
local Ship = Object:new()
Ship.sprite = love.graphics.newImage('assets/sprites/ship.png')
Ship.sprite:setFilter('nearest', 'nearest', 0)
Ship.px = Ship.sprite:getWidth()/2
Ship.py = Ship.sprite:getHeight()/2
function Ship:load(arg)
self.x = arg.x or 0
self.y = arg.y or 0
self.sx = arg.sx or arg.s or 1
self.sy = arg.sy or arg.s or 1
self.rot = arg.rot or 0
self.tint = arg.tint or {255, 255, 255}
end
function Ship:draw()
love.graphics.setColor(self.tint)
love.graphics.draw(self.sprite, self.x, self.y, self.rot,
self.sx, self.sy, self.px, self.py)
love.graphics.setColor({255, 255, 255})
end
return Ship
现在的问题是,我使用以下代码创建了其中两个Ships作为另一个对象的成员:
self.ship1 = Ship:new({x=50, y=self.y1, s=2, tint={0, 0.5, 1}})
self.ship2 = Ship:new({x=750, y=self.y2, s=-2, tint={1, 0.5, 0}})
但是当我画它们时,我只看到一个 - 第二个。事实证明,就像上面的代码没有将Ship
的新实例分配给ship1
和ship2
,而直接分配给 {{1}因为我无法理解的原因。我做错了什么,或者这是解释器的一个奇怪的错误?
答案 0 :(得分:1)
解决!显然,需要的是这个小片段:
function Object:new(arg)
local o = {}
setmetatable(o, self)
self.__index = self
o:load(arg)
return o
end
在我的所有o
方法中使new
本地解决了所有问题。我不知道它是如何工作的但是我认为在全局变量空间中它在设置元表时会破坏某些东西。
答案 1 :(得分:1)
它不是解释器的bug,它是语言的设计行为。 private sending(data) {
this.myApi.send({
type: 'json',
data: data
}).then(response => {
this.onChange.next(response);
}, httpError => { throw httpError; } );
}
创建全局变量,这是程序员不期望的。 "为什么会这样?"是语言创建者经常提出的问题。有many efforts来控制这种行为更简单。
o={}
没有o = {}
创建全局变量全局变量可以在程序中的所有函数之间访问和共享,除非您使用花哨的环境范围技术。在函数内使用全局变量为各种副作用打开了大门,你应该注意副作用。
我删除了一些语法糖,上面添加的代码可以等效编写如下:
local
现在,如果从Object.new = function(table_before_colon,arg)
highlander = {} --global variable, there can be only one
setmetatable(highlander,table_before_colon);
table_before_colon.__index = table_before_colon;
highlander:load(arg) -- table_before_colon.__index.load(highlander,arg)
return highlander
end
local Ship = Object:new()
--global highlander == Ship
--Ship.new points to Object.new
function Ship:load(arg)--equivalent to: Ship.load=function(self,arg)
--code that sets fields of the `self` object and is called from within new
self.x = arg.x or 0 -- equivalently highlander.x=arg.x or 0
end
开始到new
返回期间没有发生任何事情,那么全局变量的存在无关紧要。但是,显然,您的其他代码与此类似:
new
因此,local OtherObject = Object:new()
--otherObject == highlander
OtherObject.load = function(new_other_obj,arg)
--highlander == new_other_obj
new_other_obj.ship1 = Ship:new({x=50, y=self.y1, s=2, tint={0, 0.5, 1}})
--highlander == new_other_obj.ship1
new_other_obj.ship2 = Ship:new({x=750, y=self.y2, s=-2, tint={1, 0.5, 0}})
--highlander == new_other_obj.ship2
end
调用其他函数,这些函数也访问和修改相同的全局变量。
OtherObject.load
返回调用结束时的全局变量,最后设置为local some_object = OtherObject:new()
内部调用ship2
,调用内Ship:new
内OtherObject.load
{1}}。