虽然coco2d-x里提供了很多强大的场景转换类 ,但有时候自己需要的一些效果cocos2d-x还是无法解决,毕竟越是方便的东西越有它的局限性,所以我就自己定义了一个场景转换类:
因为自定义的场景转换类 需要继承 CCTransitionScene场景转换基类,于是我还是把场景转换类的代码 全部看了一遍,以防在某些环节使用不当而导致未知的错误,所以我先来说明CCTransitionScene 的内部构造和实现方式。
首先,我们来看看 CCTransitionScene的定义
class CC_DLL CCTransitionScene : public CCScene
{
protected:
//载入场景
CCScene * m_pInScene;
//载出场景
CCScene * m_pOutScene;
//动画播放时间
float m_fDuration;
//顾名思义 就是载入场景是否置顶
bool m_bIsInSceneOnTop;
//载出场景是否需要被清理,在clearnup()中被调用
bool m_bIsSendCleanupToScene;
public:
CCTransitionScene();
virtual ~CCTransitionScene();
//决定场景 层的先后顺序
virtual void draw();
virtual void onEnter();
virtual void onExit();
//清理载出场景
virtual void cleanup();
/** creates a base transition with duration and incoming scene
@deprecated: This interface will be deprecated sooner or later.
*/
//CC_DEPRECATED_ATTRIBUTE 表示 不建议使用的,分配空间函数
CC_DEPRECATED_ATTRIBUTE static CCTransitionScene * transitionWithDuration(float t, CCScene *scene);
/** creates a base transition with duration and incoming scene */
//同上,现在cocos2d-x把地址分配函数都 统一成create ,这点做的很好
static CCTransitionScene * create(float t, CCScene *scene);
/** initializes a transition with duration and incoming scene */
//初始化函数,一般不需要自己调用
virtual bool initWithDuration(float t,CCScene* scene);
/** called after the transition finishes */
//销毁函数,当新场景载入完成时隐式销毁旧场景
void finish(void);
/** used by some transitions to hide the outer scene */
//隐藏旧场景 显示新场景
void hideOutShowIn(void);
protected:
//把载入场景置顶
virtual void sceneOrder();
private:
void setNewScene(float dt);
};
看看各个函数的定义
CCTransitionScene * CCTransitionScene::create(float t, CCScene *scene)
{
CCTransitionScene * pScene = new CCTransitionScene();//分配地址
if(pScene && pScene->initWithDuration(t,scene))//初始化
{
//用smart point
pScene->autorelease();
return pScene;
}
//安全释放,既if(pScene)delete pScene = 0
CC_SAFE_DELETE(pScene);
return NULL;
}
transitionWithDuration 函数也是调用create
bool CCTransitionScene::initWithDuration(float t, CCScene *scene)
{
CCAssert( scene != NULL, "Argument scene must be non-nil");
if (CCScene::init())
{
m_fDuration = t;
// retain
m_pInScene = scene;
m_pInScene->retain();
//保证2个场景同时存在
m_pOutScene = CCDirector::sharedDirector()->getRunningScene(); if (m_pOutScene == NULL) { m_pOutScene = CCScene::create(); m_pOutScene->init(); } m_pOutScene->retain(); //防止 旧场景 和新场景是 同一场景 CCAssert( m_pInScene
!= m_pOutScene, "Incoming scene must be different from the outgoing scene" ); // disable events while transitions
CCDirector* pDirector = CCDirector::sharedDirector();
//停止 所有touch 事件
pDirector->getTouchDispatcher()->setDispatchEvents(false);
让新场景置顶
this->sceneOrder();
return true;
}
else
{
return false;
}
}
void CCTransitionScene::sceneOrder()
{
m_bIsInSceneOnTop = true;
}
void CCTransitionScene::draw()
{
CCScene::draw();
//画场景的先后顺序
if( m_bIsInSceneOnTop ) {
m_pOutScene->visit();
m_pInScene->visit();
} else {
m_pInScene->visit();
m_pOutScene->visit();
}
}
void CCTransitionScene::finish()
{
// clean up
//场景转换完成,还原所有场景 然后delete 掉旧场景 replace 到新场景
m_pInScene->setVisible(true);
m_pInScene->setPosition(ccp(0,0));
m_pInScene->setScale(1.0f);
m_pInScene->setRotation(0.0f);
m_pInScene->getCamera()->restore();
m_pOutScene->setVisible(false);
m_pOutScene->setPosition(ccp(0,0));
m_pOutScene->setScale(1.0f);
m_pOutScene->setRotation(0.0f);
m_pOutScene->getCamera()->restore();
//[self schedule:@selector(setNewScene:) interval:0];
this->schedule(schedule_selector(CCTransitionScene::setNewScene), 0);
}
void CCTransitionScene::setNewScene(float dt)
{
CC_UNUSED_PARAM(dt);
// [self unschedule:_cmd];
// "_cmd" is a local variable automatically defined in a method
// that contains the selector for the method
this->unschedule(schedule_selector(CCTransitionScene::setNewScene));
CCDirector *director = CCDirector::sharedDirector();
// Before replacing, save the "send cleanup to scene"
m_bIsSendCleanupToScene = director->isSendCleanupToScene();
director->replaceScene(m_pInScene);
// enable events while transitions(恢复touch事件)
director->getTouchDispatcher()->setDispatchEvents(true);
// issue #267
m_pOutScene->setVisible(true);
}
void CCTransitionScene::hideOutShowIn()
{
m_pInScene->setVisible(true);
m_pOutScene->setVisible(false);
}
// custom onEnter
void CCTransitionScene::onEnter()
{
CCScene::onEnter();
m_pInScene->onEnter();
// outScene should not receive the onEnter callback
}
// custom onExit
void CCTransitionScene::onExit()
{
CCScene::onExit();
m_pOutScene->onExit();
// inScene should not receive the onExit callback
// only the onEnterTransitionDidFinish
m_pInScene->onEnterTransitionDidFinish();
}
// custom cleanup
void CCTransitionScene::cleanup()
{
CCScene::cleanup();
if( m_bIsSendCleanupToScene )
m_pOutScene->cleanup();
}
还有cocos2d 2.0 的新派生类CCTransitionScene,但今天就写怎么多,下次继续写