首页 > 代码库 > Cocos2d-x学习笔记(六)CCAction分析
Cocos2d-x学习笔记(六)CCAction分析
原创文章,转载请注明出处:http://blog.csdn.net/sfh366958228/article/details/38821319
前言
千呼万唤始出来,不知你与我的心情是否一样,终于是等到了CCAction的出场。如果说CCSprite是身体,那么CCAction一定就是灵魂,它的组合,让整个游戏充满活力,当然,充满活力的方法也并非仅此而已。
源码分析
class CC_DLL CCAction : public CCObject { public: CCAction(void); virtual ~CCAction(void); const char* description(); // virtual CCObject* copyWithZone(CCZone *pZone); // 动作是否完成 virtual bool isDone(void); // 在动作开始之前被调用,它将设置一个target virtual void startWithTarget(CCNode *pTarget); // 在动作完成后调用,它将把target设置为空。注意,不要调用这个方法,取而代之的十target->stopAction(action) virtual void stop(void); // 调用每一帧。注意:不要重构它,除非你确保自己在做什么 virtual void step(float dt); /** *每帧会调用一次,time是一个0~1之间的值 * * For example: * - 0 意味着动作刚开始 * - 0.5 意味着动作处于中间 * - 1 意味着动作结束了 **/ virtual void update(float time); // 获取/设置动作的target inline CCNode* getTarget(void) { return m_pTarget; } inline void setTarget(CCNode *pTarget) { m_pTarget = pTarget; } // 获取/设置动作最初的target(一般不调用set) inline CCNode* getOriginalTarget(void) { return m_pOriginalTarget; } inline void setOriginalTarget(CCNode *pOriginalTarget) { m_pOriginalTarget = pOriginalTarget; } // 获取/设置Tag inline int getTag(void) { return m_nTag; } inline void setTag(int nTag) { m_nTag = nTag; } public: // 创建一个Action static CCAction* create(); protected: CCNode *m_pOriginalTarget; CCNode *m_pTarget; int m_nTag; };
CCNode子类层级分析
CCAction是整个动作体系的基类,在CCNode上使用runAction即可执行,不仅可以完成一个独立的动作,也可以定义动作序列、组合动作、反向动作等。这张图清晰的说明了整个CCAction的层级体系。主要分为三大类:CCFiniteTimeAction(有限次动作执行类)、CCSpeed(节点执行速度类)、CCFollow(节点跟随另一个节点移动)。
而CCFiniteTimeAction分为CCActionInstant(瞬时动作)和CCActionInterval(延迟动作)。我们看到的动作一般都是后者。
下面介绍一些常用的延时动作:
1)CCMoveTo / CCMoveBy 移动
2)CCRotateTo / CCRotateBy 旋转
3)CCSkewTo / CCSkewBy 扭曲
4)CCJumpTo / CCJumpBy 跳跃
5)CCBezierTo / CCBezierBy 贝塞尔曲线
6)CCBink 闪烁
7)CCScaleTo / CCScaleBy 缩放
8)CCFadeIn / CCFadeOut 淡入淡出
9)CCTintTo / CCTintBy 染色
所有动作都是通过create方法来完成创建。例如:
CCMoveTo *move = CCMoveTo::create(2.0f, cpp(50, 50));
细心的话会发现很多方法都会有To和By两种,他们的区别是To是指定坐标,By是相对坐标。
CCActionManager
之前分析CCNode的时候有提到过CCActionManager,它是一个管理所有动作的单例,工作原理十:当CCNode执行runAction时,该函数会把动作通过动作管理类的addAction函数将对象传递给CCActionManager的单例该实例再把动作添加到自己的动作序列中。
一般情况下十不需要使用这个类的,我们完全可以使用CCNode类中的stopAction、StopActionByTag和stopAllAction等函数来管理,但是有两种特殊情况需要使用CCActionManager类单例:
1)动作的执行者不是同一个节点;
2)需要暂停、重启活动时。
class CC_DLL CCActionManager : public CCObject { public: CCActionManager(void); ~CCActionManager(void); // 为指定目标添加动作 void addAction(CCAction *pAction, CCNode *pTarget, bool paused); // 删除所有动作 void removeAllActions(void); // 删除制定目标所有动作 void removeAllActionsFromTarget(CCObject *pTarget); // 删除指定动作 void removeAction(CCAction *pAction); //根据标签删除/获取指定动作 void removeActionByTag(unsigned int tag, CCObject *pTarget); CCAction* getActionByTag(unsigned int tag, CCObject *pTarget); // 获取目标的动作数 unsigned int numberOfRunningActionsInTarget(CCObject *pTarget); // 暂停目标动作 void pauseTarget(CCObject *pTarget); // 恢复目标动作 void resumeTarget(CCObject *pTarget); // 暂停所有运行中的动作 CCSet* pauseAllRunningActions(); // 恢复指定集合所有动作 void resumeTargets(CCSet *targetsToResume); ... }; // 以上是CCActionManager源码分析 // 使用示例如下 pNode->runAction(CCScaleBy::create(2, 2)); CCDirector * pDirector = CCDirector::shareDirector(); pDirector->getActionManager()->pauseTarget(pNode); pDirector->getActionManager()->resumeTarget(pNode);
注意:不要轻易使用动作管理类,除非是不同动作目标或者暂停重启动作。
CCRepeat和CCRepeatForever
CCRepeat和CCRepeatForever都是继承自CCActionInterval,可以实现动作的多次执行和重复执行。
// times是执行pAction的次数,而CCRepeat则是重复执行直到stop static CCRepeat * create(CCFiniteTimeAction *pAction, unsigned int times); static CCRepeatForever *create(CCActionInterval *pAction);
CCSequence和CCSpawn
CCSequence类可以实现按序列执行动作,让节点顺序执行这几个动作。CCSpawn类实现同时执行几个动作,最终动作的持续时间由时间最长的动作决定。
例如:
CCSequence::create(move, move_back, NULL);// 记得在动作序列的结尾加上NULL
CCReverseTime
CCReverseTime就是反向执行某个动作,支持针对动作序列的反动作序列。不是所有的类都支持反动作,XxxTo通常不支持,XxxBy通常支持。
我们一般在做某个一个Action的时候,我们需要返回会用到该sprite的reverse,但是又时候,我需要这种行为再reverse的时候,我就可以利用CCReverseTime达到这种效果,例子代码如下:
CCSprite *spriteTint = CCSprite::create("blocks.png"); spriteTint->setPosition(ccp(size.width / 2.0f, size.height / 2.0f)); this->addChild(spriteTint, 1); CCActionInterval *forwardBy = CCTintBy::create(4, 255, 0, 0); CCActionInterval *back = forwardBy->reverse(); CCReverseTime *reverseTime = CCReverseTime::create(back); //在这里也就是倒序播放它的Action了 CCAction *action = CCSequence::create(forwardBy, back, NULL); spriteTint->runAction(action);
CCSpeed和CCEaseAction
基本动作和组合动作实现了针对CCNode的各种属性改变,但这样改变的速度是不变的,通过CCEaseAction和CCSpeed类可以很方便的修改CCNode执行的速度。
CCSpeed也是一个包装器,可以改变内部动作执行时间。
CCSpeed *speed = CCSpeed::create(CCMoveBy::create(3, cpp(350, 0)), 2.0f);CCEaseAction也是包装器,但是它一般用来让动作执行起来更加自然:
1)EaseIn // 由慢至快
2)EaseOut // 由快至慢
3)EaseInOut // 由慢至快,再由快至慢
4)EaseSineIn // 由慢至快
5)EaseSineOut // 由快至慢
6)EaseSineInOut // 由慢至快,再由快至慢
7)EaseExponentialIn // 由慢至极快
8)EaseExponentialOut // 由极快至慢
9)EaseExponentialInOut // 由慢至极快,再由极快至慢
具体的差异可以通过调试查看。
CCFollow
CCFollow可以让一个节点跟随另一个节点作位移。
static CCFollow *create(CCNode *pFollowNode, const CCRect &rect = CCRectZero);通过该方法来创建一个CCFollow跟随动作,可以设置一个跟随范围,离开范围就不再跟随。
CCFollow经常用来设置Layer跟随sprite,可以实现类似摄像机的跟拍效果,TestCpp中也有类似的例子。
void ActionFollow::onEnter() { ActionsDemo::onEnter(); centerSprites(1); CCSize s = CCDirector::sharedDirector()->getWinSize(); m_grossini->setPosition(ccp(-200, s.height / 2)); CCActionInterval* move = CCMoveBy::create(2, ccp(s.width * 3, 0)); CCActionInterval* move_back = move->reverse(); CCSequence* seq = CCSequence::create(move, move_back, NULL); CCAction* rep = CCRepeatForever::create(seq); m_grossini->runAction(rep); this->runAction(CCFollow::create(m_grossini, CCRectMake(0, 0, s.width * 2 - 100, s.height))); }
组合技
无论是CCRepeat、CCRepeatForever、CCSequence、CCSpawen、CCSpeed、CCEaseAction,都是包容器,包含一个或多个动作,组成一个特定的动作,如下,我们将模拟一个心脏跳动的动画。CCSprite* pSprite = CCSprite::create("Heart.png"); this->addChild(pSprite, 0); auto *scale = CCScaleBy::create(1.0, 1.5); auto *scaleBack = scale->reverse(); auto *scaleForever = CCRepeatForever::create(CCSequence::create(scale, scaleBack, NULL)); pSprite->runAction(scaleForever);
Cocos2d-x学习笔记(六)CCAction分析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。