1. 程式人生 > >遊戲中常用到的事件分發機制

遊戲中常用到的事件分發機制

遊戲中常常需要處理不同層之間的事件傳遞以及自定義使用者資料,在不使用函式傳遞的時候,常常用到時間的監聽與分發。

第一種:簡單事件監聽(“一次監聽” 可多處觸發)

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持有的方法( 可以多處觸發 )。比較容易理解,適合模組內呼叫。

第二種:全域性事件監聽(多處監聽,多處觸發)

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

有人說這是觀察者模式,MVC模式的一種,一個model可以對應很多個觀察者view(註冊事件行為),當model收到事件通知時(事件觸發條件,傳遞資料),對應的view馬上處理事件(執行回撥函式)。