Actions are operations that nodes can run. Moving things around, changing colors, calling callback functions are some examples of actions. You can have your node to run the actions one after another sequentially or all at the same time in parallel. You can have them repeat themselves or run in reverse. Actions give us a powerful tool that if used right, can save you a lot of time and headache.
How Does It Work?
Actions do very different and diverse things on a Node:
- Some simple actions change the transformation of an object: MoveTo, MoveBy, RotateTo, ScaleTo, FlipX, etc…
- Some change the appearance of a Node, like Hide, Blink, TintTo, FadeIn, FadeOut, etc…
- There are other types of actions for other purposes that we will see in the later sections of this post
To run an action on your node, simply run:
node->runAction(action);
If you want to run a few actions on your node one after another, you make a Sequence action first and then run that instance on your node:
sequence = Sequence::create(action1, action2, action3, std::null_ptr); // Run action1, action2, action3 in sequence node->runAction(sequence);
To run two or more actions at the same time, you can either run it like this:
node->runAction(action1); node->runAction(action2); node->runAction(action3); // Run action1, action2, action3 in parallel
Or, you can use the Spawn action to run them at the same time:
spawn = Spawn::create(action1, action2, action3, std::nullptr); // Run action1, action2, action3 in parallel node->runAction(spawn);
They will have the same outcome, although there is a difference! The difference between running runAction() multiple times or Spawn action is that you can use the Spawn instance in a Sequence action as an action! Something like:
spawn = Spawn::create(action1, action2, action3, std::nullptr); // Run action1, action2, action3 in parallel sequence = Sequence::create(action4, spawn, action5, std::nullptr); // Run action4, spawn, action5 in sequence node->runAction(sequence);
If you want to repeat an action use Repeat or RepeatForever actions:
repeat = Repeat::create(action1, 4); // Repeat action1 4 times. node->runAction(repeat); repeatForever = RepeatForever::create(action2); // Repeat action2 forever. node->runAction(repeatForever);
To reverse an action, use Reverse action:
reverse = ReverseTime::create(action); // Reverse action node->runAction(reverse);
Here is a real example that moves a node from its current position to (100, 100) in a second:
auto myNode = MyNode::create(); // Create a node myNode->setPosition(0, 0); // Place it at (0,0) auto moveAction = MoveTo::create(100, 100, 1); // Create a MoveTo action to move the node to (100, 100) in one second myNode->runAction(moveAction); // Have the node run the action
We can put what we learned in action, by updating the example from our previous post.
Node Parenting Example, Using Actions:
We will use actions to re-create the example from previous blog “Node Parenting” by using actions instead of periodic methods.
- Nothing changes in the HelloWorldScene class. But, we will change the NodeBox and NodeTriangle classes.
- Remove update() and reverseDirection() methods from NodeBox and NodeTriangle classes in both the header and the cpp files.
- In init() method of NodeBox, replace:
// Repeats every frame scheduleUpdate(); // Reverse direction every 3 seconds schedule(SEL_SCHEDULE(&NodeBox::reverseDirection), 3.0); // Kill a child every 3 seconds, repeat 4 times and start with 3 seconds delay schedule(SEL_SCHEDULE(&NodeBox::killNextChild), 3.0, 4, 3);
with:
auto rotate = RotateBy::create(3.0, 90.0); auto rotateReverse = rotate->reverse(); auto rotateSequence = Sequence::create(rotate, rotateReverse, nullptr); auto rotateRepeat = RepeatForever::create(rotateSequence); auto scale = ScaleBy::create(3.0, 1.18); auto scaleReverse = scale->reverse(); auto scaleSequence = Sequence::create(scale, scaleReverse, nullptr); auto scaleRepeat = RepeatForever::create(scaleSequence); auto delay = DelayTime::create(3.0f); std::function<void()> test = std::bind(&NodeBox::killNextChild, this); auto func = CallFunc::create(test); auto funcSequence = Sequence::create(delay, func, nullptr); auto funcRepeat = Repeat::create(funcSequence, 4); runAction(scaleRepeat); runAction(rotateRepeat); runAction(funcRepeat);
This is quite self explanatory. I just converted the numbers per frame from previous code to numbers per second to create the actions.
- In init() method of NodeTriangle, this code:
m_scaleDelta = 0.01; // Scale value m_rotateDelta = 0.5; // Rotation angle value // Repeats every frame scheduleUpdate(); // Reverse direction every 3 seconds schedule(SEL_SCHEDULE(&NodeTriangle::reverseDirection), 3.0);
- Should be replace it with this:
auto rotate = RotateBy::create(3.0, -90.0); auto rotateReverse = rotate->reverse(); auto rotateSequence = Sequence::create(rotate, rotateReverse, nullptr); auto rotateRepeat = RepeatForever::create(rotateSequence); auto scale = ScaleBy::create(3.0, 1.8); auto scaleReverse = scale->reverse(); auto scaleSequence = Sequence::create(scale, scaleReverse, nullptr); auto scaleRepeat = RepeatForever::create(scaleSequence); runAction(scaleRepeat); runAction(rotateRepeat);
Now, if you run the code, you should get the same result as before, except that you have a simpler and cleaner code.
Actions List
There is a big list of actions to use. I tried to categorize them in a way that makes sense to me. There is a complete list here if you want to have a look yourself: Action List
Looks like some classes in the list are general base classes. I don’t expect these classes to be used on their own unless you want to inherit from them and make your own actions!
class Action // Base class for Action objects. class FiniteTimeAction // Base class actions that do have a finite time duration. class ActionInterval // An interval action is an action that takes place within a certain period of time. class ActionInstant // Instant actions are immediate actions. class ActionManager // A singleton class that manages all the actions. class PointArray // An Array that contain control points. Used by CardinalSpline and CatmullRom actions. class ActionEase // Base class for ease actions class EaseRateAction // Base class for Easing actions with rate parameters. class GridAction // Base class for Grid action. class Grid3DAction // Base class for Grid3D action. class TiledGrid3DAction // Base class for TiledGrid3D actions.
Simple Actions:
There are some actions that are simple and they change basic properties of a node like translation, rotation, scale, opacity and color. We have already seen some of them in our example.
How to use:
auto node = Node::create(); auto action = RotateBy::create(3.0, -90.0); node->runAction(action);
List of Simple Transform Actions:
class Follow // Makes a node follows another node class CardinalSplineTo // Moves a node to a point on screen on a Spline curve path class CardinalSplineBy // Moves a node by a distance on a Spline curve path class CatmullRomTo // Moves a node to a point on screen on a Catmull Rom curve path class CatmullRomBy // Moves a node by a distance on a Catmull Rom curve path class FlipX // Flips a node on X axis class FlipY // Flips a node on Y axis class Place // Places a node on the screen class RotateTo // Rotates a node to a degree class RotateBy // Rotates a node by a degree class MoveTo // Moves a node to a new coordinate class MoveBy // Moves a node by a distance class SkewTo // Skews a node to a value class SkewBy // Skews a node by a value class JumpTo // Jumps a node to to a new coordinate class JumpBy // Jumps a node by a distance class BezierTo // Moves a node to a point on screen on a Bezier curve path class BezierBy // Moves a node by a distance on a Bezier curve path class ScaleTo // Scales a node to a new value class ScaleBy // Scales a node by a new value
List of Simple Opacity/Color Actions:
class Show // Shows a hidden node class Hide // Hides a node class ToggleVisibility // Toggles visibility of a node class Blink // Makes a node blink class FadeTo // Fades a node to a value class FadeIn // Fades in a node (show) class FadeOut // Fades our a node (hide) class TintTo // Tints a node to a color class TintBy // Tints a node by a certain value
Easing Actions:
These Ease In and Ease Out actions will smooth the animations of the other actions. They are useful to smooth out the menu and other interface animations. They can also be used to create simple fake physics animations.
How to use:
auto node = Node::create(); // Create a node auto move = MoveBy::create(2, Vec2(200, dirs->getVisibleSize().height - newSprite2->getContentSize().height)); // create a MoveBy action. auto move_ease_in = EaseBounceIn::create(move->clone()); // Create a BounceIn easing action using the clone of the move action. node->runAction(move_ease_in); // Run the action
Notice that we cloned the move action to create a copy and preserve the original action properties.
List of the Ease In/Out Actions:
class EaseIn // EaseIn action with a rate. class EaseOut // EaseOut action with a rate. class EaseInOut // EaseInOut action with a rate. class ExponentialIn // Ease Exponential In action. class ExponentialOut // Ease Exponential Out action. class ExponentialInOut // Ease Exponential InOut action. class EaseSineIn // Ease Sine In action. class EaseSineOut // Ease Sine Out action. class EaseSineInOut // Ease Sine InOut action. class EaseElasticIn // Ease Elastic In action. class EaseElasticOut // Ease Elastic Out action. class EaseElasticInOUt // Ease Elastic InOut action. class EaseBounce // Ease Bounce Abstract Class! class EaseBounceIn // Ease Bounce In action. class EaseBounceOut // Ease Bounce Out action. class EaseBouceInOut // Ease Bounce InOut action. class EaseBackIn // Ease Back In action. class EaseBackOut // Ease Back Out action. class EaseBackInOut // Ease Back InOut action. class EaseBezierAction // Ease Bezier action. class EaseQuadraticActionIn // Ease Quadratic Action In action. class EaseQuadraticActionOut // Ease Quadratic Action Out action. class EaseQuadraticActionInOut // Ease Quadratic Action InOut action. class EaseQuarticActionIn // Ease Quartic Action In action. class EaseQuarticActionOut // Ease Quartic Action Out action. class EaseQuarticActionInOut // Ease Quartic Action InOut action. class EaseQuinticActionIn // Ease Quintic Action In action. class EaseQuinticActionOut // Ease Quintic Action Out action. class EaseQuinticActionInOut // Ease Quintic Action InOut action. class EaseCircleActionIn // Ease Circle Action In action. class EaseCircleActionOut // Ease Circle Action Out action. class EaseCircleActionInOut // Ease Circle Action InOut action. class EaseCubicActionIn // Ease Cubic Action In action. class EaseCubicActionOut // Ease Cubic Action Out action. class EaseCubicActionInOut // Ease Cubic Action InOut action.
Here is how each of the easing actions will affect the animation curve, according to the docs:
Grid Actions:
There are two types of actions: Grid actions and tiled grid actions.
According to the official document (Picture below), the difference is that the tiled grid is composed of individual tiles while the non-tiled grid is composed of vertex.
The grid has 2 dimensions as rows and columns but each vertex of a grid has 3 dimensions x, y, z. All of the grid actions work on a grid object that has a size. The bigger the grid size, the slower the effect will run on some slower machines.
How to use:
auto node = Node::create(); // Node can be anything that is inherited from the Node class (Node, Sprite, Layer, Scene, etc...) auto grid = NodeGrid::create(); // Define a NodeGrid object. auto action = SplitRows::create(10, 10); // Create an action from grid or tiled-grid list. grid->addChild(node); // Add grid to your node. grid->runAction(action); // Run the action.
List of Grid Actions:
// Grid Actions: class StopGrid // Stops the grid effect. class ReuseGrid // Reuse a grid. class SplitRows // Split Rows effect class SplitCols // Split Columns effect class Liquid // Liquid effect action class Waves // Wave effect action class Twirl // Twirl effect action class Waves3D // 3D Wave effect action class FlipX3D // 3D Flip X effect action class FlipY3D // 3D Flip Y effect action class Lens3D // 3D Lens effect action class Ripple3D // 3D Ripple effect action class Shaky3D // 3D Shaky effect action class PageTurn3D // 3D Page Turn effect action // Tiled Grid Actions: class ShakyTiles3D // 3D Shaky Tiles effect action. class ShatteredTiles3D // 3D Shattered Tiles effect action. class ShuffleTiles // Shuffle Tiles effect action. class FadeOutTRTiles // Fade Out TR Tiles effect action. class FadeOutBLTiles // Fade Out BL Tiles effect action. class FadeOutUpTiles // Fade Out Up Tiles effect action. class FadeOutDownTiles // Fade Out Down Tiles effect action. class TurnOffTiles // Turn Off Tiles effect action. class WavesTiles3D // Waves Tiles 3D effect action. class JumpTiles3D // Jump Tiles 3D effect action.
Here is a table of how the Grid actions will look:
Here is a table of how the Tiled Grid actions will look:
Time/Flow Actions:
We used some of these in our example earlier. There are pretty easy to use so I just list them as is.
class Sequence // Runs actions sequentially, one after another. class Repeat // Repeats an action a number of times. class RepeatForever // Repeats an action for ever. class Spawn // Runs actions in parallel, all at the same time. class DelayTime // Delays the action a certain amount of seconds. class ReverseTime // Executes an action in reverse order, from time=duration to time=0. class Speed // Changes the speed of an action, making it take longer (speed>1) or less (speed<1) time.
Callback Actions:
class CallFunc // Calls a 'callback'. class CallFuncN // Calls a 'callback' with the node as the first argument N means Node. class __CCCallFuncND // Calls a 'callback' with the node as the first argument and the 2nd argument is data ND means: Node and Data. class __CCCallFuncO // Calls a 'callback' with an object as the first argument. O means Object.
Camera Actions:
class ActionCamera // Base class for Camera actions. class OrbitCamera // Orbits the camera around the center of the screen using spherical coordinates.
Other Actions:
class Animate // Animates a sprite given the name of an <a class="el" title="A Animation object is used to perform animations on the Sprite objects. " href="https://cocos2d-x.org/reference/native-cpp/V3.2/d3/dc5/classcocos2d_1_1_animation.html" data-mce-href="https://cocos2d-x.org/reference/native-cpp/V3.2/d3/dc5/classcocos2d_1_1_animation.html">Animation.</a> class ActionTween // An action that lets you update any property of an object. class ActionTweenDelegate // - class ProgressTo // Progress to percentage. class ProgressFromTo // Progress from on percentage to another percentage. class RemoveSelf // Removes the node. class TargetedAction // Overrides the target of an action so that it always runs on the target specified at action creation rather than the one specified by runAction. class AccelDeccelAmplitude // Accelerate Decelerate Amplitude effect action. class AccelAmplitude // Accelerate Amplitude effect action. class DeccelAmplitude // Decelerate Amplitude effect action.
As this post has already become pretty long, I didn’t go through all the actions one by one. I think visiting the reference documents for Cocos2d-x should help a lot, now that we have seen a few of the different action types.
The Action Manager
The Action Manager gives you access to all the actions in your game application. If you decide to pause and resume the game, you need to use the Action Manager to access all your running actions.
This pseudo code below will show you how to use the Action Manager to pause your actions and then resume them again.
// You need a container in your class definition to hold the paused nodes to be able to resume them. cocos2d::Vector<Node*> pausedNodes; // You can pause the running actions and keep a list of them in your Vector container pausedNodes = cocos2d::Director::getInstance()->getActionManager()->pauseAllRunningActions(); // Later, you can resume the nodes that were previously paused if (pausedNodes.size()) { cocos2d::Director::getInstance()->getActionManager()->resumeTargets(pausedNodes); pausedNodes.clear(); }