Cocos2d-x-04: 场景与层

作者:慧科集团华东校区-朱家聪老师,转载请注明出处及本链接。

场景和层

在一个游戏中往往有多个场景和多个层。每个场景都有一个或者一个以上的层。在我们所创建的游戏工程中,AppDelegate.cpp文件中使用如下代码来创建一个新的场景:

// create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();

// run
director->runWithScene(scene);


class HelloWorld : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
    
    virtual void onExit();
};

Scene* HelloWorld::createScene()
{
    return HelloWorld::create();
}

在老版本的Cocos2d-x中,将HelloWorld定义为一个Layer。然后在createScene()函数中创建所对应的Scene。再将HelloWorld层添加到这个场景中去。而在最新版本的Cocos2d-x中将HelloWorld直接定义为了一个Scene。在这个场景中我们可以去添加自己的层,来搭建我们需要的游戏场景或者UI界面。

场景过渡

一个完整的游戏一般是由多个场景构成的,这些场景之间需要做互相的切换和调度。以一个游戏的开始界面和设置界面为例来学习场景过渡的用法。

搭建开始游戏界面

//创建背景
Sprite *background = Sprite::create("background.png");
background->setContentSize(visibleSize);
background->setAnchorPoint(Vec2::ZERO);
background->setPosition(origin);
this->addChild(background);

//开始按钮
Sprite *startSpriteNormal = Sprite::create("start-up.png");
Sprite *startSpriteSelect = Sprite::create("start-down.png");
MenuItemSprite *startItem = MenuItemSprite::create(startSpriteNormal, startSpriteSelect, CC_CALLBACK_1(StartGameScene::startGame, this));
startItem->setPosition(Vec2(origin.x+visibleSize.width/2 - 100,origin.y+100));



//设置按钮
MenuItemImage *settingItem = MenuItemImage::create("setting-up.png", "setting-down.png", CC_CALLBACK_1(StartGameScene::settingCallback, this));
settingItem->setPosition(Vec2(origin.x+visibleSize.width/2 + 100, origin.y+100));

//菜单
Menu *menu = Menu::create(startItem, settingItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu);
startScene

场景的过渡和切换

在设置按钮的点击回调方法中,添加代码来完成场景的过渡。这里需要使用到的类是TransitionScene以及他的子类。TransitionScene是一个抽象类,表示用于做场景过渡效果的特殊场景,不能用来直接做场景的切换。而是应该用他的各种子类来实现场景切换的效果。这里我们使用TransitionMoveInL来完成一个从屏幕左边移动进入的场景切换效果。使用Director的pushScene函数来弹出一个新的场景。

void StartGameScene::settingCallback(Ref* pSender){
    //创建设置界面场景
    SettingScene *set = SettingScene::create();
    auto *ts = TransitionMoveInL::create(1.0f, set);
    Director::getInstance()->pushScene(ts);
    
};

搭建设置界面

//背景
Sprite *background = Sprite::create("setting-back.png");
background->setPosition(origin);
background->setAnchorPoint(Vec2::ZERO);
background->setContentSize(visibleSize);
this->addChild(background);

//音效
MenuItemImage *soundOn = MenuItemImage::create("on.png","on.png");
MenuItemImage *soundOff = MenuItemImage::create("off.png","off.png");
MenuItemToggle *soundToggle = MenuItemToggle::createWithCallback(CC_CALLBACK_1(SettingScene::toggleCallback, this), soundOn, soundOff, NULL);
soundToggle->setPosition(Vec2(origin.x+visibleSize.width - 150, origin.y+visibleSize.height / 2 + 10));

//背景音乐
MenuItemImage *musicOn = MenuItemImage::create("on.png","on.png");
MenuItemImage *musicOff = MenuItemImage::create("off.png","off.png");
MenuItemToggle *musicToggle = MenuItemToggle::createWithCallback(CC_CALLBACK_1(SettingScene::toggleCallback, this), musicOn, musicOff, NULL);
musicToggle->setPosition(Vec2(origin.x+visibleSize.width - 150, origin.y+visibleSize.height / 2 - 40));

//OK
MenuItemImage *okItem = MenuItemImage::create("ok-up.png", "ok-down.png", CC_CALLBACK_1(SettingScene::okButtonCallback, this));
okItem->setPosition(Vec2(origin.x+visibleSize.width / 2, 50));

//Menu
Menu *menu = Menu::create(soundToggle, musicToggle, okItem, NULL);
menu->setPosition(origin);
this->addChild(menu);

运行效果:


settingScene

返回原场景

在设置界面的ok键的回调函数中,编写代码返回前一界面。因为我们在第一次界面转换时使用的是Push方法。这是一种类似于栈的场景管理方法,切换到后一个场景时,前一个场景不会被销毁。所以在需要返回时直接使用Pop方法进行弹出即可。

void SettingScene::okButtonCallback(Ref *pSender){
    Director::getInstance()->popScene();
}

场景的生命周期

在Cocos2d-x中,多个场景在转换显示的时候会经历场景的创建和销毁。有一系列的函数可以用于操作在整个场景的生命周期中的各种事件。

系统函数

//场景的生命周期
bool SettingScene::init()
{
    cout<<"场景初始化"<

多场景过渡

两个场景切换时,关系到两个场景之间的生命周期,在Start场景中也可以编写相关函数来同时监控两个场景。

//场景的生命周期
bool StartGameScene::init()
{
    cout<<"场景初始化"<<"StartScene"<

在考虑多场景切换时,我们需要从以下三种情况来尝试。

使用pushScene()跳转到设置界面

在使用push的从场景1跳转到场景2时,场景1虽然会退出,但是并不会被清除。执行后的控制台输出结果如下:

场景初始化SettingScene
退出场景动画开始StartScene
进入场景SettingScene
退出场景StartScene
进入场景动画完成SettingScene

我们可以发现,StartScene并没有被清除,而只是暂时的退出了。

使用replaceScene()跳转到设置界面

replaceScene来实现场景跳转的时候,会在整个场景过渡动画结束之后清除掉StartScene。所以使用replaceScene来跳转的场景无法再使用popScene来进行返回。

场景初始化SettingScene
退出场景动画开始StartScene
进入场景SettingScene
退出场景StartScene
进入场景动画完成SettingScene
场景清除StartScene

使用popScene()返回前一场景

在使用popScene退出一个场景时会完全清楚这个场景并且退出它。

退出场景动画开始SettingScene
退出场景SettingScene
场景清除SettingScene
进入场景StartScene
进入场景动画完成StartScene

你可能感兴趣的:(Cocos2d-x-04: 场景与层)