Cocos2D-x权威指南
上QQ阅读APP看书,第一时间看更新

3.3.2 场景的切换

tests项目是一个Cocos2D-x的功能示例。对于Cocos2D-x的初学者来说,看tests项目中的示例并理解它们,是个不错的学习方式。本节就通过介绍tests的基本结构来介绍场景间的切换。

游戏入口AppDelegate类中的applicationDidFinishLaunching函数如代码清单3-11所示。

代码清单3-11 tests项目的AppDelegate类的applicationDidFinishLaunching函数

bool AppDelegate::applicationDidFinishLaunching()
{
    CCDirector *pDirector=CCDirector::sharedDirector();
    pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());
    pDirector->setDisplayStats(true);
    pDirector->setAnimationInterval(1.0/60);
    CCScene * pScene=CCScene::create();
    CCLayer * pLayer=new TestController();
    pLayer->autorelease();
    pScene->addChild(pLayer);
    pDirector->runWithScene(pScene);
    return true;
}

这里和上一节的applicationDidFinishLaunching有一点区别,它的定义场景和给场景加层的操作都在这个函数里完成,但是本质上是类似的。下面就来看TestController布景层里面是如何调用下一级场景的。

切换场景这个事件应该是在按下主菜单上的按键后发生的,于是找到controller.cpp文件中的menuCallback函数。它是自定义的一个回调函数,在定义布景层时定义。如果不理解这一点,没关系,请跳过,后面会讲解这个问题。

menuCallback函数如代码清单3-12所示。

代码清单3-12 menuCallback函数

void TestController::menuCallback(CCObject * pSender)
{
    CCMenuItem* pMenuItem=(CCMenuItem *)(pSender);
    int nIdx=pMenuItem->getZOrder()- 10000;
    TestScene* pScene=CreateTestScene(nIdx);
    if (pScene)
    {
        pScene->runThisTest();
        pScene->release();
    }
}

除了处理菜单类的内容,这部分可以暂时跳过。后面调用在controller.cpp文件中定义的CreateTestScene函数获得场景,然后调用场景的runThisTest函数,这是自定义的。

首先来看CreateTestScene函数,如代码清单3-13所示。

代码清单3-13 CreateTestScene函数

static TestScene* CreateTestScene(int nIdx)
{
    //清空缓存
    CCDirector::sharedDirector()->purgeCachedData();
    TestScene* pScene=NULL;
    switch (nIdx)
    {
    case TEST_ACTION_MANAGER:
        pScene=new ActionManagerTestScene();
        break;
    //中间部分的代码过长,省略到这部分。如果需要完整代码,请参考Cocos2D-x引擎目录下tests
    //项目的controller.cpp文件
    default:
        break;
    }
    return pScene;
}

这里省略中间的部分,首先调用导演类的清除缓存函数,然后新建场景,并返回场景。

关于场景的定义,来看ActionManagerTestScene场景的定义。ActionManagerTest.h文件中的ActionManagerTestScene类的定义如代码清单3-14所示。

代码清单3-14 ActionManagerTestScene类的定义

class ActionManagerTestScene:public TestScene
{
public:
    virtual void runThisTest();
};

ActionManagerTest.cpp文件中的runThisTest函数的定义如代码清单3-15所示。

代码清单3-15 runThisTest函数的定义

void ActionManagerTestScene::runThisTest()
{
    CCLayer* pLayer=nextActionManagerAction();
    addChild(pLayer);
    CCDirector::sharedDirector()->replaceScene(this);
}

这里做的就是把布景层加入场景中,并把场景通过导演类的replaceScene将当场景替换成场景。

以上过程分为以下三步:

1)调用CCDirector::sharedDirector()->purgeCachedData()清空缓存。

2)新建场景。

3)调用CCDirector::sharedDirector()->replaceScene(this)替换新场景。Cocos2D-x提供了场景间切换的特效,下一节将会介绍这些内容。

注意 不要在节点初始化的init函数中调用replaceScene函数。导演类不允许在一个节点初始化的调用场景替换,否则会导致程序崩溃。

这里说一下压入场景(pushScene)和弹出场景(popScene)。它们都可以用来显示场景和保留当前场景并显示新场景;不同的是它们不把旧场景从内存中释放掉,这样可以提高加载速度,这时需要注意,如果内存不足以支撑的话,建议采用replaceScene函数。