Laya 自定義事件——基于EventDispatcher實現(xiàn)

EventDispatcher

可調(diào)度事件的所有類的基類。Laya中所有事件都是繼承自這個類。Laya中已經(jīng)實現(xiàn)了很多中事件。Event API


但是這些事件都是系統(tǒng)事件。不能完全滿足游戲開發(fā)的需要,很多時候我們還需要自己實現(xiàn)一些自定義的事件,比如在戰(zhàn)斗結(jié)束時我們獲得鉆石獎勵,這時候我們需要通知主界面刷新鉆石顯示,我們可以通過取得主界面對象修改。但是這樣會增加模塊的耦合度。EventDispatcher是基于觀察者模式實現(xiàn),所以使用自定義事件可以解決耦合度的問題。
先看一下EventDispatcher怎么實現(xiàn)

這是EventDispatcher中的接口,就是發(fā)送事件,監(jiān)聽事件,判斷是否有事件監(jiān)聽。官方注釋也很詳細,這里就不贅述了。
主要看下創(chuàng)建事件監(jiān)聽和發(fā)送事件的

  • 創(chuàng)建事件監(jiān)聽




    調(diào)用EventDispatcher.on或者EventDispatcher.once監(jiān)聽一個事件的時候。首先移除這個對象之前對這個事件名稱的監(jiān)聽,然后會通過_createListener方法創(chuàng)建一個新的事件回調(diào)(EventHandler)對象



    這個事件回調(diào)類繼承Handler,并沒有任何擴展。官方可能只是為了在名稱上與Handler做區(qū)分并保留擴展空間。
    還是回到_createListener方法,里面有這幾句代碼
        // 第一次創(chuàng)建某個事件的監(jiān)聽
        if (!events[type])events[type]=handler;
        else {
            // 判斷events[type]是不是數(shù)組類型,
            //是將handler添加到數(shù)組中
            if (!events[type].run)events[type].push(handler);
            //不是將events[type]轉(zhuǎn)換成數(shù)組,
            else events[type]=[events[type],handler];

events對象靠猜的也知道是一個事件監(jiān)聽的列表。這里判斷說明同一個事件名稱可以有多個對象同時監(jiān)聽。

  • 發(fā)送事件


調(diào)用EventDispatcher.event發(fā)送事件的時候首先判斷是否有對象監(jiān)聽了發(fā)送的事件名稱。有的話是一個還是多個對象。如果是多個則需要遍歷讓每個對象都響應一次。發(fā)送完畢后判斷如果這個監(jiān)聽對象是執(zhí)行一次,將監(jiān)聽對象從_events中刪除。
EventDispatcher的實現(xiàn)很簡單,還有其他幾個接口可以自己看下源碼??赐炅艘鎸ventDispatcher的實現(xiàn),我們在可以封裝一個自己的自定義事件類

import EventDispatcher = laya.events.EventDispatcher;

class CustomEventMgr{
    static eventDispatcher: EventDispatcher = new EventDispatcher();

    static _instance: CustomEventMgr;
    private _events;
    public static getInstance(): CustomEventMgr {
        if (CustomEventMgr._instance == null) {
            CustomEventMgr._instance = new CustomEventMgr();
        }
        return CustomEventMgr._instance;
    }

    constructor() {
        super();
    }

    // 注冊事件
    public Emit(eventName, agv?) {
        // 派發(fā)事件
        CustomEventMgr.eventDispatcher.event(eventName, agv);
    }

    /**
     * 使用 EventDispatcher 對象注冊指定類型的事件偵聽器對象,以使偵聽器能夠接收事件通知。
     * @param eventName     事件的類型。
     * @param caller    事件偵聽函數(shù)的執(zhí)行域。
     * @param listener  事件偵聽函數(shù)。
     * @param arg       (可選)事件偵聽函數(shù)的回調(diào)參數(shù)。
     */
    public AddNotice(eventName, caller, listener, arg?: any[]) {
        CustomEventMgr.eventDispatcher.on(eventName, caller, listener, (arg == null) ? null : ([arg]));
    }

    /**
     * 使用 EventDispatcher 對象注冊指定類型的事件偵聽器對象,以使偵聽器能夠接收事件通知,此偵聽事件響應一次后自動移除。
     * @param eventName     事件的類型。
     * @param caller    事件偵聽函數(shù)的執(zhí)行域。
     * @param listener  事件偵聽函數(shù)。
     * @param arg       (可選)事件偵聽函數(shù)的回調(diào)參數(shù)。
     */
    public AddNoticeOnce(eventName, caller, listener, arg?: any[]) {
        CustomEventMgr.eventDispatcher.once(eventName, caller, listener, (arg == null) ? null : ([arg]));
    }

    /**
     * 從 EventDispatcher 對象中刪除偵聽器。
     * @param eventName     事件的類型。
     * @param caller    事件偵聽函數(shù)的執(zhí)行域。
     * @param listener  事件偵聽函數(shù)。
     * @param onceOnly  (可選)如果值為 true ,則只移除通過 once 方法添加的偵聽器。
     */
    public RemoveNotice(eventName: string, caller: any, listener: Function, onceOnly?: boolean) {
        CustomEventMgr.eventDispatcher.off(eventName, caller, listener, onceOnly);
    }

    /**
     * 從 EventDispatcher 對象中刪除指定事件類型的所有偵聽器。
     * @param eventName (可選)事件類型,如果值為 null,則移除本對象所有類型的偵聽器。
     */
    public RemoveAllNotice(eventName: string) {
        CustomEventMgr.eventDispatcher.offAll(eventName);
    }
}
// //觸發(fā)事件
 CustomEventMgr.getInstance().Emit("testEvent", ["myEvent"])

// //監(jiān)聽事件
 CustomEventMgr.getInstance().AddNotice("testEvent", this, () => {
     console.log("處理事件");
 });

封裝了幾中常用的情況,注釋很清楚。用法也很簡單。
這里事件參數(shù)的傳送方式和Laya.Handler一樣,可以看Laya Handler了解一下。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容