是否可以将侦听器功能放在对象模块中?
我有一个实现显示对象的Cloud类。现在,该类只创建图像。我希望它也能负责自己的监听器事件,这样我就不需要为每个生成的对象调用addEventListener了。
我已经尝试了几种变体,并且我总是以听众函数为零。我也尝试将其拆分,以便在main中调用addEventListener函数。
我开始觉得不支持对象中的侦听器功能。也许我采取了错误的做法?我问的是可行的吗?如果是的话,我做错了什么?
--
-- Cloud.lua
--
local Cloud = {}
local mtaCloud = { __index = cloud } -- metatable
local display = require "display"
-- DOESN'T WORK
function Cloud.scroll( event )
img.y = img.y - img.scrollSpeed
if (img.y + img.contentWidth) < 0 then
img.x = 0
img:translate( math.random(1,_W), 1800 )
end
end
function Cloud.New( strImage, intHeight, intWidth, intScrollSpeed)
local image = display.newImageRect( strImage, intWidth, intHeight )
image.anchorX = 0; image.anchorY = 0.5;
image.x = _W/2; image.y = _H/2;
image.scrollSpeed = 10
image.enterFrame = scroll
Runtime:addEventListener("enterFrame", scroll)
local newCloud = {
img = image
}
return setmetatable( newCloud, mtaCloud )
end
return Cloud
-- main.lua (simplified)
local cloud = require "object.cloud"
function scene:create( event )
local group = self.view
cloud = cloud.New("img/cloud.png", 230, 140)
group:insert(cloud.img)
end
答案 0 :(得分:1)
是的,如果您指的是Chapter 16 of Programming in Lua中讨论的通常的面向对象编程意义上的对象,则可以在对象上设置侦听器。这是一个让self
引用正确的问题。我已经包含了一个适用于这个答案的实现。
我不确定你是否可以在DisplayObject上执行此操作,但这不是你在示例中所做的(DisplayObject是你的image
而不是你的构造函数返回的{{1} },即表Cloud.New()
)。
这是一种可行的方法。你的newCloud
应该有这样的东西(我在这个临时实现中使用了ShapeObjects进行测试;你会进行更改以使用你的图像资源):
Cloud.lua
请注意-- Cloud.lua
local Cloud = {}
function Cloud:scroll()
self.img.x = self.img.x + self.scrollSpeed
if self.img.x >= display.contentWidth + self.img.contentWidth then
self.img.x = - self.img.contentWidth
end
end
function Cloud:enterFrame( event )
self:scroll()
end
function Cloud:new( intHeight, intWidth, intScrollSpeed )
local aCloud = {}
local img = display.newRect( 0, 0, intWidth, intHeight )
img:setFillColor( 1 )
aCloud.img = img
aCloud.scrollSpeed = intScrollSpeed
aCloud.id = id
setmetatable( aCloud, self )
self.__index = self
Runtime:addEventListener( "enterFrame", aCloud )
return aCloud
end
return Cloud
功能中的setmetatable
和 self.__index = self
。这是关键。
我在函数定义中使用了“冒号”(例如Cloud:new()
),这是你使用的“点符号”的语法糖,其中函数的第一个参数是{{1} (例如Cloud:new(...)
)。
另外,我使用的是对象(表)监听器(不是函数);在每个self
事件上,如果对象存在(即在指定的表中找到),则运行时将调用Cloud.new( self, ...)
函数。
假设在项目子目录“objects”中找到名为“Cloud.lua”的文件,在enterFrame
中,您将拥有类似的内容:
enterFrame()
希望有所帮助。