场景管理器的职责:
- 场景切换之前对旧场景上的资源进行引用计数减一
- 场景切换之后对新场景上的资源进行引用计数加一
- 场景切换之后根据资源使用情况释放不需要的资源
- 负责两个场景之间的切换
- 负责两个场景之间的数据传递
场景切换时资源管理
- 场景切换之前,对旧场景上的资源进行引用计数减一
cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LOADING, (event, dat)=> {
if (!this.dependAssets) {
return;
}
bb.UILoader.releaseArrayRes(this.dependAssets);
this.dependAssets = null;
});
- 场景切换之后,对新场景上的资源进行引用计数加一并释放资源
cc.director.on(cc.Director.EVENT_AFTER_SCENE_LAUNCH, (scene: cc.SceneAsset) => {
if (!scene["dependAssets"]) {
this.dependAssets = null;
return;
}
this.dependAssets = scene["dependAssets"];
bb.UILoader.retainArrayRes(scene["dependAssets"]);
bb.UILoader.gc();
});
场景控制器组件和场景逻辑组件
每一个场景都有一个场景控制器,负责一个场景切换的基本功能。重新定义场景组件的生命周期,并在声明周期中加入两个周期 onEnter 和 onExit 周期。此时整个场景的生命周期变为:
- onLoad
- start
- onEnable
- onEnter
- onExit
- onDisable
- onDestory
export default class SceneCtrl {
name: string = "";
data: any = null;
logicComponet: SceneComponent = null;
}
export default class SceneComponent extends cc.Component{
sceneCtrl: bb.SceneCtrl = null;
initBind() {
bb.UIBind.bindComponent(this);
}
onEnter() : void {
}
onExit() : void {
}
}
切换场景
在此和场景有个约定, 每个场景的根节点必须挂载一个继承 场景逻辑组件基类(bb.SceneComponent)的类,而每一个继承场景逻辑组件的基类的子类都会有一个场景控制组件(bb.SceneCtrl), 而 SceneCtrl 负责整个场景的声明周期的控制。
loadScene(scene: string, data: any) {
cc.director.preloadScene(scene, (err, sceneAsset) => {
if (err) {
cc.log(`[场景加载] 失败 ${err} `);
return;
}
cc.director.loadScene(scene, (err, newScene) => {
let components = newScene.children[0]._components;
let component = components[components.length - 1];
let sceneCtrl = new bb.SceneCtrl();
sceneCtrl.data = data;
sceneCtrl.name = scene;
sceneCtrl.logicComponet = component;
sceneCtrl.logicComponet["sceneCtrl"] = sceneCtrl;
sceneCtrl.logicComponet["initBind"]();
sceneCtrl.logicComponet["onEnter"]();
});
});
}