@617976080 写道:
var MapDirector = cc.Class({
extends: cc.Component,
statics : {
instance : null,
getInstance : function(){
if(MapDirector.instance === null){
cc.error('MapDirector 未被实例化');
return false;
}
return MapDirector.instance;
}
},
properties: {
mapNode : cc.Node,
loadingLayer : cc.Node,
mapElementPrefab : cc.Prefab,
loadingProgress : cc.Node,
rocker : cc.Node,
state : null,mapTileSize : cc.size(0,0), loader : null, mapSubject : null, propManager : null }, onLoad : function(){ // 绑定单例 MapDirector.instance = this; //this.state = new ArrayObject; this.state = [ {name : 'loadData' , taskCount : 2}, {name : 'loadRes' , taskCount: 2}, {name : 'startGame' , taskCount : 0} ]; this.loader = require('Loader').getInstance(); this.mapSubject = require('MapSubject').getInstance(); this.propManager = require('PropManager').getInstance(); // 初始化加载类 this.loader.initiative({ callback : this.afterLoad, callbackTarget : this }); // 初始化地图目标 this.mapSubject.initialize({ mapNode : this.mapNode, mapID : 'aolaiguo', mapTileSize : this.mapTileSize }); // 初始化地图元素 require('MapElementSubject').setNameLabelModel(this.mapElementPrefab); // 加载第一个状态 this.loadData(); }, loadData : function(){ var callback = function(){ this.updateState('loadData'); }.bind(this); this.propManager.loadData(callback); this.mapSubject.loadData(callback); this.loader.loadResources(); }, loadRes : function(){ var callback = function(){ this.updateState('loadRes'); }.bind(this); this.mapSubject.loadRes(callback); this.propManager.loadRes(callback,this); this.loader.loadResources(); }, startGame : function(){ cc.log('startGame'); }, updateState : function(updateStateName){ var self = this; cc.log('update ' + updateStateName); this.state.forEach(function(element){ if(element.name != updateStateName){ //cc.log('is not this state'); return; } element.taskCount -= 1; if(element.taskCount === 0){ var index = this.state.indexOf(element) + 1; cc.log(index); if(this.state[index] === undefined){ return; } cc.log(this.state[index].name + ' oporate'); this[this.state[index].name].call(self); } }.bind(this)); }, // 加载完成后 afterLoad : function(data){ this.loadingLayer.active = false; }, // 更新 update : function(){ this.updateRocker(); }, // 更新聚焦者移动 updateRocker : function(){ var moveSpeed = this.rocker.controller.getSpeed(); if(moveSpeed === 0){ return; } var followTarget = this.mapSubject.followTarget; followTarget.character.walk(moveSpeed); this.mapSubject.setCenterPosition(followTarget.getPosition()); }
});
以上是我目前的地图场景管理类。
原则是使用cc.loader.loadRes的异步加载来加载所有的 json,图片等资源。所以必须第一步载入所有的json资源。才能加载图片资源(必须根据json资源中的数据, 比如地图中有哪些npc 才能加载对应的图片资源)
这里面会涉及非常多的回调的依赖。
比如:地图数据加载,得到对应的地图场景图的地址->加载地图场景图->初始化摄像机的跟随范围(依赖于获取到场景图尺寸)。 加载地图元素(地图元素的坐标,依赖于场景图尺寸)
上面的步骤必须是一步一步执行的,因为后一步的流程依赖于前一步的资源或者数据。
这样的话会有大量的回调函数,代码很难理解,执行起来非常混乱。
比如这里的移动角色,因为前面的步骤是异步的,一进入游戏就移动角色的话肯定是会出错的,因为地图还没加载完。
总之执行流程依赖异步的话,整个游戏的架构进行下去会非常混乱。
下面说一下MapDirector的执行流程。
首先MapDirector有一个成员属性state ,name是状态名称, taskCount是该状态要执行的任务数量。
比如 :,loadData中:
mapSubject(地图目标),propManager(道具管理类)执行loadData方法,这个方法调用cc.loader.loadRes,回调方法中执行传入的callback,更新当前state的taskCount(完成一个就减一,然后循环判断 ,taskCount为0的话就执行下一个状态的方法)。this.propManager.loadData(callback); this.mapSubject.loadData(callback);
这个两个对象的loadData完成后执行回调函数更新state的taskCount使其为0,然后自动调用下一个状态的方法 loadRes,
这里有个问题,是需要在成员属性state中输入正确的taskCount;这里的代码应该是写的很屎的,但是因为之前做web,没有游戏逻辑的经验,求一些建议。
帖子: 1
参与者: 1