游戏项目中的事件管理器的巧妙用法,在此分享给大家!

hello,大家好,今天给大家分享下,项目中的事件管理器的巧妙用法。相信大家都遇到过,无论是网络事件,还是实现游戏业务的时候用的事件,在写法上都会有些痛处,今天给大家带来的是一个公共的事件管理器,一个管理器便能解决游戏中所有的事件需求。废话不多说,上代码:

import { EventHandler, Node } from "cc";
export class EventManager{

    private dict: any={};

    public static Instance:EventManager=new EventManager();

    /**

     * 添加消息监听

     * @param type 消息唯一标识

     * @param listener 侦听函数

     * @param listenerObj 侦听函数所属对象

     *

     */

    public addListener(type: string, listener: Function, listenerObj: any): void {

        var arr: Array<any> = this.dict[type];

        if (arr == null) {

            arr = new Array<any>();

            this.dict[type] = arr;

        }

        //检测是否已经存在

        var i: number = 0;

        var len: number = arr.length;

        for (i; i < len; i++) {

            if (arr[i][0] == listener && arr[i][1] == listenerObj) {

                return;

            }

        }

        arr.push([listener, listenerObj]);

    }

    /**

     * 移除消息监听

     * @param type 消息唯一标识

     * @param listener 侦听函数

     * @param listenerObj 侦听函数所属对象

     */

    public removeListener(type: string, listener: Function, listenerObj: any): void {

        var arr: Array<any> = this.dict[type];

        if (arr == null) {

            return;

        }

        var i: number = 0;

        var len: number = arr.length;

        for (i; i < len; i++) {

            if (arr[i][0] == listener && arr[i][1] == listenerObj) {

                arr.splice(i, 1);

                break;

            }

        }

        if (arr.length == 0) {

            this.dict[type] = null;

            delete this.dict[type];

        }

    }

    /**

     * 移除某一对象的所有监听

     * @param listenerObj 侦听函数所属对象

     */

    public removeAll(listenerObj: any): void {

        var keys = Object.keys(this.dict);

        for (var i: number = 0, len = keys.length; i < len; i++) {

            var type = keys[i];

            var arr: Array<any> = this.dict[type];

            for (var j = 0; j < arr.length; j++) {

                if (arr[j][1] == listenerObj) {

                    arr.splice(j, 1);

                    j--;

                }

            }

            if (arr.length == 0) {

                this.dict[type] = null;

                delete this.dict[type];

            }

        }

    }

    /**

     * 触发消息

     * @param type 消息唯一标识

     * @param param 消息参数

     *

     */

    public dispatch(type: string, ...param: any): void {

        if (this.dict[type] == null) {

            return;

        }

        this.dealMsg(type,undefined,param);

    }

       /**

     * 触发指定对象的消息

     * @param type 消息唯一标识

     * @param param 消息参数

     *

     */

    public dispatchObj(type: string,listenerObj: any, ...param: any): any {

        if (this.dict[type] == null) {

            return;

        }

       return this.dealMsg(type,listenerObj,param);

    }

     /**

     * 处理一条消息

     */

    private dealMsg(type: string,listenerObj: any, ...param: any): any {

        var listeners: Array<any> = this.dict[type];

        var i: number = 0;

        var len: number = listeners.length;

        var listener: Array<any> = null as unknown as Array<any>;

        let res;

        while (i < len) {

            listener = listeners[i];

            // console.log('listenerObj='+listenerObj+',listener[1]='+listener[1])

            if(!listenerObj || (listenerObj && listenerObj == listener[1])){  //派发

                res=listener[0].apply(listener[1], param);

            }

            if (listeners.length != len) {

                len = listeners.length;

                i--;

            } 

            i++;

        }

        return res;

    }

}

使用方法如下:
注册事件:
EventManager.Instance.addListener(EventType.OnChat,this.OnChat,this.listenerObj)
private OnChat(param: any): void { }

抛出事件到所有的侦听函数对象(带可选参数):
EventManager.Instance.dispatch(EventType.OnChat, 123);

抛出事件到指定的侦听函数对象(带可选参数):
EventManager.Instance.dispatchObj(EventType.OnChat, this.listenerObj, 123);

更多项目中经典写法,可去https://store.cocos.com/app/detail/3650 下载学习。

2赞

冲压。。。。。,,,

建议直接用 cc.EventTarget

我这个代码是自己实现的,好处就是在其它引擎也可以用的,还可以自己修改的

直接用 node 完事