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函数。