cocos2dx CCTransition各个子项
1、CCTransitionProgress
该类继承了CCTransitionScene,并且有两个子类:实现了顺时针跟逆时针的进度切屏动作。
void CCTransitionProgress::onEnter() { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCRenderTexture *texture = CCRenderTexture::create((int)size.width, (int)size.height); texture->getSprite()->setAnchorPoint(ccp(0.5f,0.5f)); texture->setPosition(ccp(size.width/2, size.height/2)); texture->setAnchorPoint(ccp(0.5f,0.5f)); texture->clear(0, 0, 0, 1); texture->begin(); m_pSceneToBeModified->visit(); // 用RenderTexture截屏,将当前的显示的scene截屏。具体可以看RenderTexture的使用方法,这里不作具体说明。 texture->end(); hideOutShowIn(); // 已经把out的截屏,则可以把它隐藏掉了 // 将截完的图片从texture取出来放到ProgressTimer CCProgressTimer *pNode = progressTimerNodeWithRenderTexture(texture);//两个子类重写了该方法,实现顺时针或者逆时针的操作,其实在本类,该函数更应该使用纯虚函数。 CCActionInterval* layerAction = (CCActionInterval*)CCSequence::create( CCProgressFromTo::create(m_fDuration, m_fFrom, m_fTo), // 这里使用的是从100到0,是因为刚开始是全部遮挡住的所以是100,最终我们需要的是将out层消失,所以最终是需要0 CCCallFunc::create(this, callfunc_selector(CCTransitionProgress::finish)), NULL); // run the blend action pNode->runAction(layerAction); // 这里将pNode放到上一层,确保能够顶层显示(out的精灵图片) addChild(pNode, 2, kCCSceneRadial); }
类似于进度切换的,如果需要另外的风格,则可以参照对应的子类进行实现:CCTransitionProgressRadialCCW,CCTransitionProgressRadialCW;比如这里抄CCTransitionProgressRadialCW自己重写一个

class CCTransitionProgressRadialME : public CCTransitionProgress { public: static CCTransitionProgressRadialME* create(float t, CCScene* scene) { CCTransitionProgressRadialME* pScene = new CCTransitionProgressRadialME(); if (pScene && pScene->initWithDuration(t, scene)) { pScene->autorelease(); return pScene; } CC_SAFE_DELETE(pScene); return NULL; } protected: virtual CCProgressTimer* progressTimerNodeWithRenderTexture(CCRenderTexture* texture) { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCProgressTimer* pNode = CCProgressTimer::create(texture->getSprite()); // but it is flipped upside down so we flip the sprite pNode->getSprite()->setFlipY(true); pNode->setType(kCCProgressTimerTypeRadial); // Return the radial type that we want to use pNode->setReverseDirection(false); pNode->setPercentage(100); pNode->setPosition(ccp(size.width / 2, size.height / 2)); pNode->setAnchorPoint(ccp(0.5f, 0.5f)); return pNode; } };
代码中:pNode->getSprite()->setFlipY(true); 是因为opengl是以左下角为0坐标。而正常的图片以左上角为0坐标。比如正常的图片的矩阵
123
456
789
但是opengl从左下角开始扫描则存储的图片矩阵就成为了
789
456
123
所以这里需要进行setFlipY的操作。
具体的可以实现自己想要的功能。
2、CCTransitionCrossFade
inTexture->begin(); m_pInScene->visit(); inTexture->end(); outTexture->begin(); m_pOutScene->visit(); outTexture->end(); ccBlendFunc blend1 = {GL_ONE, GL_ONE}; ccBlendFunc blend2 = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}; // set blendfunctions inTexture->getSprite()->setBlendFunc(blend1); outTexture->getSprite()->setBlendFunc(blend2); // add render textures to the layer layer->addChild(inTexture); layer->addChild(outTexture); // initial opacity: inTexture->getSprite()->setOpacity(255); outTexture->getSprite()->setOpacity(255); // create the blend action CCAction* layerAction = CCSequence::create ( CCFadeTo::create(m_fDuration, 0), CCCallFunc::create(this, callfunc_selector(CCTransitionScene::hideOutShowIn)), CCCallFunc::create(this, callfunc_selector(CCTransitionScene::finish)), NULL ); outTexture->getSprite()->runAction( layerAction ); addChild(layer, 2, kSceneFade);
由于是图片混淆的方式进行切换。所以需要两张图片,这里将inscene跟outscene都获取出图片然后进行渐变的操作。
in图片保持原样不需要进行额外的操作,所以sec_alpha跟dest_alpha的因子都设置成GL_ONE
out图片需要从不透明渐变成全透明。{GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};该参数的意思是:
假设我们将in图片上面的某个点的颜色设置为dest_col,将out图片对应位置的点的颜色设置为src_col
则通过那两个参数的操作之后的颜色则为:result_col = src_col * SRC_ALPHA + dest_col * (1 - SRC_ALPHA) 当src_alpha从1 变成0 之后就变成全透明了。这里src_alpha的值是x / 255.0f ;x的取值范围是0~255
这里先将x设置成255,即:outTexture->getSprite()->setOpacity(255);
接下去的操作就是添加action:CCFadeTo::create(m_fDuration, 0) ,将to设置为0,即最终的src_alpha设置为0
bool CCFadeTo::initWithDuration(float duration, GLubyte opacity) { m_toOpacity = opacity; // 初始化为0 void CCFadeTo::startWithTarget(CCNode *pTarget) { CCRGBAProtocol *pRGBAProtocol = dynamic_cast<CCRGBAProtocol*>(pTarget); if (pRGBAProtocol) { m_fromOpacity = pRGBAProtocol->getOpacity(); // 将刚才设置的setOpacity(255)设置给from void CCFadeTo::update(float time) { CCRGBAProtocol *pRGBAProtocol = dynamic_cast<CCRGBAProtocol*>(m_pTarget); if (pRGBAProtocol) { pRGBAProtocol->setOpacity((GLubyte)(m_fromOpacity + (m_toOpacity - m_fromOpacity) * time)); // 从255到0的过程
如上是fadeto的action实现过程。
接下去调用finish的action函数。会调用:director->replaceScene(m_pInScene);将inscene替换进来,替换完成之后本身的CCTransitionScene会被调用OnExit()函数,
void CCTransitionCrossFade::onExit() { // remove our layer and release all containing objects this->removeChildByTag(kSceneFade, false);
则刚才操作的layer会被remove掉
3、不大理解的CCOrbitCamera
顾名思义Camera就是以相机的视角来显示
该action是跟camera有关的。当前处于3D的时候如果图片不在正中间,所显示的效果跟期望的效果可能会有差(网上看的)
如果要让它没差,则需要将视角变成2D的:CCDirector::sharedDirector()->setProjection(ccDirectorProjection::kCCDirectorProjection2D);
图片沿y轴旋转90度:CCOrbitCamera* cameraAction1 = CCOrbitCamera::create(5.0f, 1, 0, 0, -90, 0, 0);
图片沿x轴旋转90度:CCOrbitCamera* cameraAction2 = CCOrbitCamera::create(5.0f, 1, 0, 0, 90, 90, 0);
旋转度数的多少是deltaAngles这个参数决定的。
注意:最好操作都是在90度以内的
void CCOrbitCamera::update(float dt) { float r = (m_fRadius + m_fDeltaRadius * dt) * CCCamera::getZEye();//目前知道的只有正负值之分负值为原图片的左右镜像 float za = m_fRadZ + m_fRadDeltaZ * dt;//原来的z的弧度再加上delta的弧度 float xa = m_fRadX + m_fRadDeltaX * dt;//原来的x的弧度再加上delta的弧度 float i = sinf(za) * cosf(xa) * r + m_fCenterXOrig;//当xa为90度的时候cos(xa)=0即i为0,j为1 float j = sinf(za) * sinf(xa) * r + m_fCenterYOrig;//所以当xa是否为90度即angleX决定了沿x轴旋转还是沿y轴旋转 float k = cosf(za) * r + m_fCenterZOrig;//如果deltaAngleZ为0时,如果za为0或者90度会导致ij为0或者k为0从而整个页面都不动 m_pTarget->getCamera()->setEyeXYZ(i,j,k); }
【推荐】国内首个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 重磅开源!