Cocos2d-x学习笔记(十)-------->动作类

来源:互联网 发布:董洁 潘粤明 知乎 编辑:程序博客网 时间:2024/06/04 18:02
Action动作类
Action动作类:x引擎内置的强大且丰富的动作类族。Action类族由非常多的成员组成,他们可以负责精灵在场景中的各种动作:比如在2D坐标系的移动,精灵对象的缩放,围绕某个点的旋转运动。此外,Action还提供更为复杂的运动控制功能,比如某个Action的速度控制,慢动作处理,由快到慢的渐变处理,同时执行多个动作的处理,执行一个动作序列等等。灵活的将各种Action类进行组合使用,你就能让精灵执行各种想要的运动效果,实现功能强大的动作或运动类游戏。

瞬时动作:就是不需要时间,马上就完成的动作。瞬时动作的共同基类是InstantAction。代表类名称:PlaceHideShowToggleVisibility
延时动作:就是指动作的完成需要一定时间。因此actionWithDuration是延时动作执行时的第一个参数,延时动作的共同基类是CCIntervalAction。代表类名称:CCMoveToCCMoveByCCJumpToCCJumpToCCScaleToCCScaleByCCRotateToCCRotateBy
组合动作:按照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作。代表类名称:CCSequenceSpawnRepeateReverseAnimationRepeatForever
速度变化:基本动作和组合动作实现了针对精灵的各种运动、动画效果的改变,但这样的改变是匀速的,通过CCEaseAction为基类的类系和CCSpeed类我们可以很方便的修改精灵执行动作的速度:执行慢动作或者是由快至慢再或者是由慢至快。代表类名称:CCSpeedEaseInEaseOutEaseInOutEaseSineInEaseSineOutEaseSineInOut
扩展动作:其他用途,比如延时动作。代表类名称: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();

在讲解x引擎的导演类CCDirector时,使用CCDirector::shareDirector()->pause()函数可以导致整个游戏停止状态更新,此时,x引擎的动作管理器也处于暂停状态,所有正在执行动作的场景节点都会暂停动作的更新,直到使用CCDirector::shareDirector()->resume()函数之后,x引擎的动作管理器才恢复工作状态,所有被暂停动作更新的场景节点才会继续执行之前的动作对象。

移动类动作
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轴要缩放到的数值。CCScaleByCCScaleTo类似,只不过他的缩放倍数是指缩放前和缩放后相差的倍数。
效果:参考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构建时,第一个参数是旋转的时间,第二个参数是当前精灵将要旋转的角度。CCRotateByCCRotateTo类似,只是第二个参数不同,他的意义是此旋转过程中需要旋转的角度。其中正数表示顺时针旋转,负数表示逆时针旋转。
效果:参考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引擎提供的重复动作以及无限重复动作类了,他们分别是CCRepeatCCRepeatForever
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中的ActionRepeatActionRepeatForever例子。

 速度控制动作
在使用诸如旋转,移动等延时动作时,可以在这些动作的基础上使用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是终点,P1P2是控制点。变换P1或者P2点的位置,将能够起到控制曲线弧度的变化。

贝塞尔曲线经常用于在游戏中模拟抛物线。x引擎提供了CCBezierByCCBezierTo两个贝塞尔曲线动作类。
使用
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例子。

0 0
原创粉丝点击