自己写的一个异步全局消息管理器,也可以叫事件管理器,可以延时执行消息,像网络消息啊、资源加载啊、逻辑定时器啊什么的都可以丢给他,因为写了多年C++所以设计思路都是按C++的来的。
源码:https://gitee.com/jinghuashuiyue2017/GlobalMessage
有兴趣的朋友可以交流一下
自己写的一个异步全局消息管理器,也可以叫事件管理器,可以延时执行消息,像网络消息啊、资源加载啊、逻辑定时器啊什么的都可以丢给他,因为写了多年C++所以设计思路都是按C++的来的。
源码:https://gitee.com/jinghuashuiyue2017/GlobalMessage
有兴趣的朋友可以交流一下
TestScript.js
cc.Class({
extends: cc.Component,
properties: { },
start () {
globalMessage.AddListener(111,this.Callback1,this);
globalMessage.AddListener("222",this.Callback2,this);
},
OnButton1()
{
cc.log("OnButton1");
globalMessage.PostMsg(111,0,"111111111111");
},
OnButton2()
{
cc.log("OnButton2");
globalMessage.PostMsg("222",3,"22222222222");
},
Callback1(msg)
{
cc.log(msg.data);
},
Callback2(msg)
{
cc.log(msg.data);
globalMessage.DeleteListenerByTarget(111,this);
}
});
GlobalMessageScript.js
cc.Class({
extends: cc.Component,
properties: { },
onLoad () { cc.game.addPersistRootNode(this.node); },
update (dt) { globalMessage.Update(dt); },
});
GlobalMessage.js
window.globalMessage = {
//自增ID
msgID: 0,
//监听者列表
msgList: [],
//事件列表
listenerMap: new Map(),
//增加消息监听
AddListener:function(msgType, callback, target){
//回调对象
let msgListener = {
callback: callback,
target: target,
};
let listener = this.listenerMap.get(msgType);
if (listener!=null) {
listener.push(msgListener);
}
else{
let arr = new Array(msgListener);
this.listenerMap.set(msgType, arr);
}
},
//发消息
PostMsg:function(msgType, time, msgData){
this.msgID++;
if (this.msgID > 100000000) {
this.msgID = 1;
}
//事件对象
var msgEvent = {
id: this.msgID,
msgType: msgType,
data: msgData,
time: time,//毫秒
};
this.msgList.push(msgEvent);
return this.msgID;
},
//更新队列
Update:function(second){
if (this.msgList.length > 0) {
for (let i = 0; i < this.msgList.length; i++) {
let msg = this.msgList[i];
msg.time -= second;
if (msg.time < 0) {
let listener = this.listenerMap.get(msg.msgType);
if (listener!=null) {
for (let j = 0; j < listener.length; j++) {
listener[j].callback.call(listener[j].target, msg);
}
}
this.msgList.splice(i, 1);
i--;
}
}
}
},
//删除一条消息
DeleteMsg:function(msgID){
for (let index = 0; index < this.msgList.length;index++) {
if (this.msgList[index].msgID==msgID) {
this.msgList.splice(index,1);
break;
}
}
},
//删除回调,删除该消息类型的所有回调
DeleteListenerByType:function(msgType){
if (this.listenerMap.has(msgType)) {
this.listenerMap.delete(msgType);
}
},
//删除回调,删除该消息类型的一个回调
DeleteListenerByTarget:function(msgType, target){
let listener = this.listenerMap.get(msgType);
if (listener!=null) {
for (let index = 0; index < listener.length; index++) {
if (listener[index].target===target) {
listener.splice(index,1);
break;
}
}
}
}
};
替楼主整理了下代码,其实我这里也有和楼主类似的设计,不过设计的要比楼主的更和creator紧凑点,不过也从你的代码中学到了新的思路
https://github.com/tidys/CocosCreatorPlugins/blob/master/assets/core/Observer.js
https://github.com/tidys/CocosCreatorPlugins/blob/master/assets/core/ObserverMgr.js
跟cc.game.on/off有啥区别。。。
我也有类似的设计。初步的设计是因为网络延迟,我主要是采用 key - callback的形式存储起来的,比较小巧。关于事件管理的设计,我有一点需求是事件队列。当实时战斗时,切出画面,当回来的时候,事件理应是堆积起来的,然后按照顺序快速播放。
可以给事件加一些属性,比如是否立即处理,还是延迟处理,还是怎么的,有个触发条件,然后存储到一个list里面,然后靠引擎的update驱动事件派发,自己维护一套事件机制,总之,这个还是得看项目需求,实现起来也不算太难