0%

CVP认证学习笔记--(何小成)005--实现多场景切换

上篇帖子我提到了cocos中的导演、场景、图层以及精灵之间的关系。从那张关系图中可以看出,导演在整个游戏中处于一个相当重要的位置,它掌控者全局。

概念

在cocos的官网中,可以看到官方文档中对于director的一个解释http://www.cocos.com/doc/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/cocos2d-js/catalog/../4-essential-concepts/4-6-director-of-game/zh.md 从官方帮助文档中,我们可以看到,director在cocos中有以下几个作用:

  1. 环境设定:游戏开始前的帧率设置,动作管理器,事件管理器等都由director先加载起来
  2. 控制游戏主循环,游戏的原理,与动画相同,每一个看到的画面都是由director一帧一帧的渲染出来的,而这个渲染的过程就在director的主循环体内,所以循环的暂定与恢复也是由director来实现的
  3. 最后一个,也是director最重要的一个作用,同时也是本节课所讲的内容,就是场景的管理,除了创建,销毁,还有切换,push,pop等操作,这些都由director来完成,scene的整个生命周期都由director来管理。

    场景管理API

    director中关于场景管理的api有如下几个:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // run the scene
    cc.director.runScene(scene);
    // get the running scene
    var scene = cc.director.getRunningScene();
    // push in a new scene and cover the running scene
    var scene = cc.director.pushScene(scene);
    // pop the top scene and run the second scene
    cc.director.popScene();
    // pop all the scene except the scene in the bottom
    cc.director.popToRootScene()
    director对场景的管理是以堆栈的数据结构来管理,简单来说就是现进后出的数据结构,可以比喻成一个羽毛球筒,当你放进去一个一个的羽毛球后,最先放进去的一定在最底下,最后放进去的一定在最上面,这种结构就类似堆栈的数据结构,也就是说,当导演运行一个场景之后,它会被放入堆栈中,当你再push一个新的场景之后,第二个场景就会压入堆栈,放在第一个场景的上面,我们看到得就是场景二,而场景一仍然存在,只是被放在了场景二的下面,当我们做pop,堆栈就会销毁顶端的第一个场景,而它下面的场景就会呈现出来,但这时候并不会做初始操作,因为这是一直被压在下面的场景一,而当我们使用runScene的时候,会先销毁当前的场景,在new出第二个场景,我觉得如果不是有特别需要保留数据的场景,我们可以全部用runScene来管理场景,否则如果自己使用pop/push来管理场景有可能就乱了,忘了哪个销毁了哪个要初始化(个人感觉,仅参考)

    作业

    作业中代码,我也加入了一段代码来测试场景在切换的时候是否被销毁,只需要用runScene、pushScene、popScene分别来测试即可,代码如下:

这是启动的第一个菜单场景,相当于各个场景的一个入口场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var menuLayer=cc.Layer.extend({
   ctor:function(){
       this._super();
       // add text
       var tit=new cc.LabelTTF("CVP认证","",60);
       tit.setPosition(240,300);
       this.addChild(tit);
       tit.setTag(1);
       // add menu
       // click to add a text,to test if the scene destroyed when director invoke runScene
       var clickItem = new cc.MenuItemFont("添加文字",this.clickCallback,this);
       var itemstart=new cc.MenuItemFont("开始",this.startScene,this);
       itemstart.setPosition(clickItem.getPositionX(),clickItem.getPositionY()-clickItem.height/2-50);
       var itemhelp=new cc.MenuItemFont("帮助",this.helpScene,this);
       itemhelp.setPosition(itemstart.getPositionX(),itemstart.getPositionY()-itemstart.height/2-50);
       var menu=new cc.Menu(itemstart,itemhelp,clickItem);
       this.addChild(menu);
   },
   startScene:function(){
       cc.director.runScene(new HelloWorldScene());
   },
   helpScene:function(){
       cc.director.runScene(new HelpScene());
   },
   clickCallback:function(){
       // add text
       var test = new cc.LabelTTF("添加的文字","",50);
       var tit = this.getChildByTag(1);
       test.setPosition(tit.getPositionX(),tit.getPositionY()+100);
       this.addChild(test);
   }
});
// define the menu scene
var MenuScene=cc.Scene.extend({
   ctor:function(){
       this._super();
       // define the layer
       var m1=new menuLayer();
       this.addChild(m1);
   }
});

这是hello场景,其中包含了能返回菜单场景的按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var HelloWorldLayer = cc.Layer.extend({
    sprite:null,
    ctor:function () {
        this._super();
        var helloLabel = new cc.LabelTTF("Hello World", "Arial", 38);
        helloLabel.x = size.width / 2;
        helloLabel.y = size.height / 2 + 200;
        this.addChild(helloLabel, 5);
        this.sprite = new cc.Sprite(res.HelloWorld_png);
        this.sprite.attr({
            x: size.width / 2,
            y: size.height / 2
        });
        this.addChild(this.sprite, 0);
        var backItem = new cc.MenuItemFont("返回主界面",this.backCallback,this);
        var menu = new cc.Menu(backItem);
        this.addChild(menu);
        return true;
    },
    backCallback:function(){
        cc.director.runScene(new MenuScene());
    }
});
var HelloWorldScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new HelloWorldLayer();
        this.addChild(layer);
    }
});

这是一个帮助场景,场景中只有一行文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var HelpLayer = cc.Layer.extend({
    ctor:function(){
        this._super();
        var text = new cc.LabelTTF("游戏帮助场景","",100);
        text.setPosition(size.width/2,size.height/2);
        this.addChild(text);
        return true;
    }
});

var HelpScene = cc.Scene.extend({
    ctor:function(){
        this._super();
        var helpLayer = new HelpLayer();
        this.addChild(helpLayer);
        return true;
    }
});

为了不让发帖出现各种bug,我把注释都翻译成英文了,,,也真是拼了,,,哎

最后运行效果

http://www.cocoscvp.com/usercode/2016_04_09/a26fb7aab762fd52abcc8af0d183b8d3322b8117/

大爷赏点儿呗.

欢迎关注我的其它发布渠道