Action动作类
Action动作类:x引擎内置的强大且丰富的动作类族。
Action类族由非常多的成员组成,他们可以负责精灵在场景中的各种动作:比如在
2D坐标系的移动,精灵对象的缩放,围绕某个点的旋转运动。此外,
Action还提供更为复杂的运动控制功能,比如某个
Action的速度控制,慢动作处理,由快到慢的渐变处理,同时执行多个动作的处理,执行一个动作序列等等。灵活的将各种
Action类进行组合使用,你就能让精灵执行各种想要的运动效果,实现功能强大的动作或运动类游戏。
瞬时动作:就是不需要时间,马上就完成的动作。瞬时动作的共同基类是
InstantAction。代表类名称:
Place、
Hide、
Show、
ToggleVisibility。
延时动作:就是指动作的完成需要一定时间。因此
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层节点类型,也可以执行旋转动作,这样就可以实现整个游戏场景都在旋转的效果。
任意类型的动作对象,都可以设置一个
Tag标签,这个
Tag标签是一个整数,比如设置为
100,这样执行此动作的精灵对象就可以通过
Tag标签找到动作对象,可以通过
Tag来停止动作的执行:
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精灵对象来执行。
效果:参考
TestCpp项目
ActionTest中的
ActionMove例子。
CCJumpTo:可以实现精灵对象从当前位置跳跃到某个点上。
CCJumpBy:可以实现当前对象从当前位置跳跃到指定的
x个像素和
y个像素。
使用:
CCActionInterval* actionTo = CCJumpTo::create(2, ccp(300, 300), 50, 4);
CCActionInterval* actionBy = CCJumpBy::create(2, ccp(300, 0), 50, 4);
在定义
CCJumpTo类型的动作
actionTo时,第一个参数是2秒时间,第二个参数是跳跃移动的点,第三个参数是每次跳跃时达到的高度,第四个参数是从移动开始到移动结束一共执行跳跃动作4次。定义
CCJumpBy类型动作
actionBy时参数的意义也是类似,只有第二个参数的意义是
X轴和
Y轴移动的距离。
效果:参考
TestCpp项目
ActionTest中的
ActionJump例子。
缩放、旋转类动作:
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类似,只不过他的缩放倍数是指缩放前和缩放后相差的倍数。
效果:参考
TestCpp项目
ActionTest中的
ActionScale例子。
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类似,只是第二个参数不同,他的意义是此旋转过程中需要旋转的角度。其中正数表示顺时针旋转,负数表示逆时针旋转。
效果:参考
TestCpp项目
ActionTest中的
ActionRotate例子。
淡入淡出及变色类动作:
CCFadeIn:会把当前执行动作对象的透明度逐渐修改为255,也就是最大不透明度,使用时通常先将精灵的透明度设置为0,让物体因此完全透明而不可见,然后执行
CCFadeIn动作对象,在指定的时间内,精灵逐渐出现在屏幕上。
CCFadeOut:与
CCFadeIn正好相反,它不断修改精灵对象的透明度,让其最终为0,变为完全透明,在屏幕上不可见。
使用:
CCActionInterval* action1 = CCFadeIn::create(1.0f);
CCActionInterval* action2 = CCFadeOut::create(1.0f);
sprite1->runAction(action1);
sprite2->runAction(action2);
效果:参考
TestCpp项目
ActionTest中的
ActionFade例子。
CCTintTo:可以将精灵对象从当前颜色,经过指定的时间过渡成为指定的颜色,或者是
RGB每个颜色变量上增加或者减少指定的数值。
CCTintBy:和
CCTintTo类似,但颜色值变量是当前颜色值和改变后颜色值的差值。
使用:
CCActionInterval* actionTo = CCTintTo::create(2,255,0,255);
CCActionInterval* actionBy = CCTintBy::create(2,-127,-255,-127);
sprite1->runAction(actionTo);
sprite2->runAction(actionBy);
第一个参数是颜色过渡使用的时间,后面三个参数分别对应着
RGB颜色分量的。
效果:参考
TestCpp项目
ActionTest中的
ActionTint例子。
同步动作:
在x引擎中,如果要想同时执行多个延时动作,最好的方式就是将这些需要同时执行的动作放在一起,定义称为一个新的同步动作,这样精灵在执行这个动作时,会将这些动作一起执行,得到多个动作执行后的累加效果。在x引擎中,你也可以手动一个动作一个动作的执行,但x引擎不能保证这样做的最终效果,尤其是需要同步执行的动作类非常多时,一定要使用同步动作。
CCSpawn:可以将多个动作封装到一起。
CCSpawn在定义多个动作类时,可以添加多个动作,而最后一个参数
NULL,表示动作添加结束,
NULL是动作数组的结尾。
使用:
CCActionInterval* jump = CCJumpBy::create(2, ccp(300,0), 50, 4);
CCActionInterval* rotate = CCRotateBy::create(2, 720);
CCAction* action = CCSpawn::create(jump, rotate, NULL);
m_grossini->runAction(action);
效果:参考
TestCpp项目
ActionTest中的
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,ccp(100,0)),
CCCallFunc::create(this, callfunc_selector(ActionSequence2::callback1)),
NULL);
CCCallFunc::create()函数就可以将函数变为动作对象,而函数需要使用
callfunc_selector来指定,这样,在
ActionSequence2::callback1()函数中,就可以作为动作末尾的事件通知,进行相应处理了。
效果:参考
TestCpp项目
ActionTest中的
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直接就指定一个动作,使得精灵对象一直重复旋转,一直到精灵对象被销毁为止才会结束动作。
效果:参考
TestCpp项目
ActionTest中的
ActionRepeat和
ActionRepeatForever例子。
速度控制动作:
在使用诸如旋转,移动等延时动作时,可以在这些动作的基础上使用
CCSpeed类定义出新的快速或者慢速动作对象,其动作执行的效果相同,只是执行时的速度由
CCSpeed类对象控制,可以通过设置
CCSpeed类的
m_fSpeed速度属性决定新的动作是快还是慢。如果设置速度属性为2,则速度提高一倍,如果设置为0.5,则速度降低为原始速度的二分之一。
CCSpeed:可以在所有延时动作对象的基础之上定义速度控制类对象,在游戏实时进行过程中,你还可以通过
CCSpeed类提供的
setSpeed(float fSpeed)函数随时更新他运行的速度。
使用:
CCActionInterval* jump = CCJumpBy::create(4,ccp(240, 0), 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引擎将复杂难懂的曲线数学算法都封装了起来,用户只需要指定运动轨迹的关键点即可实现功能强大的曲线运动。
使用:
在定义样条曲线动作之前,用户需要首先定义好移动轨迹,
x引擎提供了定义运动轨迹的内置方法:
CCSize s = CCDirector::sharedDirector()->getWinSize();
CCPointArray* array = CCPointArray::create(20);
array->addControlPoint(ccp(0, 0));
array->addControlPoint(ccp(s.width/2-30, 0));
array->addControlPoint(ccp(s.width/2-30, s.height-80));
array->addControlPoint(ccp(0, 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, array, 1);
CCActionInterval* reverse2 = action2->reverse();
CCFiniteTimeAction* seq2 = CCSequence::create(action2, reverse2, NULL);
m_kathia->setPosition(ccp(s.width/2, 50));
m_kathia->runAction(seq2);
效果:参考
TestCpp项目
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));
效果:参考
TestCpp项目
ActionTest例子。