cocos2dx action test
1、CCToggleVisibility对当前的action动作的精灵对象进行取反的visible设置
CCActionInterval* move1 = CCMoveBy::create(1, ccp(250,0)); CCActionInterval* move2 = CCMoveBy::create(1, ccp(0,50)); CCToggleVisibility* tog1 = new CCToggleVisibility(); CCToggleVisibility* tog2 = new CCToggleVisibility(); tog1->autorelease(); tog2->autorelease(); CCFiniteTimeAction* seq = CCSequence::create( move1, tog1, move2, tog2, move1->reverse(), NULL); m_kathia->runAction(seq);
如上显示的动作将会是move1执行1秒然后tog1隐藏,因为当前是隐藏状态所以move2的动作将会处于隐藏状态的执行,当执行到tog2的时候将move2之后的位置显示出来因为之前是隐藏状态所以现在转成显示的,然后再执行move1->reverse()
具体CCToggleVisibility的执行原理可以看他源代码的update函数
void CCToggleVisibility::update(float time) { m_pTarget->setVisible(!m_pTarget->isVisible()); }
当action执行到CCToggleVisibility的时候,只做一个动作就是取反设置该执行精灵的visible
2、removeFromParentAndCleanup 从父节点移除自己,后面的bCleanUp是判断是否移除action
当调用该函数的时候,不管bCleanUp是true还是false都会从父节点中移除自己(引用计数减1);当bCleanUp为true的时候则删除之前回去调用自身拥有的action的release;如果没有调用true会产生本身移除了,但是action对象没有被删除的情况。
这种情况只有用在你想保留该节点的action留作他用。使用时候需要很注意。具体调用的源码如下所示
void CCNode::detachChild(CCNode *child, bool doCleanup) { // IMPORTANT: // -1st do onExit // -2nd cleanup if (m_bRunning) { child->onExitTransitionDidStart(); child->onExit(); } // If you don't do cleanup, the child's actions will not get removed and the // its scheduledSelectors_ dict will not get released! if (doCleanup) { child->cleanup(); } // set parent nil at the end child->setParent(NULL); m_pChildren->removeObject(child); }
如上先判断是否是在running;因为调用一个节点的显示的时候,调用顺序是这样子的:
m_pRunningScene->onEnter();
m_pRunningScene->onEnterTransitionDidFinish();
所以当要停止调用的时候需要反过来停止。
然后判断是否cleanup再移除本身的节点。
如果只是想从父节点移除,放置到另一个父节点则不能调用removeFromParentAndCleanup;需要使用
m_grossini->retain();
m_grossini->removeFromParentAndCleanup(false);
3、CCCallFuncN继承action,对应的回调函数有一个node参数
构造的时候类似于这样子:CCCallFuncN::create( this, callfuncN_selector(ActionRepeatForever::repeatForever) ),即this中有一个repeatForever的函数当调用该action的时候会去调用该函数,并传入谁执行这个action的哪个node
void ActionRepeatForever::repeatForever(CCNode* pSender) { CCRepeatForever *repeat = CCRepeatForever::create( CCRotateBy::create(1.0f, 360) ); pSender->runAction(repeat); }
如上,则可以在psender添加对应的action;
执行顺序:m_grossini->runAction(action); 会调用CCCallFunc的update函数,然后update会调用this->execute();因为execute是虚函数,在CCCallFuncN中有对应的实现,所以会调用CCCallFuncN的execute函数,如下所示
void CCCallFuncN::execute() { if (m_pCallFuncN) { (m_pSelectorTarget->*m_pCallFuncN)(m_pTarget); } 。。。 }
m_pTarget就是调用执行该actionfunc的对象。
4、Spawn: Jump + Rotate
关于这个比较有意思的是页面的动画显示的很和谐:共跳四下,刚好也转720度。
CCAction* action = CCSpawn::create( CCJumpBy::create(2, ccp(300,0), 50, 4), CCRotateBy::create( 2, 720), NULL);
可以在设置动作叠加的时候使用ccspawn;spawn每次都是将两个动作一起叠加;当有多个动作要叠加的时候
unsigned int count = arrayOfActions->count(); CCFiniteTimeAction* prev = (CCFiniteTimeAction*)arrayOfActions->objectAtIndex(0); for (unsigned int i = 1; i < arrayOfActions->count(); ++i) prev = createWithTwoActions(prev, (CCFiniteTimeAction*)arrayOfActions->objectAtIndex(i)); return (CCSpawn*)prev;
CCSpawn* CCSpawn::createWithTwoActions(CCFiniteTimeAction *pAction1, CCFiniteTimeAction *pAction2) { CCSpawn *pSpawn = new CCSpawn(); pSpawn->initWithTwoActions(pAction1, pAction2); pSpawn->autorelease(); return pSpawn; }
如上所示,每次将两个动作组合成一个spawn,然后再跟下一个动作再叠加。然后在显示的时候
void CCSpawn::update(float time){ if (m_pOne) m_pOne->update(time); if (m_pTwo) m_pTwo->update(time); }
会调用每个动作的update,子spawn的update又会调用子spawn的update。所以这里每一个时刻都会通过递归调用当前这一时刻的所有动作。
如果两个动作的时间不一样,在initWithTwoActions会进行CCDelayTime时间差的处理。使得两个动作最后使用的时间是一样的。
6、CCScaleTo 图片长宽比的减小或者增大到指定的比例
create(float duration, float sx, float sy);第一个参数是动作的时间,第二个和第三个参数是缩小或者放大的比例,如果小于1则是缩小,大于1则是放大。
可以使用scaleto来实现翻牌的动作。如下所示
rv->setVisible(false); CCScaleTo* small_ = CCScaleTo::create(1, 0, 1); // 设置动作时间为1秒,x轴最终变成0,y轴的比例不变 CCScaleTo* back_ = CCScaleTo::create(1, 1, 1); // 设置动作的时间为1秒,x轴跟y轴的比例变成1即还原到原来的大小 CCSequence* old_ = CCSequence::create(small_, CCRemoveSelf::create(), NULL);// 变小动作结束之后将自己删除,该动作调用的是removeFromParentAndCleanup CCSequence* new_ = CCSequence::create(CCScaleTo::create(0, 0, 1), CCShow::create(), back_, NULL); // 将自己的x轴变为0,然后显示出来,再然后慢慢还原 CCTargetedAction* a_ = CCTargetedAction::create(m_grossini, old_); rv->runAction(CCSequence::create(a_, new_, NULL));
先将最终显示的设置精灵rv为不可见。
【推荐】国内首个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 重磅开源!