cocos2dx CCTransitionScene

Posted czwlinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cocos2dx CCTransitionScene相关的知识,希望对你有一定的参考价值。

场景切换的类

cocos已经给我们实现了很多的场景切换。这里以CCTransitionJumpZoom* create(float t, CCScene* scene);为例

CCTransitionJumpZoom是继承CCTransitionScene,创建一个新的CCTransitionJumpZoom时候,要传入场景切换动作的持续时间,还有新的场景对象。

    CCScene* s = new TransitionsTestScene();
    CCLayer* pLayer = new TestLayer2();
    s->addChild(pLayer);
    CCScene* pScene = CCTransitionJumpZoom::create(1.2f, s);
    s->release();
    pLayer->release();
    if (pScene)
        CCDirector::sharedDirector()->replaceScene(pScene);

如上大致是创建一个场景切换的动作。有一个新的场景。然后创建一个CCTransitionJumpZoom,最后将这个新的CCTransitionJumpZoom替换。

 

一、CCTransitionJumpZoom::create(1.2f, s);

CCTransitionJumpZoom定义了m_fDuration、m_pInScene和m_pOutScene用来存储动作持续时间,要切换进来的场景,还有要切走的场景。

        m_fDuration = t;
        m_pInScene = scene;
        m_pInScene->retain();
        m_pOutScene = CCDirector::sharedDirector()->getRunningScene();
        m_pOutScene->retain();

以上是create的创建过程。

 

二、替换完成之后进行显示的动作

1、因为在CCDirector::sharedDirector()->replaceScene(pScene);的时候会给m_pNextScene = pScene 所以这里m_pNextScene不为空调用切换下一个场景的函数

void CCDirector::drawScene(void)
{
    if (m_pNextScene)
    {
        setNextScene();
    }

2、setNextScene()

void CCDirector::setNextScene(void)
{
    bool runningIsTransition = dynamic_cast<CCTransitionScene*>(m_pRunningScene) != NULL; // 当前正在跑的是正常的scene所以这里是false
    bool newIsTransition = dynamic_cast<CCTransitionScene*>(m_pNextScene) != NULL; // 放置的下一个scene是TransitionScene所以返回true

    // If it is not a transition, call onExit/cleanup
     if (! newIsTransition)
     {
         if (m_pRunningScene)
         {
             m_pRunningScene->onExitTransitionDidStart(); //因为onEnter先进所以OnExit后调用
             m_pRunningScene->onExit();
         }
 
         // issue #709. the root node (scene) should receive the cleanup message too
         // otherwise it might be leaked.
         if (m_bSendCleanupToScene && m_pRunningScene)
         {
             m_pRunningScene->cleanup();
         }
     }

    if (m_pRunningScene)
    {
        m_pRunningScene->release();
    }
    m_pRunningScene = m_pNextScene;
    m_pNextScene->retain();
    m_pNextScene = NULL;

    if ((! runningIsTransition) && m_pRunningScene)
    {
        m_pRunningScene->onEnter(); // 通过上面的操作,之前的scene已经移除掉了当前的Direct,这里是新的transtionscene的onEnter函数
        m_pRunningScene->onEnterTransitionDidFinish();
    }
}

因为整个代码都挺有意思的就全部贴出来了。

3、调用TransitionScene子类onEnter函数

 

void CCTransitionJumpZoom::onEnter()
{
    CCTransitionScene::onEnter();

这里要先调用父类的onEnter函数。

void CCTransitionScene::onEnter()
{
    CCScene::onEnter();
    CCDirector::sharedDirector()->getTouchDispatcher()->setDispatchEvents(false);
    m_pOutScene->onExitTransitionDidStart();
    m_pInScene->onEnter();
}

调用了m_pOutScene->onExitTransitionDidStart();然后又调用了m_pInScene->onEnter();

然后子类再执行两个scene期望执行的动作。

    CCActionInterval *delay = CCDelayTime::create(m_fDuration/2);
    m_pOutScene->runAction(jumpZoomOut);
    m_pInScene->runAction(
        CCSequence::create(
            delay,
            jumpZoomIn,
            CCCallFunc::create(this, callfunc_selector(CCTransitionScene::finish)),
            NULL));

如上在执行完action的时候会调用finish函数,进行m_pInScene和m_pOutScene的收尾操作。最后director->replaceScene(m_pInScene);将这个TransitionScene给去除掉,然后替换成最终的scene

 

在替换掉之后调用CCTransitionScene::onExit() 执行如下动作

    m_pOutScene->onExit();
    m_pInScene->onEnterTransitionDidFinish();

 

从上面流程可以看出:新的scene跟旧的scene

1、旧的onExitTransitionDidStart

2、新的onEnter

当完成一系列的transition动作之后

3、旧的onExit

4、新的onEnterTransitionDidFinish

 

所以我们在新的scene要执行action等动作的时候需要在onEnterTransitionDidFinish里面设置。

 

当CCTransitionScene在执行的过程中我们发现所有的点击都执行不了,这是因为在CCTransitionScene::onEnter()那里设置了禁止点击的操作。

以上是关于cocos2dx CCTransitionScene的主要内容,如果未能解决你的问题,请参考以下文章

cocos2dx android 代码混淆

cocos2dx android 代码混淆

cocos2dx 用啥工具开发

C++小问题cocos2dx小问题

(一)cocos2dx坑爹之旅--天坑CocosBuilder

cocos2dx C++关于cocos2dx的C++调用创建项目