Cocos2d-x中的那些坑-- popScene 不能使用TransitionScene的一种解决方法

来源:互联网 发布:什么叫erp软件 编辑:程序博客网 时间:2024/05/23 00:03

Cocos2d-x的Director提供了pushScene,replaceScene和popScene两个函数来负责控制场景的切换,使用pushScene和replaceScene时可以传入TransitionScene作为参数来实现让当前Scene以某种过渡跳转到下一个Scene,但是当需要使用popScene弹出当前场景,而又想加入过渡动画的话,引擎却是没有提供popSceneWithTransition之类的函数了。要实现popScene时也有过渡的话,从Cocos2d-x的论坛上看到一篇讨论关于如何实现popSceneWithTransition的帖子,链接如下:

http://discuss.cocos2d-x.org/t/tip-implement-popscene-with-transition/3647

里面已经提出了实现的方法,基本思路就是在为Director添加一个新的支持使用过渡来弹出场景的函数,帖子中挺长,中间提出了多种实现方式,

有使用模板成员函数来实现的,如下所示:

template<typename T>void popSceneWithTransition(float t){                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 = (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);       CCScene* trans = T::create(t, m_pNextScene);            //m_pobScenesStack->replaceObjectAtIndex(c-1, (CCScene*)trans);                  m_pNextScene = trans;}   }

以上方法只能支持只需要一个float参数来进行创建的Transition,对于像TransitionPageTurn这样的Transition就不能支持了

也有人提出为3.x编写的使用了C++ 11的function作为参数,结合lambda表达式的版本。

这里贴出我个人觉得比较容易理解也是比较灵活好用一个实现方法,需要实现2个函数:

CCScene *previousScene(void) {    unsigned int c = m_pobScenesStack->count();    if (c <= 1) return NULL;        return (CCScene*)m_pobScenesStack->objectAtIndex(c - 2);    }void popScene(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);    }}
在Director中实现了以上的2个函数后,在代码中就可以使用以下的例子代码来进行带过渡的popScene了:

CCScene *prevScene = CCDirector::sharedDirector()->previousScene();CCTransitionScene* transition = CCTransitionPageTurn::create(0.66, prevScene, false);CCDirector::sharedDirector()->popScene(transition);

以上的方法也可以适用于Cocos2d-x 3.x版本,这里给出在3.x版本中实现的版本:

Scene * Director::getPreviousScene(){unsigned int c = _scenesStack.size();if (c <= 1) return NULL;return (Scene*)_scenesStack.at(c - 2);}void Director::popSceneWithTransition(Scene * trans){log("popSceneWithTransition+++++++++++++++++++++++++++++++stack size = %d",_scenesStack.size());CCASSERT(_runningScene != NULL, "running scene should not null");_scenesStack.popBack();unsigned int c = _scenesStack.size();if (c == 0) {end();}else {_sendCleanupToScene = true;                //以下2句原来是个人认为应该将弹出当前场景后,将前一个已被包装在过渡场景中的previuousScene也弹出,然后压入包装好的TransitionScene                //后来仔细查看了源码,发现其实没有这2句,也是可以正常工作的//_scenesStack.popBack();//_scenesStack.pushBack(trans);_nextScene = trans; // (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);}}


目前还不知道有没有更好的实现方法微笑



0 0