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