之前介绍CCNode的时候说过,动作是指在特定时间内完成移动、缩放、旋转等操作的行为,节点可以通过运行动作来实现动画效果,这里的动作就是指CCAction对象,它有很多的子类,每个子类都封装了不同的动作效果。

先来看看CCAction的继承结构图

这里我省略了瞬时动作(CCActionInstant)和间隔动作(CCActionInterval)的子类,因为它们又包含了非常多的子类,待会再介绍它们的子类。

CCAction和CCFiniteTimeAction都是抽象类,只定义了一些基本属性和方法,没有实际用途,我们需要使用它们的子类来初始化动作,然后运行到节点上。

间隔动作

间隔动作就是指需要经过一段时间才能完成的动作,所有的间隔动作都继承自CCActionInterval。比如CCRotateBy,可以在指定时间内旋转指定的角度

  1. // 1秒内顺时针旋转360°
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];
  3. [sprite runAction:rotate];

间隔动作的继承结构图:(只列出部分常用的)

由于CCActionInterval的子类太多了,这里就不一一介绍了,可以查阅下API文档

下面列举一下常见的CCActionInterval的子类:

1.CCBlink

闪烁效果

  1. // 5秒内闪烁20次
  2. CCBlink *blink = [CCBlink actionWithDuration:5 blinks:20];
  3. [sprite runAction:blink];

2.CCMoveBy和CCMoveTo

CCMoveBy是移动一段固定的距离,CCMoveTo是移动到指定的位置

  1. // 在1秒内,向右移动100单位,同时向上移动80单位
  2. CCMoveBy *moveBy = [CCMoveBy actionWithDuration:1 position:CGPointMake(100, 80)];
  1. // 在1秒内,从节点的当前位置移动到(100, 80)这个位置
  2. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:1 position:CGPointMake(100, 80)];

3.CCRotateBy和CCRotateTo

CCRotateBy是在当前旋转角度的基础上再旋转固定的角度,CCRotateTo是从当前旋转角度旋转到指定的角度

假设精灵在初始化的时候已经顺时针旋转了45°

  1. sprite.rotation = 45;

如果使用了CCRotateBy

  1. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:90];
  2. [sprite runAction:rotateBy];
  3. // 在1秒内,再顺时针旋转90°,那么sprite的最终旋转角度是45° + 90° = 135°

如果使用了CCRotateTo

  1. CCRotateTo *rotateTo = [CCRotateTo actionWithDuration:1 angle:90];
  2. [sprite runAction:rotateTo];
  3. // 在1秒内,顺时针旋转到90°,sprite的最终旋转角度就是90°

4.CCScaleBy和CCScaleTo

CCScaleBy是在当前缩放比例的基础上再缩放固定的比例,CCScaleTo是从当前缩放比例缩放到指定的比例

假设精灵在初始化的时候的缩放比例为0.8

  1. sprite.scale = 0.8;

如果使用了CCScaleBy

  1. CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:0.5];
  2. [sprite runAction:scaleBy];
  3. // 在1秒内,宽度和高度再缩小50%,那么sprite最终缩放比例是0.8 * 0.5 = 0.4

如果使用了CCScaleTo

  1. CCScaleTo *scaleTo = [CCScaleTo actionWithDuration:1 scale:0.5];
  2. [sprite runAction:scaleTo];
  3. // 在1秒内,宽度和高度缩小为0.5倍,那么sprite最终缩放比例是就0.5

5.CCFadeIn和CCFadeOut和CCFadeTo

CCFadeIn是淡入,即由暗转亮,从没有到有;CCFadeOut是淡出,即由亮转暗,从有到没有;CCFadeTo用来修改节点的不透明度

  1. // 在2秒内,从没有到有
  2. CCFadeIn *fadeIn = [CCFadeIn actionWithDuration:2];
  3. // 在2s内,从有到没有
  4. CCFadeOut *fadeOut = [CCFadeOut actionWithDuration:2];
  5. // 在2s内,不透明度变为120,即变为半透明 (不透明度取值范围是0-255)
  6. CCFadeTo *fadeTo = [CCFadeTo actionWithDuration:2 opacity:120];

6.CCRepeat

重复执行某个动作,可以指定重复的次数

  1. // 1秒中顺时针旋转360°
  2. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];
  3. // 重复执行2次旋转动画
  4. CCRepeat *repeat = [CCRepeat actionWithAction:rotateBy times:2];
  5. [sprite runAction:repeat];

7.CCAnimate

按顺序地播放图片,可以实现帧动画。

例如有下面10张图片:(玩过街机的同学应该很熟悉,赵云的大鹏展翅)

不难发现,如果从1.png 到 10.png按顺序显示图片的话会形成一个动画

下面用CCAnimate实现动画效果

  1. // 用来存放所有的帧
  2. NSMutableArray *frames = [NSMutableArray array];
  3. // 加载所有的图片
  4. for (int i = 1; i<= 10; i++) {
  5. // 文件名
  6. NSString *name = [NSString stringWithFormat:@"zy.bundle/%i.png", i];
  7. // 根据图片名加载纹理,一个图片对应一个纹理对象
  8. CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:name];
  9. // 根据纹理初始化一个帧
  10. CGRect retct = CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height);
  11. CCSpriteFrame *frame = [[[CCSpriteFrame alloc] initWithTexture:texture rect:retct] autorelease];
  12. // 添加帧到数组中
  13. [frames addObject:frame];
  14. }
  15. // 根据帧数组初始化CCAnimation,每隔0.1秒播放下一张图片
  16. CCAnimation *animation = [CCAnimation animationWithFrames:frames delay:0.1];
  17. // 根据CCAnimation对象初始化动作
  18. CCAnimate *animate = [CCAnimate actionWithAnimation:animation];
  19. [sprite runAction:animate];

动画效果如下:

这里是将10帧分为10张不同的png图片。为了性能着想,其实最好将10帧打包成一个图片,到时从这张图片上面切割每一帧,这种图片我们可以称为"纹理相册",可以用TexturePacker制作纹理相册

8.CCSequence

一般情况下,如果给节点同时添加几个动作时,它们会同时运行。比如下面的代码效果是一边旋转一边缩放

  1. CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];
  2. CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:2];
  3. [sprite runAction:rotateBy];
  4. [sprite runAction:scaleBy];

但是有时候我们想让动作一个接着一个运行,那么就要用到CCSequence
下面演示的效果是,让精灵先变为红色,再从红色变为绿色,再从绿色变为蓝色

  1. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];
  2. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];
  3. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];
  4. // CCTintTo也是CCActionInterval的子类,可以用于更改精灵的颜色。
  5. CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];
  6. [sprite runAction:sequence];

CCSequence会按顺序执行参数中传入的所有动作

9.CCActionEase

当对节点使用CCMoveTo动作时,它会匀速移动到目的地,如果使用CCActionEase就可以使节点由慢到快或者由快到慢地移向目的地。因此CCActionEase是用来改变动作的运行时速度的。

CCActionEase是个非常强大的类,子类非常多,这里只说明其中的几个:

CCEaseIn:由慢到快

CCEaseOut:由快到慢

CCEaseInOut:先由慢到快,再由快到慢

举个代码例子:

  1. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:4 position:ccp(300, 200)];
  2. CCEaseInOut *easeInOut = [CCEaseInOut actionWithAction:moveTo rate:5];
  3. [sprite runAction:easeInOut];

你会看到精灵先由慢到快,再由快到慢。rate参数决定了速率变化的明显程度,当它大于1时才有效

10.CCGridAction

使用CCGridAction的具体子类可以实现三维效果,例如翻页效果(CCPageTurn3D)、波浪效果(CCWaves)、流体效果(CCLiquid)。虽然能实现很好看的3D效果,但是它有很大的缺点,如果不启用深度缓冲,3D效果会有些失真,如果启用了深度缓冲,会特别耗内存。

如果想开启深度缓冲的话,就要修改EAGLView的初始化参数depthFormat:

  1. EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
  2. pixelFormat:kEAGLColorFormatRGB565
  3. depthFormat:GL_DEPTH_COMPONENT24_OES];

可以改为GL_DEPTH_COMPONENT16_OES(16位深度缓冲)或者GL_DEPTH_COMPONENT24_OES(24位深度缓冲),16位深度缓冲占用的内存较少,但是仍然会有些失真

瞬时动作

瞬时动作(CCActionInstant)是指能够瞬间完成的动作,可用于改变节点位置、翻转节点形成镜像、设置节点的可视性等。

下面大致看下瞬时动作的继承结构图:

看完这个图,你可能觉得CCActionInstant好像没有一点使用价值,因为它的好多动作都可以通过修改节点属性来完成。比如可以通过设置节点的visible属性来代替使用CCShow\CCHide\CCToggleVisibility、可以通过修改节点的position属性来代替使用CCPlace。其实当它们与CCSequence结合使用时才有价值。比如,我们想先让节点运行一个CCMoveTo移动到某个位置,移动完毕后再隐藏节点,这时候我们就可以将CCMoveTo、CCHide两个动作按顺序放进CCSequence中达到想要的效果。

  1. // 移动到(300, 200)
  2. CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2 position:ccp(300, 200)];
  3. // 隐藏节点
  4. CCHide *hide = [CCHide action];
  5. CCSequence *sequence = [CCSequence actions:moveTo, hide, nil];
  6. [sprite runAction:sequence];

有时候,在一个动作序列(CCSequence)里面,我们需要在一个动作运行完毕后,调用某个方法执行一些操作,然后再执行下一个动作。那我们就可以结合CCCallFunc和CCSequence完成这个功能。

比如,我们让精灵先变为红色,再从红色变为绿色,再从绿色变为蓝色,而且在每次变换颜色后都调用某个方法执行一些操作:

  1. // 变为红色
  2. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:2 red:255 green:0 blue:0];
  3. // 变为红色后调用self的turnRed方法
  4. CCCallFunc *fn1 = [CCCallFunc actionWithTarget:self selector:@selector(turnRed)];
  5. // 变为绿色
  6. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:2 red:0 green:255 blue:0];
  7. // 变为绿色后调用self的turnGreen:方法,参数是运行当前动作的节点
  8. CCCallFuncN *fn2 = [CCCallFuncN actionWithTarget:self selector:@selector(turnGreen:)];
  9. // 变为蓝色
  10. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:2 red:0 green:0 blue:255];
  11. // 变为蓝色后调用self的turnBlue:data:方法,第一个参数是运行当前动作的节点,第二个参数是data的值
  12. CCCallFuncND *fn3 = [CCCallFuncND actionWithTarget:self selector:@selector(turnBlue:data:) data:@"blue"];
  13. // 最后调用turnDone:方法,传递了一个@"done"字符串作为参数
  14. CCCallFuncO *fn4 = [CCCallFuncO actionWithTarget:self selector:@selector(turnDone:) object:@"done"];
  15. CCSequence *sequence = [CCSequence actions:tintTo1, fn1, tintTo2, fn2, tintTo3, fn3, fn4, nil];
  16. [sprite runAction:sequence];

下面是回调方法的实现:

  1. - (void)turnRed {
  2. NSLog(@"变为红色");
  3. }
  4. // node是运行当前动作的节点
  5. - (void)turnGreen:(id)node {
  6. NSLog(@"变为绿色:%@", node);
  7. }
  8. // node是运行当前动作的节点
  9. - (void)turnBlue:(id)node data:(void *)data {
  10. NSLog(@"变为蓝色,%@,%@", node, data);
  11. }
  12. - (void)turnDone:(id)param {
  13. NSLog(@"变换完毕:%@", param);
  14. }

你会发现,精灵变为红色后就会调用turnRed方法,变为绿色后会调用turnGreen:方法,变为蓝色后会先调用turnBlue:data:方法,最后调用turnDone:方法

最后做一个总结:

下面这几个类都会在运行动作时调用一个方法

CCCallFunc :调用方法时不传递参数

CCCallFuncN :调用方法时,可以传递1个参数,参数值是运行当前动作的节点

CCCallFuncND :调用方法时,可以传递2个参数,第1个参数是运行当前动作的节点,第2个参数是actionWithTarget:selector:data:方法中的data值

CCCallFuncO :调用方法时,可以传递1个参数,参数值是actionWithTarget:selector:object:方法中的object值

CCRepeatForever

CCRepeatForever直接继承自CCAction,可以不停地运行某个间隔动作(CCActionInterval)。

如果你想让精灵不停地旋转,可以这样写:

  1. // 1秒内顺时针旋转360°
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];
  3. // 使用CCRepeatForever重复CCRotateBy动作
  4. CCRepeatForever *repeat = [CCRepeatForever actionWithAction:rotate];
  5. [sprite runAction:repeat];

也能够利用CCRepeatForever重复一个动作序列(CCSequence)

  1. // 变为红色
  2. CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];
  3. // 变为绿色
  4. CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];
  5. // 变为蓝色
  6. CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];
  7. CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];
  8. CCRepeatForever *repeat = [CCRepeatForever actionWithAction:sequence];
  9. [sprite runAction:repeat];

你会发现精灵的颜色状态是:红 -> 绿 -> 蓝 -> 红 -> 绿 -> 蓝 -> 红 ...,一直在红绿蓝3种颜色之间按顺序切换

CCSpeed

CCSpeed也是直接继承自CCAction,可以影响间隔动作(继承自CCActionInterval的动作)的运行速度。

  1. // 1秒内顺时针旋转360°
  2. CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];
  3. // 速度变为原来的一半
  4. CCSpeed *speed = [CCSpeed actionWithAction:rotate speed:0.5];
  5. [sprite runAction:speed];

本来1秒就完成旋转的,设置speed为0.5后,就需要2秒才能完成旋转

CCAction的更多相关文章

  1. 九、CCAction

    之前介绍CCNode的时候说过,动作是指在特定时间内完成移动.缩放.旋转等操作的行为,节点可以通过运行动作来实现动画效果,这里的动作就是指CCAction对象,它有很多的子类,每个子类都封装了不同的动 ...

  2. cocos2d-x 详解之 CCAction(动作)

    关于动作部分,总的来说使用起来比较简单,创建一个动作,然后让可渲染节点如精灵去执行这个动作即可.cocos2dx提供了很多类型的动作,使用起来也很方便.本节重点介绍动作CCAction的子类之一时间动 ...

  3. cocos2d-x CCAction(转载)

    接触开发2d后,越来越多的用到动作的内容,看到一篇关于动作比较完整的文章,最主要的是动作的类图,从类图可以更加的理解各个类之间的继承的关系,以及使用更容易的去应用 . 文章有一些方法已经被修改了,现在 ...

  4. cocos2D(九)---- CCAction

    之前介绍CCNode的时候说过,动作是指在特定时间内完毕移动.缩放.旋转等操作的行为,节点能够通过执行动作来实现动画效果,这里的动作就是指CCAction对象,它有非常多的子类,每一个子类都封装了不同 ...

  5. cocos2dx进阶学习之CCAction

    CCAction在cocos2dx中,抽象了节点的动作.它由CCObject派生,因此它不是渲染节点. 它经常的用法是,创建一个action,然后让某个CCNode对象(一般是精灵),去执行它. 在马 ...

  6. cocos2d-x学习记录2——CCAction动作

    CCAction能够使CCNode运动起来,能够呈现出多种多样的动作.这些动作能够改变其运动方向.形状.大小.旋转等. 同时,还可利用CCCallFunc.CCCallFuncN.CCCallFunc ...

  7. CCAction、CCFiniteTimeAction、CCSpeed、CCFollow

    /**************************************************************************** Copyright (c) 2010-201 ...

  8. 【Cocos2d-X开发学习笔记】第12期:动作类CCAction的详细讲解

    一般对于游戏中的精灵而言,它们不仅仅是存在于场景中,而且是动态展现的,例如,精灵移动的动态效果.动 画效果.跳动效果.闪烁和旋转动态效果等.每一种效果都可以看成是精灵的一个动作. 一.动作类(CCAc ...

  9. cocos2d-X学习之主要类介绍:动作:CCAction

    引用自:http://www.cnblogs.com/lhming/archive/2012/07/01/2572238.html 类继承图: 主要函数: virtual CCObject *  co ...

随机推荐

  1. ORM框架是什么

    ORM框架是什么 对象关系映射,目前数据库是关系型数据库  ORM 主要是把数据库中的关系数据映射称为程序中的对象 目前集中常见的ORM框架1  Nhibernate原因:用的比较多,资料也比较好找. ...

  2. 25.在从1到n的正数中1出现的次数[NumberOf1Between1_N]

    [题目] 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次. [分析] 这是一道广为流传的goo ...

  3. js 在myeclipse中报错

    转myeclipse中的js文件报错   整理一下,希望帮到 遇到此问题的哥们.姐们. 方法一:myeclipse9 很特殊 和 myeclipse10 不一样,所以myeclipse9 不能使用该方 ...

  4. UML从需求到实现---类图(2)

    上节写到了UML中的类图:UML从需求到实现---类图(1) 写完以后总觉得写的不够详细.里面很多细节没有说到.一篇文章就把强大的面向对象的类说完.当然是不可能的.这次我再补充一些关于UML中类图和类 ...

  5. 一个功能完备的.NET开源OpenID Connect/OAuth 2.0框架——IdentityServer3

    今天推荐的是我一直以来都在关注的一个开源的OpenID Connect/OAuth 2.0服务框架--IdentityServer3.其支持完整的OpenID Connect/OAuth 2.0标准, ...

  6. android 广播

    关于广播以前感觉是一知半解的,这次看到同事整理的文档,顺带跟着再参考几篇博文也学习整理了下,先上个整理的图 代码模板 发送广播 public static final String RECEIVE_A ...

  7. UVALive 6885 Flowery Trails 最短路枚举

    题目连接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129723 题意: 给你一个n点m图的边 1到n有多条最短路 ...

  8. 【codevs2822】爱在心中 tarjan 缩点+理解

    [codevs2822]爱在心中 2014年1月26日5580 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸, ...

  9. AppInventor学习笔记(五)——瓢虫快跑应用学习

    一.瓢虫引入 1:加入控件: 先引入方框中含有的控件,里面有两个画布,一个图像精灵,一个重力感应,一个时钟(设为10Ms).顺手改名.设置图像精灵的移动speed为10,并且引入瓢虫的图像 2.加入逻 ...

  10. CDH中flume是已经启动着了…

    文章来自:http://www.cnblogs.com/hark0623/p/4174646.html   转发请注明 在CDH中用了几天flume后才发现,原来CDH中的flume默认是启动的……… ...