美文网首页一只腊鸭做游戏Laya游戏开发实战Laya游戏开发
Laya 自定义事件——基于EventDispatcher实现

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

作者: s0ok | 来源:发表于2019-11-26 10:22 被阅读0次

    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了解一下。

    相关文章

      网友评论

        本文标题:Laya 自定义事件——基于EventDispatcher实现

        本文链接:https://www.haomeiwen.com/subject/wrmjwctx.html