Cocos2D研究院之CCAction详解(四)

2024-04-30 04:32

本文主要是介绍Cocos2D研究院之CCAction详解(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:Cocos2D研究院之CCAction详解(四)

上一章我们了解了CCNode的实现原理,这次我跟大家探讨一下行为类。

从代码的角度讲,行为其实就是改变实体的属性,如坐标、角度等,这些属性大部分都可以靠实体类自身封装的方法来设置,之所以要用行为单独封装它们,还是为了使操作更加简便。试想,当我们要让一个实体连续执行一段行为序列或者不断重复执行一个行为时,编码会变得相当复杂,如果这一过程还是在一定时间内逐渐完成的该怎么办,各种复杂的行为掺杂在一起同时执行,是不是想一想就头大呢?这就是行为类存在的最大意义,它会使编码过程变得异常简单,就像是策划在写脚本一样~

行为类的基类是CCAction,任何一种行为都是由它拓展衍变而来的。行为类可以分为四大类:有限次执行类、无限重复行为类、速度行为类和跟随移动类,其中前两者的使用频率最高;而有限次执行类又可以分为瞬时行为类和过程行为类。它们的继承关系如下图:

图中的CCAction是基类,比较抽象,在实际开发中不会直接用到,更多的是在参数传递中充当‘泛型’;CCFiniteTimeAction从字面就能看出来(finite = 有限的),是有限次执行类,它是最为普通的行为,就是按时间顺序做一系列事情,做完后行为结束;CCRepeatForever的名字更易懂了,无限重复行为类,就是说它可以让节点反复的做一件事,除非把行为或节点删除,否则永远不会停止;CCSpeed的作用是调整行为实例的执行速度,因此它依赖于其它的行为,单独的CCSpeed没有意义;CCFollow可以使节点跟随指定的另一个节点移动。

下面我就介绍一下这些类的工作原理:

CCAction声明了如下方法:

+(id) action

创建一个CCAction实例,其实就是封装了alloc、init和autorelease方法。

-(void) startWithTagert: (id)aTarget

将节点与行为对象相关联。

-(void) stop

取消节点与行为的关联,即停止行为。

-(void) isDone

检测行为是否执行完毕。

-(void) step

计算自身行为的执行状况,即任务完成了多少,并调用自身的update。

-(void) update

执行自身行为的主逻辑,是行为的核心算法。

-(void) pause

暂停行为(可恢复)。

-(void) unPause

从暂停中恢复。

-(BOOL) isRunning

检测行为是否在更新逻辑。

*需要注意的是,CCAction是抽象类,很多方法都是空的,它主要靠自己的子类去实现接口,因此不能直接用CAction的对象描述节点的行为。

CCFiniteTimeAction

CCFiniteTimeAction是所有有限次执行类(或者也可以叫顺序执行类吧)的基类,这种类在游戏中的应用是相当多的,因此尽管它也是个抽象类,但对于它的理解将直接影响到游戏开发的效率与质量。

-( CCFiniteTimeAction*) reverse

CCFiniteTimeAction只增加了一个接口,其作用是反向执行一个行为,比如一个行为对象的作用是将节点右移10个像素,那么当这个对象执行了reverse后,执行它的节点会向左移动10像素。但是CCFiniteTimeAction只是声明了该方法,实现还是交给了它的子类。

CCRepeatForever

CCRepeatForever的接口和CCFiniteTimeAction大致相同(除了初始化),只是实现方法不同。它们的区别是:CCFiniteTimeAction执行有限次,有结束的一刻,而CCRepeatForever永远不会自己停止,会无限的执行;CCFiniteTimeAction的子类有具体的行为含义,可以独立存在,而CCRepeatForever没有具体含义,它只表示会重复地执行,因此它必须依附于有具体含义的行为。

+(id) actionWithAction: (CCActionInterval*)action

CCRepeatForever其实是对另一个行为的封装,参数action就是被封装的行为对象。

CCSpeed

CCSpeed的接口和CCRepeatForever一样,没有什么特别之处,它的作用就是改变其它行为的执行速度,比如一个精灵以每秒10帧的速度切换自己的frame来播放动画,CCSpeed可以将其改成每秒20帧或每秒5帧。

CCFollow

+(id) actionWithTarget: (CCNode*)fNode

使节点跟随另一个节点移动,参数fNode即为被跟随的节点。

+(id) actionWithTarget: (CCNode*)fNode worldBoundary: (CGRect)rect

使节点跟随另一个节点移动,参数rect表示跟随者只能在该区域内移动,如超出该范围,则停止跟随。

CCActionInterval

持续性(防和谐= =)行为类,CCFiniteTimeAction的子类,因此能和所有继承自CCFiniteTimeAction的类的对象组成行为序列,换句话说,它不能和CCRepeatForever、CCSpeed以及CCFollow组成行为序列。它和CCActionInstant的区别在于:CCActionInterval行为的执行需要一定的时间(或者说一个过程),而CCActionInstant的行为都是瞬间完成的,没有过程(类似节点的各种“set”方法)。

+(id) actionWithDuration: (ccTime)d

持续行为类的标志性方法,作用为创建一个在d秒内执行完自身行为的对象并返回。

-(id) initWithDuration: (ccTime)d

初始化,将设置行为的执行时间设置为d秒。

CCActionInstant

瞬时行为类,CCFiniteTimeAction的子类,能和所有继承自CCFiniteTimeAction的类的对象组成行为序列。它与CCActionInterval的唯一区别就是没有执行过程。CCActionInstant的接口没有什么特别之处,就不单独介绍了。

下面列出的是瞬时行为类的子类

CCHide  隐藏节点,效果类似于CCNode的setVisible:No ,将其封装成action是为了使其可以和其他行为组成一个连续的行为序列。

[CCHide action]

CCShow  显示节点,效果类似于CCNode的setVisible:Yes ,与CCHide的作用正好相反。

[CCShow action]

CCToggleVisibility  切换节点可见性,即当节点可见时设为不可见,不可见时设为可见。

[CCToggleVisibility action]

CCPlace  放置节点,效果类似于CCNode的setPosition。

[CCPlace  actionWithPosition:pos]

CCFlipX  横向翻转节点,效果等同于CCNode执行setFlipX函数。

[CCFlipX actionWithFlipX:isFlip]

CCFlipY  纵向翻转节点,效果等同于CCNode执行setFlipY函数。

[CCFlipY actionWithFlipYX:isFlip]

CCCallFunc  自定义行为,效果为调用一个自定义的方法,通过方法的实现来达到自己想要的效果。

[CCCallFunc actionWithTarget:self selector:@selector(fun)]

CCCallFuncN  自定义行为,效果与CCCallFunc基本相同,只是会将节点对象作为参数传递给被调用的函数。

[CCCallFuncN actionWithTarget:self selector:@selector(fun:)]

CCCallFuncND  自定义行为,效果与CCCallFuncN基本相同,只是可以额外传递一个参数给被调用的函数。

[CCCallFuncND actionWithTarget:self selector:@selector(fun:data:) data:object]

*需要特别注意的是,CallFunc虽然是瞬时行为,但这个“瞬时”只体现在它调用函数是在一瞬间完成的,但这个函数的执行可能需要一段时间,就是说CallFunc的行为已经做完了,开始执行序列后面的行为,但被调用的函数还没有完成,此时它们是并行的。

下面是持续行为类,它们全部继承自CCActionInterval

CCMoveTo  将节点移动到指定坐标。

[CCMoveTo actionWithDuration:time position:pos]

CCMoveBy  使节点根据参数发生相对位移。

[CCMoveBy actionWithDuration:time position:pos]

CCJumpTo  使节点跳跃到指定的位置,可以设置高度和次数。

[CCJumpTo actionWithDuration:time position:pos height:height jumps:times]

CCJumpBy  和CCJumpTo类似,但是位移是相对位移。

[CCJumpBy actionWithDuration:time position:pos height:height jumps:times]

CCBezierBy  使节点按贝塞尔曲线运动。

[CCBezierBy actionWithDuration:time Bezier:path] (path的类型是ccBezerConfig,这是一个结构体,成员见下方)

CGPoint endPosition  曲线的终点坐标(相对于起点的偏移量,非绝对坐标),图中的P3

CGPoint controlPoint_1 曲线第一个弧度的参考点坐标(相对于起点的偏移量,非绝对坐标),图中的P1

CGPoint controlPoint_2曲线第二个弧度的参考点坐标(相对于起点的偏移量,非绝对坐标),图中的P2

CCScaleTo 设置节点的缩放倍率。

[CCScaleTo actionWithDuration:time scale:rate]

[CCScaleTo actionWithDuration:time scaleX:x scaleY:y]

CCScaleBy 缩放节点(相对)

[CCScaleBy actionWithDuration:time scale:rate]

[CCScaleBy actionWithDuration:time scaleX:x scaleY:y]

CCRotateTo  设置节点的旋转角度。

[CCRotateTo actionWithDuration:time angle:rotate]

CCRotateBy  旋转节点

[CCRotateBy actionWithDuration:time angle:rotate]

CCBlink 使节点闪烁,可以设置闪烁次数。

[CCBlink actionWithDuration:time blinks:times]

CCTintTo  设置节点色调。

[CCTintTo actionWithDuration:time red:r green:g blue:b]

CCTintBy  使节点色调发生偏移。

[CCTintBy actionWithDuration:time red:r green:g blue:b]

(*颜色的参数类型其实就是无符号的byte)

CCFadeTo 逐渐改变透明度

[CCFadeTo actionWithDuration:time opacity:color]

CCFadeIn 淡入。

[CCFadeIn actionWithDuration:time]

CCFadeOut 淡出。

[CCFadeOut actionWithDuration:time]

CCDelay  延迟,即增加一个间歇时间。

[CCDelay actionWithDuration:time]

复合行为

CCSequence  行为序列(继承自CCActionInterval),即将若干个待执行的行为按顺序组合在一起,然后依次执行,如果中间有持续行为的话则等到前一个行为执行完毕后再执行下一个(CCCallFunc是并行),因此单独的CCSequence对象是没有意义的。

[CCSequence actions:act0, act1, act2, nil] (act0、act1、act2都是单独的行为对象)

[CCSequence actionsWithArray:act] (act是保存着行为对象的数组)

CCSpawn  并行行为(继承自CCActionInterval),即将若干个待执行的行为组合在一起,同时执行它们,行为的执行时间以最长的那个行为为准,就是说当全部的子行为结束时,CCSpawn才算结束。单独的CCSpawn对象也没有意义。

[CCSpawn actions:act0, act1, act2, nil]

[CCSpawn actionsWithArray:act]

CCRepeat  重复执行行为(继承自CCActionInterval),就是将一个已知的行为或行为序列多次执行,执行的次数通过参数设定,效果类似于CCRepeatForever,但CCRepeat只执行有限次,有运行结束的那一刻。

[CCRepeat actionWithAction:act times:times]

*上面的三个类都是容器,可以容纳多个行为,它们之间也可以互相容纳。

CCAnimation  动画,这个行为有点特殊,它并非继承自CCAction以及CCAction的任何子类,相对来说是个独立的行为。CCAnimation的作用是根据一个帧序列连续切换,形成一个动画,可以说是专门为精灵类准备的。

变速类行为

这类行为的作用就是改变另一行为的速度,基类是CCEaseAction,继承自CCActionInterval。

CCEaseIn  由快至慢

CCEaseOut  由慢至快

CCEaseInOut  由快至慢再由慢至快

CCEaseSineIn  由快至慢

CCEaseSineOut  由慢至快

CCEaseSineInOut  由快至慢再由慢至快

CCEaseExponentianIn  由极快至慢

CCEaseExponentianOut  由慢至极快

CCEaseExponentianInOut  由极快至慢再由慢至极快

CCActionmanager

这个类其实并不属于行为类,它的父类是NSObject,而不是CCAction,但它又与CCAction密不可分,因此在这里单独介绍下。

CCActionmanager是个标准的单例类,它的作用顾名思义,就是管理行为类的对象,工作原理是:当节点执行runAction时,会把action通过addAction方法将对象传递给CCActionmanager的单例,该实例再把这个action添加到自己的行为序列中。CCActionmanager通过schedule定时刷新自己的update方法,在这个方法中去调用行为序列中每个action的step(会有一些筛选条件,比如暂停的行为不会update),这些step方法再根据自身的完成进度去update或是结束行为。就是说实际上是由CCActionmanager驱动的每个action去更新自己的逻辑,而runAction方法只是将行为对象添加进CCActionmanager的更新队列罢了。当节点被清除或是行为结束时,CCActionmanager会自动将action从队列中剔除,无需开发者操心。

到这里行为类的工作原理已经介绍的差不多了,一些细节上的东西很难一次讲清楚,我会在后面的章节中尽量补充,大家如果觉得有欠缺的话希望能够提出来,以帮助我们改进,谢谢。

下面是代码示例(下载)

-(id) init
{self = [super init];if (self){//创建层,并添加为场景的子节点m_layer = [[CCLayer alloc] init];[self addChild:m_layer];//根据图片yz创建精灵,精灵的使用之后会做介绍m_actor = [CCSprite spriteWithFile:@"yz.png"];//设置精灵的坐标点为120, 300[m_actor setPosition:CGPointMake(120, 300)];//设置精灵的行为[self setAction];//将精灵添加为层的子节点,Z轴为1,标签为1[m_layer addChild:m_actor z:1 tag:1];}return self;
}-(void) setAction
{//向下移动120像素id moveDown = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, -120)];//向右移动90像素id moveRight = [CCMoveBy actionWithDuration:1 position:CGPointMake(90, 0)];//向上移动120像素id moveUp = [CCMoveBy actionWithDuration:1 position:CGPointMake(0, 120)];//向左移动90像素id moveLeft = [CCMoveBy actionWithDuration:1 position:CGPointMake(-90, 0)];//放大1/4id zoomOut = [CCScaleBy actionWithDuration:0.3f scale:1.25f];//缩小20%id zoomIn = [CCScaleBy actionWithDuration:0.3f scale:0.8f];//将下移、右移、上移、左移组成一个顺序序列id moveSet = [CCSequence actions:moveDown, moveRight, moveUp, moveLeft, nil];//将放大、缩小组成一个顺序序列,并重复3次id zoomSet = [CCRepeat actionWithAction:[CCSequence actions:zoomOut, zoomIn, nil] times:3];//将移动和缩放两个序列组合成一个并列执行的任务id singleAct = [CCSpawn actions:moveSet, zoomSet, nil];//无限循环这个并行的组合序列id repeatAct = [CCRepeatForever actionWithAction:singleAct];//启动action[m_actor runAction:repeatAct];
}

 

运行后的效果(图片会以一个矩形的轨迹逆时针运动,每走一圈会缩放三次)

这篇关于Cocos2D研究院之CCAction详解(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947904

相关文章

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四