Coco2dx-Action Principle 2 Action Classification
The previous article is about the workflow of Action and the execution principle of ActionManager. This article describes the classification and specific design of Action.
Category of Action types:
I. Limited time action: FiniteTimeAction
Including: instant action (CCActionInstance) and duration action (CCActionInterval)
1. instant action: There are several real-time actions that only change the position, visible, and other attributes of a node, such as CCPlace and CCShow, these are the complex actions that can be easily combined with other actions after they are encapsulated into actions.
There are also CCCallFunc and CCRemoveSelf. The former is generally used for Action callback, and the latter is generally used to remove the target node at the end of the execution action combination.
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. Duration action: Generally, the most commonly used duration actions in the project, including the familiar CCMoveTo, CCMoveBy... according to the length of time, the average number of n segments is executed at each frame.
Reverse Action (reverse): Not all actions have a reverse action. Generally, a reverse action exists only when the property of XXBy is set to a relative value, while a XXXTo action generally does not.
MoveBy* MoveBy::reverse() const{ return MoveBy::create(_duration, Vec2( -_positionDelta.x, -_positionDelta.y));}
Why does the XXXTo class action have no reverse action:
Because if the XXXTo class action is to create a inverse action, the initial attribute of the target Node needs to be obtained, and the initial attribute is obtained at Node: runAction.
But the action is not associated with the Node when it is created. Therefore, you cannot obtain the inverse action.
Get the first-level attributes:
void MoveTo::startWithTarget(Node *target){ MoveBy::startWithTarget(target); _positionDelta = _endPosition - target->getPosition();}
// This function is called in addAction of ActionManager. The Node attribute is obtained only when runAction is used.
Categories of duration actions:
Location change: Move, Jump
Attribute change action: Scale, Rotate, Fade, Tint
Visual effects: Blink, Animation
Control Action: DelayTime, Repeat, RepeatForever
Ii. Variable Speed: Speed (Package A duration action to change the Speed of the action, which can be a negative number)
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: more flexible variable speed movement. The base class is ActionInterval, which also encapsulates a continuous action, but changes the constant speed to acceleration during update (calculated by formula)
void EaseIn::update(float time){ _inner->update(tweenfunc::easeIn(time, _rate));}
Iii. Follow action: Follow (you can simulate lens movement. For details, refer to the cocos Follow example)
4. compound action:CCDelayTime, CCRepeat, CCSequence, CCSpawn
The serial and parallel action groups CCSequence and CCSpawn are recursive by createWithTwoActions. Update is actually a recursive process.
Spawn* Spawn::create(const Vector
& 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
(prev); }while (0); return ret;}