首页 > 代码库 > Cocos2d-x场景切换相关函数介绍

Cocos2d-x场景切换相关函数介绍

场景切换是通过导演类Director实现的,其中的相关函数如下:

runWithScene(Scene* scene)。该函数可以运行场景。只能在启动第一个场景时候调用该函数。如果已经有一个场景运行情况下则不能调用该函数。

replaceScene(Scene* scene)。切换到下一个场景。用一个新的场景替换当前场景,当前场景被终端释放。

pushScene(Scene* scene)。切换到下一个场景。将当前场景挂起放入到场景堆栈中,然后再切换到下一个场景中。

void popScene()。与pushScene配合使用,可以回到上一个场景。

void popToRootScene()。与pushScene配合使用,可以回到根场景。

我们需要注意replaceScene和pushScene使用的区别。replaceScene会释放和销毁场景,如果需要保持原来场景的状态,replaceScene函数不适合。pushScene并不会释放和销毁场景,原来场景的状态可以保持,但是场景不能放太多的场景对象。

使用replaceScene代码如下:

auto sc = Setting::createScene();
Director::getInstance()->replaceScene(sc);

其中的Setting是下一个要切换的场景。使用pushScene代码如下:

auto sc = Setting::createScene();
Director::getInstance()->pushScene(sc);

从Setting场景回到上一个场景使用代码如下:

Director::getInstance()->popScene();

下面我们通过一个实例场景切换相关函数,如下图所示有两个场景:HelloWorld和Setting(设置)。在HelloWorld场景点击“游戏设置”菜单可以切换到Setting场景,在Setting场景中点击“OK”菜单可以返回到HelloWorld场景。


我们首先需要在工程中添加一个Setting场景(SettingScene.cpp和SettingScene.h),如下图所示,右键点击HelloWorld工程中Classes文件夹,在弹出菜单中选择“添加”→“新建项”:


弹出对话框如下图所示,在名称中输入“SettingScene.cpp”,并选择保存文件位置,然后点击“添加”按钮创建SettingScene.cpp。使用同样的方法创建SettingScene.h。


下面我们看看代码部分,HelloWorldScene.cpp中的重要代码如下:

bool HelloWorld::init()
{  
   if ( !Layer::init() )
   {
       return false;
   }
   
   Size visibleSize = Director::getInstance()->getVisibleSize();
   Point origin = Director::getInstance()->getVisibleOrigin();
 
   Sprite *bg = Sprite::create("background.png");
   bg->setPosition(Point(origin.x + visibleSize.width/2,
                             origin.y +visibleSize.height /2));
   this->addChild(bg);
 
    //开始精灵
   Sprite *startSpriteNormal = Sprite::create("start-up.png");
   Sprite *startSpriteSelected =Sprite::create("start-down.png");
 
    MenuItemSprite*startMenuItem = MenuItemSprite::create(startSpriteNormal,
                                       startSpriteSelected,
                   CC_CALLBACK_1(HelloWorld::menuItemStartCallback,this));
    startMenuItem->setPosition(Director::getInstance()->convertToGL(Point(700,170)));
   
    //设置图片菜单
   MenuItemImage *settingMenuItem = MenuItemImage::create(
                            "setting-up.png",
                            "setting-down.png",
                                 CC_CALLBACK_1(HelloWorld::menuItemSettingCallback,this));
    settingMenuItem->setPosition(Director::getInstance()->convertToGL(Point(480,400)));
   
    //帮助图片菜单
   MenuItemImage *helpMenuItem = MenuItemImage::create(
                             "help-up.png",
                            "help-down.png",
                                 CC_CALLBACK_1(HelloWorld::menuItemHelpCallback,this));   
    helpMenuItem->setPosition(Director::getInstance()->convertToGL(Point(860,480)));
 
    Menu*mu = Menu::create(startMenuItem, settingMenuItem, helpMenuItem, NULL);        
    mu->setPosition(Point::ZERO);
    this->addChild(mu);
   
   return true;
}
 
voidHelloWorld::menuItemSettingCallback(Ref* pSender)                                                    ①
{  
    autosc = Setting::createScene();                                                                                                     ②
    //Director::getInstance()->replaceScene(sc);                                                                                 ③
    Director::getInstance()->pushScene(sc);                                                                              ④
}
 
void HelloWorld::menuItemHelpCallback(Ref*pSender)
{
   MenuItem* item = (MenuItem*)pSender;
    log("TouchHelp %p", item);
}
 
void HelloWorld::menuItemStartCallback(Ref*pSender)
{
   MenuItem* item = (MenuItem*)pSender;
    log("TouchStart %p", item);
}

上述代码中的第①行定义的函数menuItemSettingCallback,是在用户点击“游戏设置”菜单时候回调。第②行代码是创建设置创建对象。第③行是使用replaceScene函数进行场景切换。第④行代码是pushScene函数进行场景切换。

HelloWorldScene.cpp中的重要代码如下:

bool Setting::init()
{
   if ( !Layer::init() )
   {
       return false;
   }
   
   Size visibleSize = Director::getInstance()->getVisibleSize();
   Point origin = Director::getInstance()->getVisibleOrigin();
 
   Sprite *bg = Sprite::create("setting-back.png");
   bg->setPosition(Point(origin.x + visibleSize.width/2,
                             origin.y +visibleSize.height /2));
   this->addChild(bg);
 
    //音效
   auto soundOnMenuItem = MenuItemImage::create(
                            "on.png",
                             "on.png");
   auto soundOffMenuItem = MenuItemImage::create(
                            "off.png",
                            "off.png");
   
   auto soundToggleMenuItem = MenuItemToggle::createWithCallback(
                  CC_CALLBACK_1(Setting::menuSoundToggleCallback,this),
                                                                            soundOnMenuItem,
                                                                            soundOffMenuItem,
                                                                            NULL);
    soundToggleMenuItem->setPosition(Director::getInstance()->convertToGL(Point(818,220)));
   
   //音乐
   auto musicOnMenuItem  =MenuItemImage::create(
                            "on.png",
                            "on.png");
    automusicOffMenuItem  =MenuItemImage::create(
                            "off.png",
                            "off.png");
   auto musicToggleMenuItem = MenuItemToggle::createWithCallback(
                           CC_CALLBACK_1(Setting::menuMusicToggleCallback,this),
                                                   musicOnMenuItem,
                                                   musicOffMenuItem,
                                                    NULL);
    musicToggleMenuItem->setPosition(Director::getInstance()->convertToGL(Point(818,362)));
 
   //Ok按钮
    autookMenuItem  = MenuItemImage::create(
                            "ok-down.png",
                            "ok-up.png",
                                 CC_CALLBACK_1(Setting::menuOkCallback, this));
 
    okMenuItem->setPosition(Director::getInstance()->convertToGL(Point(600,510)));
 
   Menu* mn = Menu::create(soundToggleMenuItem,
                                                                   musicToggleMenuItem,okMenuItem,NULL);
    mn->setPosition(Point::ZERO);
   this->addChild(mn);
   
   return true;
}
 
void Setting::menuOkCallback(Ref*pSender)                                                                                   ①
{
    Director::getInstance()->popScene();                                                                                             ②
}
void Setting::menuSoundToggleCallback(Ref*pSender)
{}
void Setting::menuMusicToggleCallback(Ref*pSender)
{}

上述代码中的第①行定义的函数menuOkCallback,是在用户在设置场景点击“OK”菜单时候回调。第②行代码是使用popScene函数返回HelloWorld场景。

更多内容请关注Cocos2d-x系列图书《Cocos2d-x实战(卷Ⅰ):C++开发》
本书交流讨论网站:http://www.cocoagame.net
欢迎加入cocos2d-x技术讨论群:257760386、327403678