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()那里设置了禁止点击的操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!