九、CCAction
来源:互联网 发布:定焦镜头拍淘宝哪个好 编辑:程序博客网 时间:2024/06/12 01:52
之前介绍CCNode的时候说过,动作是指在特定时间内完成移动、缩放、旋转等操作的行为,节点可以通过运行动作来实现动画效果,这里的动作就是指CCAction对象,它有很多的子类,每个子类都封装了不同的动作效果。
先来看看CCAction的继承结构图
这里我省略了瞬时动作(CCActionInstant)和间隔动作(CCActionInterval)的子类,因为它们又包含了非常多的子类,待会再介绍它们的子类。
CCAction和CCFiniteTimeAction都是抽象类,只定义了一些基本属性和方法,没有实际用途,我们需要使用它们的子类来初始化动作,然后运行到节点上。
间隔动作
间隔动作就是指需要经过一段时间才能完成的动作,所有的间隔动作都继承自CCActionInterval。比如CCRotateBy,可以在指定时间内旋转指定的角度// 1秒内顺时针旋转360°CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];[sprite runAction:rotate];
间隔动作的继承结构图:(只列出部分常用的)
由于CCActionInterval的子类太多了,这里就不一一介绍了,可以查阅下API文档
下面列举一下常见的CCActionInterval的子类:
1.CCBlink
闪烁效果
// 5秒内闪烁20次CCBlink *blink = [CCBlink actionWithDuration:5 blinks:20];[sprite runAction:blink];
2.CCMoveBy和CCMoveTo
CCMoveBy是移动一段固定的距离,CCMoveTo是移动到指定的位置
// 在1秒内,向右移动100单位,同时向上移动80单位CCMoveBy *moveBy = [CCMoveBy actionWithDuration:1 position:CGPointMake(100, 80)];
// 在1秒内,从节点的当前位置移动到(100, 80)这个位置CCMoveTo *moveTo = [CCMoveTo actionWithDuration:1 position:CGPointMake(100, 80)];
3.CCRotateBy和CCRotateTo
CCRotateBy是在当前旋转角度的基础上再旋转固定的角度,CCRotateTo是从当前旋转角度旋转到指定的角度
假设精灵在初始化的时候已经顺时针旋转了45°sprite.rotation = 45;
如果使用了CCRotateBy
CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:90];[sprite runAction:rotateBy];// 在1秒内,再顺时针旋转90°,那么sprite的最终旋转角度是45° + 90° = 135°
如果使用了CCRotateTo
CCRotateTo *rotateTo = [CCRotateTo actionWithDuration:1 angle:90];[sprite runAction:rotateTo];// 在1秒内,顺时针旋转到90°,sprite的最终旋转角度就是90°
4.CCScaleBy和CCScaleTo
CCScaleBy是在当前缩放比例的基础上再缩放固定的比例,CCScaleTo是从当前缩放比例缩放到指定的比例
假设精灵在初始化的时候的缩放比例为0.8
sprite.scale = 0.8;
如果使用了CCScaleBy
CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:0.5];[sprite runAction:scaleBy];// 在1秒内,宽度和高度再缩小50%,那么sprite最终缩放比例是0.8 * 0.5 = 0.4
如果使用了CCScaleTo
CCScaleTo *scaleTo = [CCScaleTo actionWithDuration:1 scale:0.5];[sprite runAction:scaleTo];// 在1秒内,宽度和高度缩小为0.5倍,那么sprite最终缩放比例是就0.5
5.CCFadeIn和CCFadeOut和CCFadeTo
CCFadeIn是淡入,即由暗转亮,从没有到有;CCFadeOut是淡出,即由亮转暗,从有到没有;CCFadeTo用来修改节点的不透明度
// 在2秒内,从没有到有CCFadeIn *fadeIn = [CCFadeIn actionWithDuration:2];// 在2s内,从有到没有CCFadeOut *fadeOut = [CCFadeOut actionWithDuration:2];// 在2s内,不透明度变为120,即变为半透明 (不透明度取值范围是0-255)CCFadeTo *fadeTo = [CCFadeTo actionWithDuration:2 opacity:120];
6.CCRepeat
重复执行某个动作,可以指定重复的次数
// 1秒中顺时针旋转360°CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];// 重复执行2次旋转动画CCRepeat *repeat = [CCRepeat actionWithAction:rotateBy times:2];[sprite runAction:repeat];
7.CCAnimate
按顺序地播放图片,可以实现帧动画。
例如有下面10张图片:(玩过街机的同学应该很熟悉,赵云的大鹏展翅)
不难发现,如果从1.png 到 10.png按顺序显示图片的话会形成一个动画
下面用CCAnimate实现动画效果
// 用来存放所有的帧NSMutableArray *frames = [NSMutableArray array];// 加载所有的图片for (int i = 1; i<= 10; i++) { // 文件名 NSString *name = [NSString stringWithFormat:@"zy.bundle/%i.png", i]; // 根据图片名加载纹理,一个图片对应一个纹理对象 CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:name]; // 根据纹理初始化一个帧 CGRect retct = CGRectMake(0, 0, texture.contentSize.width, texture.contentSize.height); CCSpriteFrame *frame = [[[CCSpriteFrame alloc] initWithTexture:texture rect:retct] autorelease]; // 添加帧到数组中 [frames addObject:frame];}// 根据帧数组初始化CCAnimation,每隔0.1秒播放下一张图片CCAnimation *animation = [CCAnimation animationWithFrames:frames delay:0.1];// 根据CCAnimation对象初始化动作CCAnimate *animate = [CCAnimate actionWithAnimation:animation];[sprite runAction:animate];动画效果如下:
这里是将10帧分为10张不同的png图片。为了性能着想,其实最好将10帧打包成一个图片,到时从这张图片上面切割每一帧,这种图片我们可以称为"纹理相册",可以用TexturePacker制作纹理相册
8.CCSequence
一般情况下,如果给节点同时添加几个动作时,它们会同时运行。比如下面的代码效果是一边旋转一边缩放
CCRotateBy *rotateBy = [CCRotateBy actionWithDuration:1 angle:360];CCScaleBy *scaleBy = [CCScaleBy actionWithDuration:1 scale:2];[sprite runAction:rotateBy];[sprite runAction:scaleBy];但是有时候我们想让动作一个接着一个运行,那么就要用到CCSequence
下面演示的效果是,让精灵先变为红色,再从红色变为绿色,再从绿色变为蓝色
CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];// CCTintTo也是CCActionInterval的子类,可以用于更改精灵的颜色。CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];[sprite runAction:sequence];CCSequence会按顺序执行参数中传入的所有动作
9.CCActionEase
当对节点使用CCMoveTo动作时,它会匀速移动到目的地,如果使用CCActionEase就可以使节点由慢到快或者由快到慢地移向目的地。因此CCActionEase是用来改变动作的运行时速度的。
CCActionEase是个非常强大的类,子类非常多,这里只说明其中的几个:
CCEaseIn:由慢到快
CCEaseOut:由快到慢
CCEaseInOut:先由慢到快,再由快到慢
举个代码例子:
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:4 position:ccp(300, 200)];CCEaseInOut *easeInOut = [CCEaseInOut actionWithAction:moveTo rate:5];[sprite runAction:easeInOut];你会看到精灵先由慢到快,再由快到慢。rate参数决定了速率变化的明显程度,当它大于1时才有效
10.CCGridAction
使用CCGridAction的具体子类可以实现三维效果,例如翻页效果(CCPageTurn3D)、波浪效果(CCWaves)、流体效果(CCLiquid)。虽然能实现很好看的3D效果,但是它有很大的缺点,如果不启用深度缓冲,3D效果会有些失真,如果启用了深度缓冲,会特别耗内存。
如果想开启深度缓冲的话,就要修改EAGLView的初始化参数depthFormat:
EAGLView *glView = [EAGLView viewWithFrame:[window bounds] pixelFormat:kEAGLColorFormatRGB565 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中达到想要的效果。
// 移动到(300, 200)CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2 position:ccp(300, 200)];// 隐藏节点CCHide *hide = [CCHide action];CCSequence *sequence = [CCSequence actions:moveTo, hide, nil];[sprite runAction:sequence];
有时候,在一个动作序列(CCSequence)里面,我们需要在一个动作运行完毕后,调用某个方法执行一些操作,然后再执行下一个动作。那我们就可以结合CCCallFunc和CCSequence完成这个功能。
比如,我们让精灵先变为红色,再从红色变为绿色,再从绿色变为蓝色,而且在每次变换颜色后都调用某个方法执行一些操作:
// 变为红色CCTintTo *tintTo1 = [CCTintTo actionWithDuration:2 red:255 green:0 blue:0];// 变为红色后调用self的turnRed方法CCCallFunc *fn1 = [CCCallFunc actionWithTarget:self selector:@selector(turnRed)];// 变为绿色CCTintTo *tintTo2 = [CCTintTo actionWithDuration:2 red:0 green:255 blue:0];// 变为绿色后调用self的turnGreen:方法,参数是运行当前动作的节点CCCallFuncN *fn2 = [CCCallFuncN actionWithTarget:self selector:@selector(turnGreen:)];// 变为蓝色CCTintTo *tintTo3 = [CCTintTo actionWithDuration:2 red:0 green:0 blue:255];// 变为蓝色后调用self的turnBlue:data:方法,第一个参数是运行当前动作的节点,第二个参数是data的值CCCallFuncND *fn3 = [CCCallFuncND actionWithTarget:self selector:@selector(turnBlue:data:) data:@"blue"];// 最后调用turnDone:方法,传递了一个@"done"字符串作为参数CCCallFuncO *fn4 = [CCCallFuncO actionWithTarget:self selector:@selector(turnDone:) object:@"done"];CCSequence *sequence = [CCSequence actions:tintTo1, fn1, tintTo2, fn2, tintTo3, fn3, fn4, nil];[sprite runAction:sequence];下面是回调方法的实现:
- (void)turnRed { NSLog(@"变为红色");}// node是运行当前动作的节点- (void)turnGreen:(id)node { NSLog(@"变为绿色:%@", node);}// node是运行当前动作的节点- (void)turnBlue:(id)node data:(void *)data { NSLog(@"变为蓝色,%@,%@", node, data);}- (void)turnDone:(id)param { NSLog(@"变换完毕:%@", param);}你会发现,精灵变为红色后就会调用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秒内顺时针旋转360°CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];// 使用CCRepeatForever重复CCRotateBy动作CCRepeatForever *repeat = [CCRepeatForever actionWithAction:rotate];[sprite runAction:repeat];也能够利用CCRepeatForever重复一个动作序列(CCSequence)
// 变为红色CCTintTo *tintTo1 = [CCTintTo actionWithDuration:1 red:255 green:0 blue:0];// 变为绿色CCTintTo *tintTo2 = [CCTintTo actionWithDuration:1 red:0 green:255 blue:0];// 变为蓝色CCTintTo *tintTo3 = [CCTintTo actionWithDuration:1 red:0 green:0 blue:255];CCSequence *sequence = [CCSequence actions:tintTo1, tintTo2, tintTo3, nil];CCRepeatForever *repeat = [CCRepeatForever actionWithAction:sequence];[sprite runAction:repeat];
你会发现精灵的颜色状态是:红 -> 绿 -> 蓝 -> 红 -> 绿 -> 蓝 -> 红 ...,一直在红绿蓝3种颜色之间按顺序切换
CCSpeed
CCSpeed也是直接继承自CCAction,可以影响间隔动作(继承自CCActionInterval的动作)的运行速度。
// 1秒内顺时针旋转360°CCRotateBy *rotate = [CCRotateBy actionWithDuration:1 angle:360];// 速度变为原来的一半CCSpeed *speed = [CCSpeed actionWithAction:rotate speed:0.5];[sprite runAction:speed];本来1秒就完成旋转的,设置speed为0.5后,就需要2秒才能完成旋转
- 九、CCAction
- 九、CCAction
- 九、CCAction
- 九、CCAction
- cocos2D(九)---- CCAction
- CCAction
- CCACTION
- CCAction
- CCAction
- 【玩转cocos2d-x之九】动作类CCAction
- 【玩转cocos2d-x之九】动作类CCAction
- CCAction详解
- 游戏-CCAction
- CCAction类
- ccaction/ccanimate
- CCAction动画
- (13) CCAction
- CCAction(CCAction CCFiniteTimeAction CCSpeed CCFollow)
- tesseract杂项
- Tomcat负载均衡原理详解及配置(Apache2.2.19+Tomcat7.0.12)
- hdu1070水题找感觉
- 王案资料1
- How To Design For Android Devices
- 九、CCAction
- 王年表
- Android的内存机制和常见泄漏情形
- 从今天看算法导论实现里面的一些伪代码
- linux异步IO浅析
- 方便复制
- uva10012 - How Big Is It?
- 集群基础学习之VCS常用命令
- 王案资料2