场景管理器的职责:

  • 场景切换之前对旧场景上的资源进行引用计数减一
  • 场景切换之后对新场景上的资源进行引用计数加一
  • 场景切换之后根据资源使用情况释放不需要的资源
  • 负责两个场景之间的切换
  • 负责两个场景之间的数据传递

场景切换时资源管理

  • 场景切换之前,对旧场景上的资源进行引用计数减一
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"]();
        }); 
    });
}