游戏中常常需要处理不同层之间的事件传递以及自定义用户数据,在不使用函数传递的时候,常常用到时间的监听与分发。
第一种:简单事件监听(添加了全局函数,事件名和方法存在table中)
local EventListener = {}
local events = {}
-- 相同的事件名只能注册一次
function EventListener.registerEvent(eventName, handler)
events[eventName] = handler
end
function EventListener.dispatchEvent(eventName, ...)
local handler = events[eventName]
if handler then
return handler(...)
else
-- print(eventName .. " handler not found")
end
end
return EventListener
这个方法是将注册的事件监听添加至 table Events(事件名作key,所以同一事件只能注册一次),然后在触发条件处通过遍历 table找到对应的key,再执行传入的handler持有的方法( 可以多处触发 )。比较容易理解,适合模块内调用,性能低。
Event--------EventCustom
EventListener----------EventListenerCostom
EventDispatcher----------- display.newNode():getEventDispatcher()
第二种:全局事件监听(多处监听,多处触发)
local EventManager = class("EventManager")
local node = display.newNode()
node:retain()
local eventDispatcher = node:getEventDispatcher()
eventDispatcher:retain()
--创建一个监听事件,第一个参数是事件的键值名(事件名) 第二个参数是回调函数。
--同一事件可以多处监听,即回调函数可以不同,因为这里的触发事件不是放在table表中的
function EventManager.addEventListener(evtName,callback)
local listener = cc.EventListenerCustom:create(evtName,callback)
eventDispatcher:addEventListenerWithFixedPriority(listener, 1)
return listener
end
--可以多处监听,自然可以多处触发,可以传递不同参数,通过eventDispatcher:dispatchEvent(event)触发
function EventManager.dispatchEvent(evtName,data)
local event = cc.EventCustom:new(evtName)
local evtData = nil
if data == nil then
evtData = {}
elseif type(data) ~= "table" then
evtData = data
else
evtData = data
end
evtData.name = evtName
event.data = evtData
eventDispatcher:dispatchEvent(event)
end
--在不需要监听事件时,将监听移除(与事件的监听成对使用)
function EventManager.removeEventListener(evtName)
eventDispatcher:removeCustomEventListeners(evtName)
end
function EventManager.removeEventListenerByHandler(evtHandler)
eventDispatcher:removeEventListener(evtHandler)
end
return EventManager