动作(Action)原理二 动作分类详解

上篇文章是关于Action的工作流程和ActionManager的执行原理,本文说说Action的分类和具体的设计

动作类型的分类:

一、限时动作:FiniteTimeAction包括:即时动作(CCActionInstance)和持续时间动作(CCActionInterval)1、即时动作:即时动作有几个其实是只改变的node的position,visible等属性而已,例如CCPlace,CCShow等,这些主要是把他们包装成动作后可以方便的与其他动作类组合为复杂动作其次还有CCCallFunc和CCRemoveSelf,前者一般用于动作回调,后者一般用于在执行动作组合的最后移除目标节点CallFunc:void CallFunc::execute() {if (_callFunc) {(_selectorTarget->*_callFunc)();} else if( _function ){_function();}}CallFuncN:void CallFuncN::execute() {if (_callFuncN) {(_selectorTarget->*_callFuncN)(_target);}else if (_functionN) {_functionN(_target);}}CCCallFuncND:void __CCCallFuncND::execute(){if (_callFuncND){(_selectorTarget->*_callFuncND)(_target, _data);}}CCCallFuncO:void __CCCallFuncO::execute(){if (_callFuncO) {(_selectorTarget->*_callFuncO)(_object);}}RemoveSelf:void RemoveSelf::update(float time) {CC_UNUSED_PARAM(time);_target->removeFromParentAndCleanup(_isNeedCleanUp);}2、持续时间动作:一般项目中用的最多的是持续时间动作,包括熟悉的CCMoveTo,CCMoveBy…根据时间的长度,平均分为n段在每帧执行逆动作(reverse):并非所有动作都有逆动作,一般XXBy这种设置属性为相对值的动作才存在逆动作,而XXXTo的动作一般没有逆动作MoveBy* MoveBy::reverse() const{return MoveBy::create(_duration, Vec2( -_positionDelta.x, -_positionDelta.y));}为什么XXXTo类的动作不会有reverse动作:因为如果XXXTo类的动作在如果要创建逆动作的时候,,需要获取目标节点的初始属性,而初始属性的获取是在Node:runAction的时候才会获取的,但是动作在创建的时候,并没有关联到Node上,所以不可以获取逆动作。获取初识属性:void MoveTo::startWithTarget(Node *target){MoveBy::startWithTarget(target);_positionDelta = _endPosition – target->getPosition();}//该函数在ActionManager中的addAction中调用,当runAction的时候才获取节点属性持续时间动作的分类:位置变化动作:Move,Jump,Bezier属性变化动作:Scale,Rotate,Fade,Tint视觉特效动作:Blink,Animation控制动作:DelayTime,Repeat,RepeatForever二、变速动作:Speed(包装一个持续时间的动作,改变该动作的速度,可以为负数)Speed* Speed::create(ActionInterval* action, float speed){Speed *ret = new (std::nothrow) Speed();if (ret && ret->initWithAction(action, speed)){ret->autorelease();return ret;}CC_SAFE_DELETE(ret);return nullptr;}void Speed::step(float dt){_innerAction->step(dt * _speed);}CCActionEase:更加灵活的变速运动,基类是ActionInterval,同样包装了一个持续性的动作,只是在update的时候,将匀速变为加速(通过公式计算)void EaseIn::update(float time){_inner->update(tweenfunc::easeIn(time, _rate));}

三、跟随动作:Follow(可以模拟镜头移动,具体可参考cocos的Follow的例子)\四、复合动作:CCDelayTime,CCRepeat,CCSequence,CCSpawn其中串行和并行的动作组CCSequence和CCSpawn是靠createWithTwoActions递归而成的。update的时候其实也是一个递归的过程Spawn* Spawn::create(const Vector<FiniteTimeAction*>& arrayOfActions){Spawn* ret = nullptr;do{auto count = arrayOfActions.size();CC_BREAK_IF(count == 0);auto prev = arrayOfActions.at(0);if (count > 1){for (int i = 1; i < arrayOfActions.size(); ++i){prev = createWithTwoActions(prev, arrayOfActions.at(i));}}else{// If only one action is added to Spawn, make up a Spawn by adding a simplest finite time action.prev = createWithTwoActions(prev, ExtraAction::create());}ret = static_cast<Spawn*>(prev);}while (0);return ret;}

如果寒暄只是打个招呼就了事的话,那与猴子的呼叫声有什么不同呢?事实上,

动作(Action)原理二 动作分类详解

相关文章:

你感兴趣的文章:

标签云: