cocos2d-xでトランジションを指定してpopSceneする

cocos2d-xの2.2.2での話。

cocos2d-xにpushSceneがあることに、つい先ほど気付いた。
シーンを完全に置き換えるreplaceSceneがあることは当然知っていたのだけど、前のシーンを残した状態で新たなシーンに遷移するpushSceneがあることを見落としていた。
(普通に考えれば、そりゃあるよね)

たとえば、ゲームのプレイ画面からメニュー画面を開くとき。
pushSceneでメニュー画面に遷移して、popSceneでプレイ画面に戻ってこられるので、なかなか便利だ。
中でも何が一番便利かといえば、CCTransitionXXを使って簡単に遷移アニメーション効果を付けられるところだろう。

ただし。
pushSceneにはCCTransitionXXをセットできるのだけど、不思議な事にpopSceneにはそれができない。
せっかく遷移アニメーションで気持ちよくメニュー画面を開いても、閉じるときに何もなくただ切り替わるだけでは違和感ありありで使えない。

そこで調べてみたところ、CCDirectionに手を加える事でpopSceneにCCTransitionXXをセットすることができた。
本当はCCDirectionなどに手を加えたくはないのだけど、他に方法はなさそうなのでしょうがない。

CCDirection.cppに以下の2つのメソッドを追加する。
(当然ヘッダーファイルの書き換えも必要)

// ひとつ前(戻り先)のCCSceneを返す
CCScene *CCDirector::previousScene(void) {
    unsigned int c = m_pobScenesStack->count();
    if (c < = 1) return NULL;
    return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);
}

// トランジションを指定してpopSceneする
void CCDirector::popSceneWithTransition(CCScene *trans) {
    CCAssert(m_pRunningScene != NULL, "running scene should not null");
    m_pobScenesStack->removeLastObject();
    unsigned int c = m_pobScenesStack->count();
    
    if (c == 0) {
        end();
    }
    else {
        m_bSendCleanupToScene = true;
        m_pNextScene = trans;
    }
}

こんなふうに使います。

CCDirector *director = CCDirector::sharedDirector();

// 戻り先のシーンを取得。
CCScene *scene = director->previousScene();

// トランジションを作成。
CCTransitionScene* transition = CCTransitionSlideInL::create(0.5f, scene);

// トランジションを指定してpopSceneする
director->popSceneWithTransition(transition);

test
CCScene *CCDirector::previousScene(void) {
    unsigned int c = m_pobScenesStack->count();
    if (c <= 1) return NULL;
    return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);
}

void CCDirector::popSceneWithTransition(CCScene *trans) {
    CCAssert(m_pRunningScene != NULL, "running scene should not null");
    m_pobScenesStack->removeLastObject();
    unsigned int c = m_pobScenesStack->count();
    
    if (c == 0) {
        end();
    }
    else {
        m_bSendCleanupToScene = true;
        m_pNextScene = trans; // (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);
    }
}
CCScene *CCDirector::previousScene(void) {
    unsigned int c = m_pobScenesStack->count();
    if (c <= 1) return NULL;
    return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);
}

void CCDirector::popSceneWithTransition(CCScene *trans) {
    CCAssert(m_pRunningScene != NULL, "running scene should not null");
    m_pobScenesStack->removeLastObject();
    unsigned int c = m_pobScenesStack->count();
    
    if (c == 0) {
        end();
    }
    else {
        m_bSendCleanupToScene = true;
        m_pNextScene = trans; // (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);
    }
}
CCScene *CCDirector::previousScene(void) {
    unsigned int c = m_pobScenesStack->count();
    if (c <= 1) return NULL;
    return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);
}

void CCDirector::popSceneWithTransition(CCScene *trans) {
    CCAssert(m_pRunningScene != NULL, "running scene should not null");
    m_pobScenesStack->removeLastObject();
    unsigned int c = m_pobScenesStack->count();
    
    if (c == 0) {
        end();
    }
    else {
        m_bSendCleanupToScene = true;
        m_pNextScene = trans; // (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);
    }
}
CCScene *CCDirector::previousScene(void) {
    unsigned int c = m_pobScenesStack->count();
    if (c <= 1) return NULL;
    return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);
}

void CCDirector::popSceneWithTransition(CCScene *trans) {
    CCAssert(m_pRunningScene != NULL, "running scene should not null");
    m_pobScenesStack->removeLastObject();
    unsigned int c = m_pobScenesStack->count();
    
    if (c == 0) {
        end();
    }
    else {
        m_bSendCleanupToScene = true;
        m_pNextScene = trans; // (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);
    }
}

cocos2d-xでトランジションを指定してpopSceneする” への1件の返信

  1. ピンバック: #cocos2dx トランジションを指定したpopSceneをライブラリを魔改造せずに実装する