Cocos2d中的另一个核心应该属Action模块了,从基类CCAction到其下的各种子类,有数十个之多,通过他们之间的相互组合,可以得到非常丰富的动态内容。
从名称上看,Action这套东西肯定是同显示对象的动作有关,但这些东西内部的原理又是怎样的呢?如果你熟悉设计模式,那么你可以试着回忆一下命令模式这一概念,Cocos2d中所谓的动作从设计的角度讲,就是一个命令。
先来看它的接口。所谓的命令模式,其实就是对某一个或者多个操作的封装,而操作是针对于某个对象的,这个对象就是这个命令的目标:
通过CCActioin的void setTarget(CCNode *pTarget)和CCNode *getTarget(void)方法可以分别设置和获取命令的操作对象,实际上我们发现,CCACtion的目标是节点CCNode对象,也就是说Cocos2d中的动作都是用来操作显示对象的。
除此之外CCAction还有一个void startWithTarget(CCNode * pTarget)方法,该方法在动作/命令执行之前调用,它也有设置操作目标的作用,至于具体怎么用,要看子类怎么实现它,一般来说这个方法主要执行一些初始化操作。
命令的目标有了,接下来我们想知道命令如何触发。因为CCAction的目标是一个显示列表对象,因此动作的触发可以交给CCNode对象来承担:
通过CCNode对象的CCAction * runAction (CCAction *action)方法我们可以给显示对象传递一个动作对象,并执行它。事实上这个方法封装了命令目标的设置在里面,也就是说我们可以简单的通过这个方法来执行一个命令对象,而不需要自己主动去设置动作的目标了。
CCFlipX * flip = CCFlipX::create(true); pSprite->runAction(flip);
上面的代码实现了一个图片的水平翻转。
需要指出的是,动作或者说命令并不是立即被触发的,runAction方法实际上只是将动作对象放入等待执行的队列中,这个队列将在统一的帧周期中被依次执行。当一个帧周期到来时,首先会被调用的是CCAction的void step (float dt)方法,该方法接受一个时间差作为参数,并计算出动作的(时间)进度值(大于等于零小于等于1),接着传递给CCAction的void update (float time)方法,update方法将根据进度值更新对象的显示状态。
CCAction有三个子类CCFiniteTimeAction,CCFollow和CCSpeed。其中:
CCFiniteTimeAction顾名思义就是有限时间的动作,包括瞬时动作,和间隔动作,比如缓动。
CCFollow设置对象的跟随另一个对象运动,而CCSpeed对显示对象没有直接控制作用,他是通过控制其他的动作(控制该动作的执行速度)来间接地控制显示对象。
短短的一篇随笔无法完全介绍Action模块的具体应用,更多的内容放在后面通过具体的案例来进一步深入研究。