I used to be an ActionScript developer. Last year I started working with Objective-C, and this year I got into cocos2d. I’ve had some insights during the learning process, so I’m looking back and sharing them, as a report and reference for more fellow developers who want to move from Flash development to cocos2d. Learning cocos2d has been a pleasant process, because switching from Starling feels incredibly convenient—like back when I moved from PureMVC to Robotlegs, that feeling of meeting too late.
This article records a short summary of what I learned about Action in cocos2d.
Actions in cocos2d are similar to motion tweens in Flash, but they’re more powerful.
In Flash, everything you can do with motion tweens, including position, rotation, scale, color, and opacity, can also be done with Actions in Cocos2D. But in Flash development, relying only on changes in position, rotation, scale, color, and opacity isn’t enough to make an interesting game—these are just animations. More comprehensive actions are what make various values change, and they come in two types: instantaneous changes and changes over time.
In Flash, I generally use GTween to control changes to various values. Here’s an example: say you’re making the resource amount display text in StarCraft. When you spend or gather some resources, the resource amount text doesn’t change directly; it ticks over time. So I usually create a custom TextField, implement a pair of getter and setter, and use GTween to change their values, adding easing. Many effects can be achieved this way. You can even ease through texture swaps according to certain rules.
OK, back to cocos2d. Actions in cocos2d can be used to make nodes perform **position, rotation, scale, color change, disappear** and many other actions. And because they are applied to all CCNode nodes, you can apply actions to sprites, labels, menus, and even scenes. This is a very flexible feature. As I said above, true actions come in two types: instantaneous changes and changes over time. In cocos2d, CCFiniteTimeAction is divided into CCActionInstant and CCActionInterval. Besides CCFiniteTimeAction, there are also infinite repeat actions, follow actions, and speed actions.
CCActionInterval Interval Actions
Interval actions have the effect of changing over time. They are the most widely used and have a large number of subclasses. Among their subclasses, CCMoveTo, CCMoveBy, CCScaleTo, CCScaleBy, CCFadeIn, CCFadeOut, etc. are all regular features like position, rotation, and fade in/out, just as their names suggest.
There are 2 special, commonly used types: 1. CCEase easing actions, implemented by many subclasses 2. CCSequence action sequences.
CCEase Easing Actions
At first, when I used actions to do animation tweening and wanted to add easing, in Flash I usually used GTween (same with TweenLite, TweenMax), passing in an easing function to tween something. But in cocos2d, easing itself is actually an interval action.
For example, in a match-3 game, when the player scores points from clearing gems, I need the score prompt text to scale from large to small to create an impact, and the more points added, the larger the scale change. I add a back ease-in-out effect to the large-to-small scaling animation:
-(void) curScoreChangeTo:(int)score from:(int)oscore
{
int delta = score - oscore;
CGFloat prepareScale = 1.0f;
if(delta>0)
{
//delta 是300~8100
prepareScale = delta / 300 + 1.0f;
if(prepareScale>10) prepareScale = 10;
}
[curScoreLabel stopAllActions];
[curScoreLabel setScale:prepareScale];
\[curScoreLabel setString:\[NSString stringWithFormat:@"%d",score\]\];
\[curScoreLabel runAction:\[CCEaseBackInOut actionWithAction:\[CCScaleTo actionWithDuration:0.5 scale:1.0f\]\]\];
}
The key to using easing is [curScoreLabel runAction:[CCEaseBackInOut actionWithAction:[CCScaleTo actionWithDuration:0.5 scale:1.0f]]];
CCSequence Action Sequences
CCSequence *actionB = [CCSequence actions:
[CCScaleTo actionWithDuration:0.4 scale:0.6],
[CCScaleTo actionWithDuration:0.4 scale:1.0],nil];
[gemB runAction:actionB];
This code snippet shows scaling to 60% within 0.4 seconds, then scaling to 100% in another 0.4 seconds.
CCActionInstant
Instant actions are used to flip, move, set visibility, etc., but they are most widely used for callbacks when an action sequence reaches a certain point.
CCScaleTo *scale = [CCScaleTo actionWithDuration:REMOVE_GEM_SCALE_DURATION scale:2.0];
CCFadeOut *fadeOut = [CCFadeOut actionWithDuration:REMOVE_GEM_DURATION];
[gem runAction:[CCSequence actions:
[CCEaseOut actionWithAction:scale rate:4],fadeOut,
[CCCallBlock actionWithBlock:^(void) {[self removeChild:gem cleanup:YES];}], nil]];
This code snippet shows easing + callback + action sequence. They execute in order: first an ease-out scale action, then fade out, then callback.
CCRepeatForever Infinite Repeat Action
It keeps executing an action forever. You should know that actions can be stacked multiple times and can also be executed in sequence; with repetition added, this can achieve many effects, and it’s usually used quite a lot.
CCFollow Follow Action
It makes a node follow another node.
CCSpeed
It can adjust the update frequency of an action; the effect looks like adding a coefficient to the running speed.