1)网络模块
在websocket收到消息,不是直接 evt.getInstance().emit("msg"+ msgId, msgData); 这样发不出来,而是扔到socket组件的消息队列msg_queue,在一个组件的update里面进行抛出消息。
解决的问题: 避免切换场景时,觉得:服务器消息发过来了,但是我在切换场景,没有处理。
2)ui模块
切换场景其实不再是切换场景了,而是仅仅 addChild 一个简单的prefab,通过addChild的方式添加到场景树里面,由于单场景,及其cocos是单线程的,addChild时,依次执行prefab的onLoad start, 是不会出现 socket组件来update分发网络消息的。因此,网络消息不可能出现没有处理的情况。
3)直观的可视化场景树
由于可以有工具方便查看场景节点树所有节点,一切变得如此直观!!!
4)可靠性证明
当前场景树:
Canvas-->test_ctrl组件
socket-->test_socket组件
待动态加载节点: test_prefab-->test_prefab组件
test.ctrl.js
var evt = require("evt");
cc.Class({
extends: cc.Component,
properties: {
test_prefab: cc.Prefab
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
this.init_event_manager();
cc.log("testctrl onLoad");
},
init_event_manager: function(){
evt.getInstance().on("change-game", function (data, then) {
var p = cc.instantiate(then.test_prefab).getComponent("testprefab");
then.node.addChild(p.node);
}, this);
},
onDestroy: function(){
evt.getInstance().removeByNode(this);
},
start () {
cc.log("testctrl start");
},
update: function (dt) {
if(this.flag){
return;
}
if(!this.flag){
this.flag = true;
}
cc.log("testctrl update");
}
});
test_socket.js
var evt = require("evt");
cc.Class({
extends: cc.Component,
properties: {
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
cc.log("testsocket onLoad");
this.msg_queue = [
{
cmdId: "change-game",
},
{
cmdId: "1",
},
{
cmdId: "2",
},
{
cmdId: "3",
},
{
cmdId: "4",
},
{
cmdId: "5",
},
];
},
start () {
cc.log("testsocket start");
},
update (dt) {
if(this.msg_queue.length > 0){
var msg = this.msg_queue[i];
cc.log(msg.cmdId);
evt.getInstance().emit(msg.cmdId, {});
this.msg_queue.splice(0, 1);
}
},
});
3.test_prefab.js
cc.Class({
extends: cc.Component,
properties: {
},
// LIFE-CYCLE CALLBACKS:
onLoad () {
cc.log("testprefab onLoad");
},
start () {
cc.log("testprefab Start");
},
update: function (dt) {
if(this.flag){
return;
}
if(!this.flag){
this.flag = true;
}
cc.log("testprefab update");
}
});
4.evt.js
var evt = cc.Class({
ctor: function(){
this._list = {};
},
statics:{
_instance: null,
},
on: function (key, func, node) {
if(!this._list[key]){
this._list[key] = [];
}
var d = {};
d.func = func;
d.node = node;
this._list[key].push(d);
},
removeByNode: function (node) {
for(var key in this._list){
var d = this._list[key];
for(var i = 0; i < d.length; i++){
if(d[i].node == node){
d.splice(i, 1);
i--;
}
}
}
},
emit: function (key, arg) {
if(this._list[key]){
var dataList = this._list[key];
for(var i = 0; i < dataList.length; i++){
var d = dataList[i];
if(d.node instanceof cc.Component){
if(cc.isValid(d.node)){
d.func(arg, d.node);
}else{
d.func(arg, d.node);
}
}
}
}else{
// cc.log("emit event key=[", key, "] not found");
}
}
});
evt._instance = null;
evt.getInstance = function(){
if(!evt._instance){
evt._instance = new evt();
}
return evt._instance;
};
module.exports = evt;
先说打印结果:
ctrl onLoad socket onLoad -->
ctrl start socket start-->
ctrl update socket update-->
ctrl update socket update -->
ctrl update socket update -->
prefab1 onLoad prefab2 onLoad prefab1 start prefab2 start (模拟这一帧率一下子加载了多个资源)-->
ctrl update socket update prefab1 update prefab2 update-->
ctrl update socket update prefab1 update prefab2 update-->
ctrl update socket update prefab1 update prefab2 update-->
蓝色部分表示:没有新节点情况下,update无穷无尽在更新。
结论:
1)加载场景树的话,依次执行
onLoad1 onLoad2 ...-->start1 start2...-->update1 update2...;
2)当出现有新的节点(假如是3 4 5 三个新节点)加入时,就执行这三个节点的