Laya 自定义事件——基于EventDispatcher实现

EventDispatcher

可调度事件的所有类的基类。Laya中所有事件都是继承自这个类。Laya中已经实现了很多中事件。Event API


但是这些事件都是系统事件。不能完全满足游戏开发的需要,很多时候我们还需要自己实现一些自定义的事件,比如在战斗结束时我们获得钻石奖励,这时候我们需要通知主界面刷新钻石显示,我们可以通过取得主界面对象修改。但是这样会增加模块的耦合度。EventDispatcher是基于观察者模式实现,所以使用自定义事件可以解决耦合度的问题。
先看一下EventDispatcher怎么实现

这是EventDispatcher中的接口,就是发送事件,监听事件,判断是否有事件监听。官方注释也很详细,这里就不赘述了。
主要看下创建事件监听和发送事件的

  • 创建事件监听




    调用EventDispatcher.on或者EventDispatcher.once监听一个事件的时候。首先移除这个对象之前对这个事件名称的监听,然后会通过_createListener方法创建一个新的事件回调(EventHandler)对象



    这个事件回调类继承Handler,并没有任何扩展。官方可能只是为了在名称上与Handler做区分并保留扩展空间。
    还是回到_createListener方法,里面有这几句代码
        // 第一次创建某个事件的监听
        if (!events[type])events[type]=handler;
        else {
            // 判断events[type]是不是数组类型,
            //是将handler添加到数组中
            if (!events[type].run)events[type].push(handler);
            //不是将events[type]转换成数组,
            else events[type]=[events[type],handler];

events对象靠猜的也知道是一个事件监听的列表。这里判断说明同一个事件名称可以有多个对象同时监听。

  • 发送事件


调用EventDispatcher.event发送事件的时候首先判断是否有对象监听了发送的事件名称。有的话是一个还是多个对象。如果是多个则需要遍历让每个对象都响应一次。发送完毕后判断如果这个监听对象是执行一次,将监听对象从_events中删除。
EventDispatcher的实现很简单,还有其他几个接口可以自己看下源码。看完了引擎对EventDispatcher的实现,我们在可以封装一个自己的自定义事件类

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?) {
        // 派发事件
        CustomEventMgr.eventDispatcher.event(eventName, agv);
    }

    /**
     * 使用 EventDispatcher 对象注册指定类型的事件侦听器对象,以使侦听器能够接收事件通知。
     * @param eventName     事件的类型。
     * @param caller    事件侦听函数的执行域。
     * @param listener  事件侦听函数。
     * @param arg       (可选)事件侦听函数的回调参数。
     */
    public AddNotice(eventName, caller, listener, arg?: any[]) {
        CustomEventMgr.eventDispatcher.on(eventName, caller, listener, (arg == null) ? null : ([arg]));
    }

    /**
     * 使用 EventDispatcher 对象注册指定类型的事件侦听器对象,以使侦听器能够接收事件通知,此侦听事件响应一次后自动移除。
     * @param eventName     事件的类型。
     * @param caller    事件侦听函数的执行域。
     * @param listener  事件侦听函数。
     * @param arg       (可选)事件侦听函数的回调参数。
     */
    public AddNoticeOnce(eventName, caller, listener, arg?: any[]) {
        CustomEventMgr.eventDispatcher.once(eventName, caller, listener, (arg == null) ? null : ([arg]));
    }

    /**
     * 从 EventDispatcher 对象中删除侦听器。
     * @param eventName     事件的类型。
     * @param caller    事件侦听函数的执行域。
     * @param listener  事件侦听函数。
     * @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);
    }
}
// //触发事件
 CustomEventMgr.getInstance().Emit("testEvent", ["myEvent"])

// //监听事件
 CustomEventMgr.getInstance().AddNotice("testEvent", this, () => {
     console.log("处理事件");
 });

封装了几中常用的情况,注释很清楚。用法也很简单。
这里事件参数的传送方式和Laya.Handler一样,可以看Laya Handler了解一下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,322评论 5 465
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,288评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,227评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,015评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,936评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,534评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,995评论 3 389
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,616评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,907评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,923评论 2 315
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,741评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,525评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,016评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,141评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,453评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,054评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,249评论 2 339