在Corona SDK中创建一个类,并从中分派事件?

我想创建一个类,它包含一些图形,并在按下按钮时从该类分发事件...这是我简单的代码:

MyClass.lua:

local Class = {}
local Class_mt = { __index = Class } -- metatable
local thisObject

-------------------------------------------------
-- 私人 功能
-------------------------------------------------

local function tapListener( e ) -- local; 只有在此模块中可见
    local event = {
        name = "customEvent",
        mycustomvar = "这是我的自定义变量"
    }

    thisObject.body:dispatchEvent( event )
end

-------------------------------------------------
-- 公共功能
-------------------------------------------------

function Class.new( ) -- 构造函数

    local rect = display.newRect( 0, 0, 50, 50 )
    rect:addEventListener( "tap", tapListener )

    local newClass = {
        body = rect
    }

    return setmetatable( newClass, Class_mt )
end

--添加此函数以获取对对象的引用
function Class:init()
    thisObject = self
end
-------------------------------------------------

返回班级

然后创建此类并侦听一些事件的分发:

local MyClass = require( "MyClass" )

function myCustomEvent(e)
  print(e.mycustomvar)
end

local myNewClass = MyClass.new()
myNewClass:init()
myNewClass.body:addEventListener("customEvent", myCustomEvent)

这确实有效...但似乎有点hacky——请告诉我您的想法?

谢谢。

点赞
用户1925928
用户1925928

我已经审核了代码。现在它应该可以工作了。

MyClass.lua:

local Class = {}
local Class_mt = { __index = Class }    -- 元表

-------------------------------------------------
-- 私有函数
-------------------------------------------------

local function tapListener( e )    -- 局部函数;只在此模块中可见
    local event = {
        name = "customEvent",
        myscustomvar = "这是我的自定义变量"
    }
    Runtime:dispatchEvent( event )
end

-------------------------------------------------
-- 公共函数
-------------------------------------------------

function Class.new( )    -- 构造函数

    local rect = display.newRect( 0, 0, 50, 50 )
    rect:addEventListener( "tap", tapListener )

    local newClass = {
        body = rect
    }

    return setmetatable( newClass, Class_mt )
end

-------------------------------------------------

return Class

main.lua:

local MyClass = require( "MyClass" )
local mynewclass = MyClass.new()

local function myCustomEvent(e)
    print(e.myscustomvar)
end

Runtime:addEventListener("customEvent", myCustomEvent)
2014-01-26 14:26:07
用户869951
用户869951

http://docs.coronalabs.com/api/type/EventListener/dispatchEvent.html 所解释的,dispatchEvent 是显示对象的一个方法。因此,你不能在你的类上调用它,因为类只是一个代表“类”类的表格(你可能应该将其命名为其他名称 ;)。因此,如果它表示在矩形中发生的自定义事件,那么你会调用矩形上的 dispatchEvent(),或者从运行时(如果它表示一个“应用程序”事件)。如果自定义事件是为矩形而提供的,并且由于事件侦听器回调仅传递一个参数(事件),那么你应该在自定义事件中包含一个“目标”成员,以防侦听器想要知道哪个“矩形”发送了事件。

local function tapListener( e )    -- local; only visible in this module
    local event = {
        name = "customEvent",
        myscustomvar = "this is my custom var",
        target = rect
    }
    rect:dispatchEvent( event )
end

请注意如何在 tapListener 中使用 rect,因此该函数需要访问 rect。最好将 tapListener 放在 Class.new() 中:

function Class.new( )    -- constructor

    local rect = display.newRect( 0, 0, 50, 50 )

    local function tapListener( e )    -- local; only visible in this module
        local event = {
            name = "customEvent",
            myscustomvar = "this is my custom var",
            target = rect
        }
        rect:dispatchEvent( event )
    end

    rect:addEventListener( "tap", tapListener )

    ...
end

如果不喜欢在构造函数中创建函数,则有其他方法,它们各自具有不同的优缺点。我个人喜欢将事物放在一起,所以我会更喜欢上面的方法。你还可以将各种处理程序(如 tapListener)移动到“侦听器工厂”函数中,例如:

function bindCustomEventDispatcher(rect)
    local function tapListener(e)
        local event = { ... } -- 创建自定义事件
        rect:dispatchEvent( event )
    end
    local function touchListener(e)
        local event = { ... } -- 创建自定义事件
        rect:dispatchEvent( event )
    end
    local function zapListener(e)
        local event = { ... } -- 创建自定义事件
        rect:dispatchEvent( event )
    end
    rect:addEventListener( "tap", tapListener )
    rect:addEventListener( "touch", touchListener )
    rect:addEventListener( "zap", zapListener )
end

我没有建议使用模块全局变量,因为它不如其他变量那么容易扩展到多个对象(rect 实例),你需要使用数组。但是,如果这不是一个问题,那么你的方法是完全有效的。

2014-01-26 15:57:02