Action动作类
Action动作类:x引擎内置的强大且丰富的动作类族。
Action类族由非常多的成员组成,他们可以负责精灵在场景中的各种动作:比如在
2D坐标系的移动,精灵对象的缩放,围绕某个点的旋转运动。此外,
Action还提供更为复杂的运动控制功能,比如某个
Action的速度控制,慢动作处理,由快到慢的渐变处理,同时执行多个动作的处理,执行一个动作序列等等。灵活的将各种
Action类进行组合使用,你就能让精灵执行各种想要的运动效果,实现功能强大的动作或运动类游戏。
延时动作:就是指动作的完成需要一定时间。因此
actionWithDuration是延时动作执行时的第一个参数,延时动作的共同基类是
CCIntervalAction。代表类名称:
CCMoveTo、
CCMoveBy、
CCJumpTo、
CCJumpTo、
CCScaleTo、
CCScaleBy、
CCRotateTo、
CCRotateBy。
组合动作:按照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作。代表类名称:
CCSequence、
Spawn、
Repeate、
Reverse、
Animation、
RepeatForever。
速度变化:基本动作和组合动作实现了针对精灵的各种运动、动画效果的改变,但这样的改变是匀速的,通过
CCEaseAction为基类的类系和
CCSpeed类我们可以很方便的修改精灵执行动作的速度:执行慢动作或者是由快至慢再或者是由慢至快。代表类名称:
CCSpeed、
EaseIn、
EaSEOut、
EaseInOut、
EaseSineIn、
EaseSineOut、
EaseSineInOut。
扩展动作:其他用途,比如延时动作。代表类名称:Delay
使用:在创建好一个具体类型的动作类实例之后,精灵类对象就可以使用
runAction(CCAction* action)函数开始执行对应的动作。
CCSprite* sprite = CCSprite::create("sprite.png"); CCActionInterval* actionMove = CCMoveBy::create(5.0f,ccp(100,100)); sprite->runAction(actionMove);注:在游戏中通常都是在精灵对象上使用 runAction函数,但此函数其实是精灵类的父类 CCNode定义的方法,所以除了精灵类, CCNode类型及其子类型都是可以执行动作对象的。比如一个 CCLayer层节点类型,也可以执行旋转动作,这样就可以实现整个游戏场景都在旋转的效果。
actionMove->setTag(100); ...... sprite->stopActionByTag(100);当精灵同时执行多个动作时,可以使用stopAllActions()函数来停止作用在其身上的全部动作对象:
sprite->stopAllActions();
移动类动作:
CCMoveTo:可以实现精灵对象从当前位置移动到二维坐标的某个点上。
CCMoveBy:可以实现当前对象从当前点在
X轴和
Y轴方向移动指定的
x个像素和
y个像素。
使用:
CCActionInterval* actionTo = CCMoveTo::create(2,ccp(winSize.width*0.5f,winSize.height*0.5f)); CCActionInterval* actionBy = CCMoveBy::create(2,ccp(80,80)); CCActionInterval* actionByBack = actionBy->reverse(); m_tamara->runAction(actionTo); m_grossini->runAction(actionBy); m_kathia->runAction(actionByBack);以上代码首先是定义 CCMoveTo类型的动作 actionTo,指定时间参数是2秒,要移动到的目标点是屏幕的中央,这个动作执行后m_tamara这个精灵对象就会从当前点使用2秒时间移动到屏幕中央。
第二个定义的是
CCMoveBy类型的动作
actionBy,指定时间参数也是2秒,要在X轴和Y轴上都移动80个像素单位,这个动作执行后m_grossini精灵对象就会使用2秒时间同时在X轴和Y轴移动80个像素单位的距离。
第三个动作也是
CCMoveBy类型,它是由刚刚生成的
actionBy动作使用
reverse()函数生成的反向动作,即在
X轴和
Y轴移动负80个像素单位,然后这个动作由m_kathia精灵对象来执行。
CCJumpTo:可以实现精灵对象从当前位置跳跃到某个点上。
CCJumpBy:可以实现当前对象从当前位置跳跃到指定的
x个像素和
y个像素。
使用:
CCActionInterval* actionTo = CCJumpTo::create(2,ccp(300,300),50,4); CCActionInterval* actionBy = CCJumpBy::create(2,0),4);在定义 CCJumpTo类型的动作 actionTo时,第一个参数是2秒时间,第二个参数是跳跃移动的点,第三个参数是每次跳跃时达到的高度,第四个参数是从移动开始到移动结束一共执行跳跃动作4次。定义 CCJumpBy类型动作 actionBy时参数的意义也是类似,只有第二个参数的意义是 X轴和 Y轴移动的距离。
缩放、旋转类动作:
CCScaleTo:可以实现X轴和Y轴方向,或者两方向上同时进行缩放动作。
CCScaleBy:和
CCScaleTo类似,但是它的缩放倍数指的是缩放前和缩放后相差的倍数。
使用:
CCActionInterval* actionTo = CCScaleTo::create(2.0f,0.5f); CCActionInterval* actionTo2D = CCScaleTo::create(2.0f,2.0f,0.5f); CCActionInterval* actionBy = CCScaleBy::create(2.0f,2.0f); sprite1->runAction(actionTo); sprite2->runAction(actionTo2D); sprite3->runAction(actionBy);CCScaleTo在构建时的第一个参数是缩放使用的时间,它提供两种不同的参数形式,如果只有第二个参数而没有指定第三个参数,则第二个参数就是 X轴和 Y轴共同要缩放到得的倍数;如果第二个参数和第三个参数都指定了,则第二个参数是 X轴要缩放到的数值,第三个参数是 Y轴要缩放到的数值。 CCScaleBy与 CCScaleTo类似,只不过他的缩放倍数是指缩放前和缩放后相差的倍数。
CCRotateTo:可以实现控制精灵旋转到指定的角度。
CCRotateBy:可以实现控制精灵在当前角度的基础上再旋转固定角度。
使用:
CCActionInterval* actionTo = CCRotateTo::create(2,45); CCActionInterval* actionTo2 = CCRotateTo::create(2,-45); CCActionInterval* actionBy = CCRotateBy::create(2,360); sprite1->runAction(actionTo); sprite2->runAction(actionTo2); sprite3->runAction(actionBy);CCRotateTo构建时,第一个参数是旋转的时间,第二个参数是当前精灵将要旋转的角度。 CCRotateBy和 CCRotateTo类似,只是第二个参数不同,他的意义是此旋转过程中需要旋转的角度。其中正数表示顺时针旋转,负数表示逆时针旋转。
淡入淡出及变色类动作:
CCFadeIn:会把当前执行动作对象的透明度逐渐修改为255,也就是最大不透明度,使用时通常先将精灵的透明度设置为0,让物体因此完全透明而不可见,然后执行
CCFadeIn动作对象,在指定的时间内,精灵逐渐出现在屏幕上。
使用:
CCActionInterval* action1 = CCFadeIn::create(1.0f); CCActionInterval* action2 = CCFadeOut::create(1.0f); sprite1->runAction(action1); sprite2->runAction(action2);效果:参考 ActionFade例子。
CCTintBy:和
CCTintTo类似,但颜色值变量是当前颜色值和改变后颜色值的差值。
使用:
CCActionInterval* actionTo = CCTintTo::create(2,255,255); CCActionInterval* actionBy = CCTintBy::create(2,-127,-255,-127); sprite1->runAction(actionTo); sprite2->runAction(actionBy);第一个参数是颜色过渡使用的时间,后面三个参数分别对应着 RGB颜色分量的。
同步动作:
在x引擎中,如果要想同时执行多个延时动作,最好的方式就是将这些需要同时执行的动作放在一起,定义称为一个新的同步动作,这样精灵在执行这个动作时,会将这些动作一起执行,得到多个动作执行后的累加效果。在x引擎中,你也可以手动一个动作一个动作的执行,但x引擎不能保证这样做的最终效果,尤其是需要同步执行的动作类非常多时,一定要使用同步动作。
使用:
CCActionInterval* jump = CCJumpBy::create(2,4); CCActionInterval* rotate = CCRotateBy::create(2,720); CCAction* action = CCSpawn::create(jump,rotate,NULL); m_grossini->runAction(action);效果:参考 ActionSpawn例子。
顺序动作:
在执行多个动作类对象的时候,除了同步执行动作以外,还有一种比较重要的就是顺序动作类
CCSequence。也就是指将多个动作按照顺序放入一个队列,依次执行队列中的动作。
CCSequence:可以将多个动作按指定顺序执行。
使用:
CCActionInterval* move = CCMoveBy::create(1,ccp(150,0)); CCActionInterval* delay = CCDelayTime::create(2); CCFiniteTimeAction* action = CCSequence::create(move,delay,move,NULL); m_grossini->runAction(action);定义了一个移动类动作对象,和一个延时类动作对象。这两个对象将按照移动、延时2秒、移动的次序放入动作队列中,然后让精灵对象执行这个动作序列。
在顺序动作中,有时需要加入一个函数调用作为动作序列的一个动作,这个函数调用往往是用于通知游戏某个动作结束了,比如可以在动作序列最后一个动作调用函数。这个函数就可以处理全部动作完成后的工作,这里就需要使用
x引擎提供的宏定义,将函数转换为一个瞬时动作。
使用:
CCFiniteTimeAction* action = CCSequence::create( CCPlace::create(ccp(200,200)),CCShow::create(),CCMoveBy::create(1,0)),CCCallFunc::create(this,callfunc_selector(ActionSequence2::callback1)),NULL);CCCallFunc::create()函数就可以将函数变为动作对象,而函数需要使用 callfunc_selector来指定,这样,在 ActionSequence2::callback1()函数中,就可以作为动作末尾的事件通知,进行相应处理了。
效果:参考
ActionDelayTime例子。
重复动作:
有时候,一个动作需要重复执行若干次,甚至是一刻不停的重复执行,这个时候,就要使用到
x引擎提供的重复动作以及无限重复动作类了,他们分别是
CCRepeat、
CCRepeatForever。
CCRepeat:可以指定但前对象重复执行n次动作。
CCRepeatForever:可以指定当前对象执行无限次动作。
使用:
CCRotateBy* rot1 = CCRotateBy::create(1,360); CCRotateBy* rot2 = CCRotateBy::create(1,-360); CCActionInterval* action1 = CCRepeat::create(rot1,5); CCActionInterval* action2 = CCRepeatForever::create(rot2); sprite1->runAction(action1); sprite2->runAction(action2);CCRepeat第一个参数是要执行的动作,第二个参数是循环的次数。 CCRepeatForever直接就指定一个动作,使得精灵对象一直重复旋转,一直到精灵对象被销毁为止才会结束动作。
速度控制动作:
在使用诸如旋转,移动等延时动作时,可以在这些动作的基础上使用
CCSpeed类定义出新的快速或者慢速动作对象,其动作执行的效果相同,只是执行时的速度由
CCSpeed类对象控制,可以通过设置
CCSpeed类的
m_fSpeed速度属性决定新的动作是快还是慢。如果设置速度属性为2,则速度提高一倍,如果设置为0.5,则速度降低为原始速度的二分之一。
使用:
CCActionInterval* jump = CCJumpBy::create(4,ccp(240,100,4); CCActionInterval* rot = CCRotateBy::create(4,360*2); CCSpeed* speed1 = CCSpeed::create(jump,1.0f); CCSpeed* speed2 = CCSpeed::create(rot,1.0f); ...... speed1->setSpeed(2.5f); speed2->setSpeed(0.25f);CCSpeed在创建实例时,第一个参数指定要控制的动作类对象,第二个参数填写执行速度的倍数。在游戏过程中,我们设置 speed1将速度加快到原来的2.5倍,而 speed2的速度设置为原来的四分之一。
样条曲线动作:
样条曲线动作的运动轨迹必须要经过一些复杂的数学运算,才能计算出这套动作的完整轨迹。而在定义这些动作时,只需要在参数中指定几个关键的坐标点,运动轨迹就是经过这些关键坐标点的直线或者是曲线。至于是直线还是曲线,曲线弯曲的方向,曲线的弯曲平滑程度都要根据指定的
tension扩张力参数来运算得出。
x引擎将复杂难懂的曲线数学算法都封装了起来,用户只需要指定运动轨迹的关键点即可实现功能强大的曲线运动。
使用:
CCSize s = CCDirector::sharedDirector()->getWinSize(); CCPointArray* array = CCPointArray::create(20); array->addControlPoint(ccp(0,0)); array->addControlPoint(ccp(s.width/2-30,s.height-80)); array->addControlPoint(ccp(0,0));样条曲线动作类名为 CCCardinalSplineBy,上面代码定义的5个坐标点,以及类名中的 By表明,运动轨迹是以执行曲线动作的精灵锚点为原点,进而组成的一个闭合二维矩形区域。
定义一种具有向外松弛弯曲效果的曲线动作:
CCCardinalSplineBy* action = CCCardinalSplineBy::create(3,array,0); CCActionInterval* reverse = action->reverse(); CCFiniteTimeAction* seq = CCSequence::create(action,reverse,NULL); m_tamara->setPosition(ccp(50,50)); m_tamara->runAction(seq);这里定义了一个样条曲线,设定了它的执行时间为3秒,第二个参数是其运动轨迹数组,第三个参数是扩张力参数。设置为0,这会使曲线向外松弛弯曲。这个扩张力参数设置为1表示没有扩张力,每两个点之间的连线是直线;设置小于1时,向外松弛弯曲,数值越小弯曲程度越大;设置大于1时,向内缩紧弯曲,数值越大弯曲程度越大。在定义好样条曲线之后,我们紧接着定义一个此动作的反动作,这个反动作会按照原来的运动轨迹回到最初的位置。最后,我们将这两个样条曲线结合成为一个动作序列,让精灵 m_tamara来执行这个动作序列。接下来再设置第二个曲线动作,这次设置扩张力为1,表示每两个点之间做直线动作:
CCCardinalSplineBy* action2 = CCCardinalSplineBy::create(3,1); CCActionInterval* reverse2 = action2->reverse(); CCFiniteTimeAction* seq2 = CCSequence::create(action2,reverse2,NULL); m_kathia->setPosition(ccp(s.width/2,50)); m_kathia->runAction(seq2);效果:参考 ActionCardinalSpline例子。
贝塞尔曲线动作:
贝塞尔曲线是应用于二维图形应用程序的数学曲线,通过它,可以绘制出精确的曲线线条。贝塞尔曲线的定义有四个点:起始点、终止点(也称锚点)以及两个相互分离的中间点。滑动两个中间点,贝塞尔曲线的形状会发生变化。
P0是起点,
P3是终点,
P1、
P2是控制点。变换
P1或者
P2点的位置,将能够起到控制曲线弧度的变化。
贝塞尔曲线经常用于在游戏中模拟抛物线。
x引擎提供了
CCBezierBy和
CCBezierTo两个贝塞尔曲线动作类。
使用:
ccBezierConfig bezier; bezier.controlPoint_1 = ccp(0,s.equals/2); bezier.controlPoint_2 = ccp(300,-s.equals/2); bezier.endPosition = ccp(300,100);只需要提供两个控制点和一个终点就可以了,这里要注意的是 CCBezier这个 action是以当前位置为起始点的。
CCActionInterval* bezierForward = CCBezierBy::create(3,bezier); CCActionInterval* bezierBack = bezierForward->reverse(); CCAction* rep = CCRepeatForever::create((CCActionInterval*)CCSequence::create(bezierForward,bezierBack,NULL));效果:参考 ActionTest例子。