版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
游戏开发平台Cocos2D-xocos2d-X中的动作特效与动画2019/3/8xxxxxxxxxx1游戏开发平台Cocos2D-xocos2d-X中的动作特效与2019/3/8xxxxxxxxxx2
Cocos2D-x的基础类,包括节点类CCNode、导演类CCDirector、场景类CCScene、布景层、CCLayer和精灵类CCSprite等。这些类都是构成游戏画面的基本元素。 但是游戏不仅是由静态画面构成的,更多时候,游戏是动态效果的呈现,所以动作、特效和动画是游戏区别于应用的特点,又是决定游戏质量的关键一环。 因此,决定一个二维游戏引擎的好坏的重要因素是引擎对动作、特效和动画的支持程度。2019/3/8xxxxxxxxxx2 Cocos2D-x的动作类2019/3/8xxxxxxxxxx3Cocos2D-x的动作类CCAction并不是一个在屏幕中显示的对象,动作必须要依托于CCNode类及它的子类的实例才能发挥作用。C0C0S2D-x的动作包括位置移动、跳跃,甚至是对象颜色的渐变。CCAction类继承于对象类CCObject,有三个子类:有限时间动作、跟随、移动速度,其中有限时间动作分为瞬时动作(CCActionlnstant)和延时动作(CCActionlnterval)。动作类2019/3/8xxxxxxxxxx3Cocos2D-CCAction的主要函数2019/3/8xxxxxxxxxx4CCAction的主要函数2019/3/8xxxxxxxx2019/3/8xxxxxxxxxx5CCAction的子类CCFiniteTimeAction分为瞬时动作(CCActionlnstant)和延时动作bCCActionlnterval)2019/3/8xxxxxxxxxx5CCAction的子类移动动作2019/3/8xxxxxxxxxx6VoidActionMove::onEnter(){ActionsDemo::onEnter();centerSprites(3);CCSizes=CCDirector::sharedDirector()->getWinSize();CCActionlnterval*actionTo=CCMoveTo::create(2,CCPointMake(s.width-40,s.height-40));CCActionlnterval*actionBy=CCMoveBy::create(2,CCPointMake(80,80));CCActionlnterval*actionByBack=actionBy->reverse;);_tamara->runAction(actionTo);_grossini->runAction(CCSequence::create(actionBy,actionByBack,NULL));_kathia->runAction(CCMoveTo::create(1,CCPointMake(40,40)));}以上分别定义了CCMoveTo和CCMoveBy的实例。之前已经说过CCMoveBy是MoveTo的子类,CCMoveTo是移动到目标位置,而CCMoveB>.是次目前位置的基础上移之到目标位置。 创建函数create的第一个参数是时间,第二个参数是位置对象。动作调用reverse函数会返回另外一个动作,使这个动作倒置,而精灵类实例在调用runAction函数时也会有不同,m_grossini精灵使用的就是动作序列CCSequence。CCSequence动作序列的定义由多个动作构成,create函数中以NULL参数作结尾,效果是作为参数传入的动作会颐序执行。移动动作2019/3/8xxxxxxxxxx6VoidA缩放动作2019/3/8xxxxxxxxxx7VoidActionScale::onEnter(){ActionsDemo::onEnter();centerSprites(3);CCActionlnterval*actionTo=CCScaleTo::create(2.Of,0.5f);CCActionlnterval*actionBy=CCScaleBy::create(2.Of/l.Of,lO.Of);CCActionlnterval*actionBy2=CCScaleBy::create(2.Of,5.Of,l.Of};m_grossini->runAction(actionTo);m_tamara->runAction(CCSequence::create(actionBy,actionBy->reverse(),NULL));m_kathia->runAction(CCSequence::create(actionBy2,actionBy2->reverse(),NULL));}以上分别定义了CCScaleTo和CCScaleBy的实例。之前已经说过CCScaleBy是CCScaleTo的子类,CCScaleTo是缩放到相应比例,CCScaleBy是在目前基础上变化相应的缩放比例。create函数可以使用两个参数或者三个参数。两个参数的第一个参数是时间间隔,第二个参数是缩放比例。三个参数的第一个参数是时间间隔,第二个参数是x轴缩放比例,第三个参数是y轴缩放比例。缩放动作2019/3/8xxxxxxxxxx7VoidAc扭曲动作2019/3/8xxxxxxxxxx8VoidActionSkew::onEnter(){ActionsDemo::onEnter();centerSprites(3);CCActionlnterval*actionTo=CCSkewTo::create(2,37.2f,-37.2f);CCActionlnterval*actionToBack=CCSkewTo::create(2,0,0);CCActionlnterval*actionBy=CCSkewBy::create(2,O.Of,-90.Of);CCActionlnterval*actionBy2=CCSkewBy::create(2,45.Of,45.0f);CCActionlnterval*actionByBack=actionBy->reverse();m_tamara->runAction(CCSequence::create(actionTo,actionToBack,NULL));M_grossini->runAction(CCSequence::create(actionBy,actionByBack,NULL));m_kathia->runAction(CCSequence::create(actionBy2,actionBy2->reverse(),NULL));}以上分别定义了CCSkewTo和CCSkewBy是实例。之前已经说过CCSkewBy是CCSkewTo的子类。二者关系和之前类似,以By结尾的参数是相对于目前值的过程量,以To结尾的参数是绝对的参数,不管现有状态如何,直接设置为参数的这个值。三个参数的第一个参数是时间间隔,第二个参数是x轴扭曲参数,第三个参数是y轴扭曲参数。扭曲动作2019/3/8xxxxxxxxxx8VoidAc旋转动作2019/3/8xxxxxxxxxx9voidActionRotate::onEnter(){ActionsDemo::onEnter();centerSprites(3);CCActionlnterval*actionTo=CCRotateTo::create(2,45);CCActionlnterval*actionTo2=CCRotateTo::create(2,-45);CCActionlnterval*actionToO=CCRotateTo::create(2,0);m_tamara->runAction(CCSequence::create(actionTo,actionToO,NULL));CCActionlnterval*actionBy=CCRotateBy::create(2,360);CCActionlnterval*actionByBack=actionBy->reverse();M_grossini->runAction(CCSequence::create(actionBy,actionByBack,NULL));m_kathia->runAction(CCSequence::create(actionTo2,actionToO->copy()->autorelease(),NULL));以上分别定义了CCRotateTo和CCRotateBy的实例。之前已经说过CCRotateBy是CCRotateTo的子类,二者关系和之前类似。两个参数的第一个参数是时间间隔,第二个参数是旋转角度,这里的角度表示采用角度制。旋转动作2019/3/8xxxxxxxxxx9voidAct跳转动作2019/3/8xxxxxxxxxx10voidActionJump::onEnter()ActionsDemo::onEnter();centerSprites(3);CCActionlnterval*actionTo=CCJumpTo::create(2,CCPointMake(300,300),50,4);CCActionlnterval*actionBy=CCJumpBy::create(2,CCPointMake(300,0),50,4);CCActionlnterval*actionUp=CCJumpBy::create(2,CCPointMake(0,0),80,4);CCActionlnterval*actionByBack=actionBy->reverse();m_tamara->runAction(actionTo);m_grossini->runAction(CCSequence::create(actionBy,actionByBack,NULL));m_kathia->runAction(CCRepeatForever::create(actionUp));以上分别定义了CCJumpTo和CCJumpBy的实例。之前已经说过CCJumpTo是CCJumpBy的子类,二者关系和之前类似。四个参数的第一个参数是时间间隔,第二个参数CCJumpTo的是目标位置的绝对坐标,CCJumpBy的是相对于目前位置的相对坐标,第三个参数为跳跃高度,第四个参数是跳跃的次数。跳转动作2019/3/8xxxxxxxxxx10voidAc贝塞尔曲线动作2019/3/8xxxxxxxxxx11voidActionBezier::onEnter()ActionsDemo::onEnter();CCSizes=CCDirector::sharedDirector()->getWinSize();centerSprites(3);ccBezierConfigbezier;bezier.controlPoint_l=CCPointMake(0,s.height/2);bezier.controlPoint_2=CCPointMake(300,-s.height/2);bezier.endPosition=CCPointMake(300,100);CCActionlnterval*bezierForward=CCBezierBy::create(3,bezier);CCActionlnterval*bezierBack=bezierForward->reverse();CCAction*rep=CCRepeatForever::create((CCActionlnterval*)CCSequence::create(bezierForward,bezierBack,NULL));m_tamara->setPosition(CCPointMake(80,160));ccBezierConfigbezier2;bezier2.controlPoint_1=CCPointMake(100,s.height/2);bezier2.controlPoint_2=CCPointMake(200,-s.height/2);bezier2.endPosition=CCPointMake(240,160);CCActionlnterval*bezierTol=CCBezierTo::create(2,bezier2);m_kathia->setPosition(CCPointMake(400,160));CCActionlnterval*bezierTo2=CCBezierTo::create{2,bezier2);m_grossini->runAction(rep);m_tamara->runAction(bezierTo1);m__kathia->runAction(bezierTo2);贝塞尔曲线动作2019/3/8xxxxxxxxxx11voi2019/3/8xxxxxxxxxx12
ccBezierConfig的三个参数需要配置,前两个是控制点,最后一个是终点。其中终点在CCBezierTo和CCBezierBy两个类中的运行结果不同,依然是CCBezierTo的终点是绝对位置,而CCBezierBy是相对于目前位置的相对位置。控制点的设置分别控制在路径上的高峰和低谷的位置。如果走的路径与图中方向一致,苎两个控制点的纵坐标设置为一正一负。控制点纵坐标的正负决定是向下走还是向上绝对值决定移动的幅度。而横坐标是横坐标方向的移动,该值对于CCBezierBy是相对于目前位置的相对位置,于CCBezierTo的终点是绝对位置。如果需要图中曲线旋转90度的路径,就把两个控制点的横坐标分别设置为一正一负即可,然后交换x轴和y轴的要求
CCBezierTo和CCBezierBy都是贝塞尔曲线动作。create函数没有什么区别,都是两个参数,第一个参数依然是动作时间,第二个参数是贝塞尔曲线的配置系数。.贝塞尔曲线是应用于二维图形应用程序的数学曲线,每一个顶点都有两个控制点,用于控制该顶点两侧曲线的弧度2019/3/8xxxxxxxxxx12ccBez淡入淡出动作2019/3/8xxxxxxxxxx13VoidActionFade::onEnter(){ActionsDemo::onEnter();centerSprites(2);m_tamara->setOpacity(0);CCActionlnterval*actionl=CCFadeln::actionWithDuration(l.Of);CCActionlnterval*actionlBack=actionl->reverse();CCActionlnterval*action2=CCFadeOut::actionWithDuration(l.Of);CCActionlnterval*action2Back=action2->reverse();m_tamara->runAction(CCSequence::actions(actionl,actionlBack,NULL));m_kathia->runAction(CCSequence::actions(action2,action2Back/NULL));}std::StringActionFade::subtitle(){return"Fadeln/FadeOut";}这里需要说明的是,淡入首先要将不透明度设置为0。淡入淡出动作2019/3/8xxxxxxxxxx13Void闪烁动作2019/3/8xxxxxxxxxx14voidActionBlink::onEnter() ActionsDemo::onEnter(); centerSprites(2); CCActionlnterval*actionl=CCBlink::actionWithDuration(2,10);CCActionlnterval*action2=CCBlink::actionWithDuration(2,5);m_tamara->runAction(actionl); m_kathia->runAction(action2); }闪烁动作2019/3/8xxxxxxxxxx14voidAc色值渐变动作2019/3/8xxxxxxxxxx15voidActionTint::onEnter(){ActionsDemo::onEnter();centerSprites(2);CCActionlnterval*actionl=CCTintTo::actionWithDuration(2,255,0,255);CCActionlnterval*action2=CCTintBy::actionWithDuration(2,-127,-255,-127);CCActionlnterval*action2Back=action2->reverse(); m_tamara->runAction(actionl);m__kathia->runAction(CCSequence::actions(action2,action2Back/NULL))}以上分别定义了CCTintTo和CCTintBy的实例,第一个参数是动作时间,后三个参数分别是颜色的R、G、B值。CCTintTo是直接设置色值,CCTintBy是在目前值上加上相应的值。色值渐变动作2019/3/8xxxxxxxxxx15void摄像机动作类2019/3/8xxxxxxxxxx16第3章介绍了摄像机类CCCamera,动作中也有一个摄像机动作类CCOrbitCamera,它是摄像机环绕屏幕中心旋转所形成的动作。voidActionOrbit::onEnter(){ActionsDemo::onEnter();centerSprites(3);CCActionlnterval*orbit3=CCOrbitCamera::create(2,1,0,0,180,90,0);CCFiniteTimeAction*action3=CCSequence::create(orbit3,orbit3->reverse(),NULL);m_kathia->runAction(CCRepeatForever::create((CCActionlnterval*)actionl));m_tamara->runAction(CCRepeatForever::create((CCActionlnterval*)action2));m_grossini->runAction(CCRepeatForever::create((CCActionlnterval*)action3));CCActionlnterval*move=CCMoveBy::create(3,CCPointMake(100,-100));CCActionlnterval*move_back=move->reverse();CCFiniteTimeAction*seq=CCSequence::create(move,move_back,NULL);CCAction*rfe=CCRepeatForever::create((CCActionlnterval*)seq);m_kathia->runAction(rfe);m_tamara->runAction((CCAction*)(rfe->copy()->autorelease()));m_grossini->runAction((CCAction*)(rfe->copy()->autorelease()));}摄像机动作类2019/3/8xxxxxxxxxx16第3章介摄像机动作类2019/3/8xxxxxxxxxx17旋转的坐标描述采用了球坐标。球坐标采用球面半径、与X轴夹角、与Z轴夹角这几个值来描述坐标点。摄像机动作类CCOrbitCamera的创建函数create有7个参数,第一个参数是动作时间,第二、三个参数是起始的坐标值中的半径和过程中的坐标值中的半径,第四、五个参数是起始的坐标值中的与z轴夹角和过程中的坐标值中的与z轴夹角,第六、七个参数是起始的坐标值中的与x轴夹角和过程中的坐标值中的与x轴夹角。注意在使用摄像机旋转时,如果正在旋转的这个节点后面还有其他节点的话,可能会出现旋转的节点只有一部分显示出来的这种情况。这时只需要关闭OpenGL的深度检测,获得导演类并调用setDepthTest设置为false即可,如下面的代码所示:CCDirector::sharedDirector()->setDepthTest(false)。摄像机动作类2019/3/8xxxxxxxxxx17基本样条动作2019/3/8xxxxxxxxxx18在游戏中,有时会希望使用一些非常规轨迹能描述的运动轨迹,希望只是“告诉”游戏对象几个离散的点,游戏对象就可以根据这些离散的点模拟出相应的路径。当然,有相应的公式模拟出这条曲线,那就是基本样条。Cocos2D-x中有沿基本样条路径移动动作类CCCardinalSplineTo和其子类实现这样的功能其中CCCardinalSplineTo和CCCardinalSplineBy的关系与之前以“To”和“By”结尾的类类似,CCCatmullRomTo和CCCatmullRomBy也是这样的。它们都是采用基本样条的公式;不同的是,CCCatmullRomTo和CCCatmullRomBy的拉力系数是0.5,而之前的CCCardinalSplineTo和CCCardinalSplineBy的拉力系数是可以自定义的。基本样条动作2019/3/8xxxxxxxxxx18在游戏中画基本样条路径2019/3/8xxxxxxxxxx19VoidActionCardinalSpline::onEnter(){ActionsDemo::onEnter();this->centerSprites(2);CCSizes=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*action=CCCardinalSplineBy::create(3,array,0);CCActionlnterval*reverse=action->reverse();CCFiniteTimeAction*seq=CCSequence::create(action,reverse,NULL);M_tamara->setPosition(ccp(50,50));M_tamara->runAction(seq);CCCardinalSplineBy*action2=CCCardinalSplineBy::create(3,array,1);CCActionlnterval*reverse2=action2->reverse();CCFiniteTimeAction*seq2=CCSequence::create(action2,reverse2,NULL);m_kathia->setPosition(ccp(s.width/2,50));m_kathia->runAction(seq2);M_pArray=array;array->retain();}首先定义一个点数组,把路径的点放入点数组中。创建基本样条动作时,3个参数分别是动作时间、点数组、拉力系数。
CCCardinalSplineTo和CCCardinalSplineBy的区别是,由于第一个是绝对的,第二个是相对的,第二个定义点数组的时候,第一个点最好设置为(0,0),否则起始点会被忽略掉。可以重写布景层的draw函数来把路径画出来。画基本样条路径2019/3/8xxxxxxxxxx19Voi画Catmull-Rom样条路径2019/3/8xxxxxxxxxx20voidActionCatmullRom::onEnter(){ActionsDemo::onEnter();this->centerSprites(2);CCSizes=CCDirector::sharedDirector()->getWinSize();m_tamara->setPosition(ccp(50,50));CCPointArray*array=CCPointArray::create(20);array->addControlPoint(ccp(0,0));array->addControlPoint(ccp(80,80));array->addControlPoint(ccp(s.width-80,80));array->addControlPoint(ccp(s.width-80,s.height-80));array->addControlPoint(ccp(80,s.height-80));array->addControlPoint(ccp(80,80));array->addControlPoint(ccp(s.width/2,s.height/2));CCCatmullRomBy*action=CCCatmullRomBy::create(3,array);CCFiniteTimeAction*reverse=action->reverse();CCFiniteTimeAction*seq=CCSequence::create(action,reverse,NULL);m_tamara->runAction(seq);CCPointArray*array2=CCPointArray:create(20);array2->addControlPoint(ccp(s.width/2,30));array2->addControlPoint(ccp(s.width-80,30));array2->addControlPoint(ccp(s.width-80,s.height-80));array2->addControlPoint(ccp(s.width/2,s.height-80));array2->addControlPoint(ccp(s.width/2,30));CCCatmullRomTo*action2=CCCatmullRomTo::create(3,array2);CCFiniteTimeAction*reverse2=action2->reverse();CCFiniteTimeAction*seq2=CCSequence::create(action2,reverse2,NULL);m_kathia->runAction(seq2);m__pArrayl=array;m_pArrayl->retain();m_pArray2=array2;m_pArray2->retain();CCCatmullRomTo和CCCatmullRomBy的用法和之前的那组类的用法一样,只是不需要第三个拉力系数参数。它们的区别和之前的也是一样的,也可以重写布景层的draw函数来把路径画出来。画Catmull-Rom样条路径2019/3/8xxxxxx缓冲动作2019/3/8xxxxxxxxxx21在实现运动中,常常需要实现一些加速度或者减速度的效果。Cocos2D-x引擎为我们提供了相应的实现接口,这样就不用再用原来的公式计算方法来实现加减速度的效果。Ease系列的方法改变了运动的速度,但是并没有改变总体时间。如果整个动作持续5s,那么整个时间仍然会持续5s。这些动作可以分成三类。□Inactions:action(开始的时候加速) □Outactions:action(结束的时候加速)□InOutactions:action(开始和结束的时候加速)CCActionEase有很多子类,根据不同的缓冲公式来模拟加减速过程。缓冲动作的具体内容如下。1)指数缓冲:分别为EaseExponentialln、EaseExponentialOut、EaseExponentiallnOut。2)赛因缓冲:分别为EaseSineIn、EaseSineOut、EaseSineInOut。3)跳跃缓冲:分别为EaseBounceln、EaseBounceOut、EaseBouncelnOut。4)弹性缓冲:分别为EaseElasticIn、EaseElasticOut、EaseElasticInOut。5)回震缓冲:分别为EaseBackln、EaseBackOut、EaseBacklnOut。以上介绍的5种缓冲,加上基本的缓冲动作,一共6种缓冲动作,其定义如代码清单4-15所示。缓冲动作2019/3/8xxxxxxxxxx21在实现运动中缓冲动作2019/3/8xxxxxxxxxx22//基本缓冲动作CCEaseln::create((CCActionlnterval*)(move->copy()->autorelease()),2.5f);CCEaseOut::create((CCActionlnterval*)(move->copy()->autorelease()),2.5f);CCEaselnOut::create((CCActionlnterval*)(move->copy()->autorelease()),0.65f);//指数缓冲动作CCEaseExponentialln::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseExponentialOut::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseExponentiallnOut::create((CCActionlnterval*)(move->copy()->autorelease()));//赛因缓冲动作CCEaseSineln::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseSineOut::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseSinelnOut::create((CCActionlnterval*)(move->copy()->autorelease()));缓冲动作2019/3/8xxxxxxxxxx22//基本缓冲缓冲动作2019/3/8xxxxxxxxxx23//跳跃缓冲动作CCEaseBounceln::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseBounceOut::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseBouncelnOut::create((CCActionlnterval*)(move->copy()->autorelease()));//弹性缓冲动作CCEaseElasticIn::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseElasticOut::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseElasticInOut::create((CCActionlnterval*)(move->copy()->autorelease()),0.3f);//缓冲动作CCEaseBackln::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseBackOut::create((CCActionlnterval*)(move->copy()->autorelease()));CCEaseBacklnOut::create((CCActionlnterval*)(move->copy()->autorelease()));第一个参数是要缓冲的动作,其中基本缓冲动作需要第二个参数是速率,弹性缓冲动作需要第二个参数是震动的周期,默认值为0.3。缓冲动作2019/3/8xxxxxxxxxx23//跳跃缓冲组合动作2019/3/8xxxxxxxxxx24在游戏中,游戏对象有时不是执行一个动作,有时是多个动作的动作序列,有时是同时执行几个动作序列。这时候就需要使用组合动作的方式将多个动作或按序列组织,或合成在一起。1.CCSequence
定义一个动作序列,可以使用动作的CCArray数组;也可以把所有的动作作为参数传入create函数中,最后结尾参数使用NULL(空值)即可;还可以把两个有限时间动作按顺序传人create函数中。CCFiniteTimeAction*seq2=CCSequence::create(action2#reverse2,NULL);m_kathia->runAction(seq2);2.CCSpawn CCSpawn动作是使被合成的动作同时进行。它的定义方法和动作序列一致CCAction*action=CCSpawn::create(CCJumpBy::create(2,CCPointMake(300,0),50,4),CCRotateBy::create(2,720),NULL);m_grossini->runAction(action);组合动作2019/3/8xxxxxxxxxx24在游戏中,游组合动作2019/3/8xxxxxxxxxx253.CCRepeat和CCRepeatForever
除了以上两个可以实现多个动作的类外,还有可以使一个动作重复播放的类,那就是CCRepeat和CCRepeatForever。二者都可以使动作重复进行,不同之处就是CCRepeat可以在第二个参数中定义重复次数,而CCRepeatForever是一直重复的。CCActionInterval*rep2=CCRepeat::create((CCFiniteTimeAction*)(seq->copy()->autorelease()),10);m_kathia->runAction(rep2);CCAction*rep2=CCRepeatForever::create((CCActionlnterval*)(seq->copy()->autorelease()));m_kathia->runAction(rep2);组合动作2019/3/8xxxxxxxxxx253.CCRe跟随动作2019/3/8xxxxxxxxxx26跟随动作CCFollow是一个节点跟随另外一个节点的动作。voidActionFollow::onEnter(){ActionsDemo::onEnter();centerSprites(1);CCSizes=CCDirector::sharedDirector()->getWinSize();m_grossini->setPosition(CCPointMake(-200,s.height/2));CCActionlnterval*move=CCMoveBy::create(2,CCPointMake(s.width*3,0));CCActionlnterval*move_back=move->reverse();CCFiniteTimeAction*seq =CCSequence::create(move,move_back,null);CCAction*rep =CCRepeatForever::create((CCActionlnterval*)seq);m_grossini->runAction(rep);this->runAction(CCFollow::create(m_grossinifCCRectMake(0,0,s.width*2-100,s.height)));}跟随动作2019/3/8xxxxxxxxxx26跟随动作CC可调整动作速度2019/3/8xxxxxxxxxx27可调整速度动作CCSpeed不是一个独立的动作,可以把它理解为是对目前动作的一个“包装”,经过这个“包装”以后,就可以实现“慢动作”和“快进”的效果。使用CCSpeed来处理很方便VoidSpeedTest::onEnter(){EaseSpriteDemo::onEnter();CCSizes=CCDirector::sharedDirector()->getWinSize();CCActionlnterval*junpl=CCJunpBy::create(4#CCPointMake(-s.width+80,0),100,4);CCActionlnterval*jump2=jumpl->reverse();CCActionlnterval*rotl=CCRotateBy::create(4,360*2);CCActionlnterval*rot2=rotl->reverse();CCFiniteTimeAction*seq3_l=CCSequence::create(jump2,jumpl,NULL);CCFiniteTimeAction*seq3_2=CCSequence::create(rotl,rot2,NULL);CCFiniteTimeAction*spawn=CCSpawn::create(seq3_1,seq3_2,NULL);CCSpeed*action=CCSpeed::create(CCRepeatForever::create((CCActionlnterva1*)spawn).1.Of);action->setTag(kTagActionl);CCAction*action2=(CCAction*)(action->copy()->autorelease());CCAction*action3=(CCAction*)(action->copy()->autorelease());action2->setTag(kTagActionl);action3->setTag(kTagActionl);m_grossini->runAction(action2);m_tamara->runAction(action3);m_kathia->runAction(action);this->schedule(schedule_selector(SpeedTest::altertime),1.Of);}voidSpeedTest::altertime(floatdt){CCSpeed*actionl=(CCSpeed*)(m_grossini->getActionByTag(kTagActionl))CCSpeed*action2=(CCSpeed*)(m_tamara->getActionByTag(kTagActionl));CCSpeed*action3=(CCSpeed*)(m_kathia->getActionByTag(kTagActionl));actionl->setSpeed(CCRAND0M_0_1()*2);action2->setSpeed(CCRAND0M_0_1()*2);action3->setSpeed(CCRAND0M_0_1()*2);}在onEnter函数中,就是定义普通动作,并使用schedule,使得每1.0s调用altertime函数。在altertime函数中,通过getActionByTag获得动作,把它们视作CCSpeed,并使用setSpeed设置速度:设置1,是原速度;大于1,速度加快,小于1,速度减慢。可调整动作速度2019/3/8xxxxxxxxxx27可调整2019/3/8xxxxxxxxxx28动作延时CCDelayTime就是动作延后一段固定的时间,可以把它理解为一个“空动作”,只有时间,没有任何动作。voidActionDelayTime::onEnter(){ActionsDemo::onEnter();alignSpritesLeft(1);CCActionlnterval*move=CCMoveBy::create(1,CCPointMake(150,0));CCFiniteTimeAction*action=CCSequence::create(move,CCDelayTime::create(2),move,NULL);m_grossini->runAction(action);}2019/3/8xxxxxxxxxx28动作延时CCDela改变动作执行对象2019/3/8xxxxxxxxxx29CCTargetedAction类可以改变动作的执行对象。一般默认的动作执行对象是调用mnAction的对象:有时候要自定义动作执行对象,这时候需要使用CCTargetedAction。VoidActionTargeted::onEnter(){ActionsDemo::onEnter();centerSprites(2);CCJumpBy*jumpl=CCJumpBy::create(2,CCPointZero,100,3);CCJumpBy*jump2=(CCJumpBy*)jumpl->copy()->autorelease();CCRotateBy*rotl=CCRotateBy::create(1,360);CCRotateBy*rot2=(CCRotateBy*)rotl->copy()->autorelease0;CCTargetedAction*tl=CCTargetedAction::create(m_cathia,jump2);CCTargetedAction*t2=CCTargetedAction::create(m_cathia,rot2);CCSequence*seq=(CCSequence*)CCSequence::create(junpl,tl,rotl,t2,NULL);CCRepeatForever*always=CCRepeatForever::create(seq);m_tamara->runAction(a1ways);}它的定义使用create函数,第一个参数是执行动作的节点,第二个参数是须执行的动作。这样一来,虽然调用runAction的是m_tamara,但是执行到tl和t2时,执行动作的节点变为了m_kathia。改变动作执行对象2019/3/8xxxxxxxxxx29CC函数回调动作2019/3/8xxxxxxxxxx30有时候某些动作完成后,需要执行一些数据上的处理,比如攻击一个敌人,需要处理加减血等。其中CCCallFunc就是回调函数,该回调的函数不含参数。CCCallFunc的回调函数以CCNode对象和数据作为参数。“N”就是“Node”的意思;“D”就是“Data”的意思,数据可以是任何类型的。CCCallFuncO是以CCObject作为回调函数参数的,“0”就是“Object”的意思。voidActionSequence2::onEnter(){ActionsDemo::onEnter()alignSpritesLeft(1);m_grossini->setVisible(false);CCFiniteTimeAction*action=CCSequence::create(CCPlace::create(CCPointMake(200,200)),CCShow::create(),CCMoveBy::create(1,CCPointMake(100,0)),CCCallFunc::create(this,callfunc_selector(ActionSequence2::callbackl)),CCCallFuncN::create(this,califuncN_selector(ActionSequence2::callback2)),CCCallFuncND::create(this.callfuncNDselector(ActionSequence2::callback3),(void*)Oxbebabeba),NULL);m_grossini->runAction(action);}函数回调动作2019/3/8xxxxxxxxxx30有时候某函数回调动作2019/3/8xxxxxxxxxx31voidActionSequence2::callbackl(){CCSizes=CCDirector::sharedDirector()->getWinSize();CCLabelTTF*label=CCLabelTTF::create("callback1called","MarkerFelt",16);label->setPosition(CCPointMake(s.width/4*l,s.height/2));addChild(label);}voidActionSequence2::callback2(CCNode*sender){CCSizes=CCDirector::sharedDirector()->getWinSize();CCLabelTTF*label=CCLabelTTF::create(11callback2called","MarkerFelt",16);label->setPosition(CCPointMake(s.width/4*2,s.height/2));addChild(label);}voidActionSequence2::callback3(CCNode*sender,void*data){CCSizes=CCDirector::sharedDirector()->getWinSize();CCLabelTTF*label=CCLabelTTF::create("callback3called","MarkerFelt",16);label->setPosition(CCPointMake(s.width/4*3.s.height/2));addChild(label);}可以看到CCCallFunc、CCCallFuncN和CCCallFuncND的定义,第一个参数就是拥有回调函数的对象,第二个参数通过相应选择器获得函数名称,CCCallFuncND的最后一个参数就是数据对象,底下分别是三个函数的定义。函数回调动作2019/3/8xxxxxxxxxx31可以看到过程动作2019/3/8xxxxxxxxxx32很多时候,在进入游戏之前都需要载人动作,这时候需要一些动作用来实现载入时的动画。Cocos2D-x提供了CCProgressTo和CCProgressFromTo来实现这个动画,但是执行这种动作的节点是CCProgressTimer。voidSpriteProgressToRadial:ronEnter(){SpriteDemo::onEnter();CCSizes=CCDirector::sharedDirector()->getWinSize();CCProgressTo*tol=CCProgressTo::create(2,100);CCProgressTo*to2=CCProgressTocreate(2,100);CCProgressTimer*left=CCProgressTimer::create(CCSprite::create(s_pPathSisterl));left->setType(kCCProgressTimerTypeRadial);addChild(left);left->setPosition:(CCPointMake(100,s.height/2));left->runAction(CCRepeatForever::create(tol));CCProgressTimer*right=CCProgressTimer::create(CCSprite::create(s_pPathBlock));right->setType(kCCProgressTimerTypeRadial);right->setReverseProgress(true);addChild(right);right->setPosition(CCPointMake(s.width-100,s.height/2));right->runAction(CCRepeatForever::create(to2));}首先是定义CCProgressTo或CCProgressFromTo。第一个参数都是动作时间;CCProgressTo的第二个参数是结束时图片显示的百分比,CCProgressFromTo的第二个参数是开始时图片显不的百分比;CCProgressFromTo的第三个参数是结束时图片显示的百分比。
接下来是定义CCProgressTimer,传人精灵对象来定义,通过调用setType函数来设置动画的类型:kCCProgressTimerTypeRadial是圆形扫描的动画,kCCProgressTimerTypeBar是直线扫描的动画。调用setReverseProgress函数设置正反的方向。kCCProgressTimerTypeBar类型的通过setBarChangeRate设置水平和竖直的变化量。
通过调用setxxxxxoint函数设置开始点,(0,0)为左上,(1,1)为右下,其他点可以用浮点数来表示。过程动作2019/3/8xxxxxxxxxx32很多时候,在动作管理类2019/3/8xxxxxxxxxx33动作管理类CCActionManager是一个管理所有动作的单例,工作原理是:当CCNode汉行runAction时,该函数会把动作通过动作管理类的addAction函数将对象传递给JCActionManager的单例,该实例再把这个动作添加到自己的动作序列中。 动作管理单例通过定时刷新自己的update方法,在这个方法中去调用行为序列中每个动作的step(暂停的行为不会update),这些step方法再根据自身的完成进度去update或是结東行为。 实际上是由动作管理单例驱动的每个动作去更新自己的逻辑,而runAction方法只是将行为对象添加进CCActionManager的待执行队列。当节点被清除或是行为结束时,动作管理类会自动将动作从队列中删除,不需要程序员的管理。 一般情况下,不需要使用这个单例来管理动作,可以使用CCNode类的stopAction、stopActionByTag和stopAllActions等函数来管理,但是有两种情况需要使用CCActionManager类单例:□动作的执行者不是同一个节点。□需要暂停/重启活动时。动作管理类2019/3/8xxxxxxxxxx33动作管理类动作管理类的主要函数2019/3/8xxxxxxxxxx34动作管理类的主要函数2019/3/8xxxxxxxxxx342019/3/8xxxxxxxxxx35不要轻易使用动作管理类,除非是不同动作目标和需要暂停/重启动作。这里的例子就是需要暂停/重启动作时使用VoidResumeTest::onEnter(){ActionManagerTest::onEnter();CCSizes=CCDirector::sharedDirector()->getWinSize();CCLabelTTF*1=CCLabelTTF::create("Grossinionlyrotate/scalein3seconds","Thonburi",16);addChild(1);l->setPosition(CCPointMake(s.width/2,245));CCSprite*pGrossini=CCSprite::create(s_pPathGrossini);addChild(pGrossini,0,kTagGrossini);pGrossini->setPosition(CCPointMake(s.width/2,s.height/2));pGrossini->runAction(CCScaleBy::create(2,2));CCDirector*pDirector=CCDirector::sharedDirector();pDirector->getActionManager()->pauseTarget(pGrossini);pGrossini->runAction(CCRotateBy::create(2,360));this->schedule(schedule—selector(ResumeTest::resumeGrossini).3.Of);}VoidResumeTest::resumeGrossini(floattime){this->unschedule(schedule—selector(ResumeTest::resumeGrossini));CCNode*pGrossini=getChildByTag(kTagGrossini);CCDirector*pDirector=CCDirector::sharedDirector();pDirector->getActionManager()->resumeTarget(pGrossini);}2019/3/8xxxxxxxxxx35不要轻易使用动作管理网格动作2019/3/8xxxxxxxxxx36网格动作类似于特效,可以实现翻转、抖动、震荡、水波纹等效果:基于网格实现,首先来认识网格Cocos2D-x中,网格类的基类CCGridBase有两个子类,即CCGrid3D和CCTiledGrid3D。这两个类的共同点是,网格的每个子块都可以分离出来。网格没有什么直接应用的场合,只要明白CCGrid3D和CCTiledGrid3D,并且网格动作是基于网格的即可。运行网格动作的节点好像被分成了大小相同的很多矩形,通过这些矩形的动作形成整体动作,这些矩形就好像形成了一个矩阵。16x12的网格将会运行得非常快,但是效果并不是非常好。32x24的网格看起来会非常棒,但是在有些时候运行起来不会太快。使用网格之前需要取消OpenGL的深度检测,调用如下语句:
CCDirector::sharedDirector()->setDepthTest(false)。网格动作的使用和普通动作一样,可以使用mnAction来运行动作网格动作2019/3/8xxxxxxxxxx36网格动作类似清除网格2019/3/8xxxxxxxxxx37在使用网格时,网格动作结束后需要把网格清空voidTextLayer::checkAnim(floatdt){CCNode*s2=getChildByTag(kTagBackground);if(s2->number0fRunningActions()==0ScScs2->getGrid()!=NULL)s2->setGrid(NULL);}这段代码首先获得父节点,然后检测父节点是否还有动作。如果没有并且网格不为空,则调用setGrid函数并传入空参数(NULL)便可清空网格。使用schedule—直检测调用该函数就可以实现清空无动作的节点网格。清除网格2019/3/8xxxxxxxxxx37在使用网格时动画2019/3/8xxxxxxxxxx38之前已经介绍过一些方法让你的节点“动”起来,Cocos2D-x中还有一种动作,就是动画类CCAnimate。要实现CCAnimate,还需要定义CCAnimation等类。我们来看关于动画的这些类。CCAnimationCache类是一个单例,用于缓存所有的动画和动画帧CCAnimationCache::sharedAnimationCache()->addAnimation(animation,"dance");CCAnimationCache*animCache=CCAnimationCache::sharedAnimationCache();CCAnimation*normal=animCache->animationByName("dance11);首先通过sharedAnimationCache函数可以获得动画缓存CCAnimationCache,通过addAnimation函数往动画缓存中加人动画,并给动画命名,然后通过动画缓存调用animationByName函数传人动画名就可以获得相应的动画。动画2019/3/8xxxxxxxxxx38之前已经介绍过一动画2019/3/8xxxxxxxxxx39和精灵巾贞CCSpriteFrame类似,动画帧CCAnimationFrame是单张的图片,也可以通过精灵帧定义。CCSpriteFrame*frame=(CCSpriteFrame*)pObj;CCAnimationFrame*animFrame=newCCAnimationFrame();animFrame->initWithSpriteFrame(frame,1,NULL);这里initWithSpriteFrame函数就是通过精灵巾贞CCSpriteFrame初始化动園巾贞CCAni-=iationFrame的,第一个参数是精灵帧CCSpriteFrame,第二个参数是该动画帧的延迟时间有时动画的某一帧需要延迟,使用该参数定义就可以),最后一个参数是CCDictionary类型的信息。CCAnimation就是动画,储存一个动画动作需要的所有帧,可以通过帧的数组定义CCArray*animFrames=CCArray::create();chartmp[50];for(intj=0;j<14;j++){sprintf(tmp,"grossini_dance_%02d.png”,j+1);CCSpriteFrame*frame=cache->spriteFrameByName(tmp);animFrames->addObject(frame);}CCAnimation*animation=CCAnimation::create(animFramesf0.3f);首先定义一个精灵帧CCSpriteFrame的数组,然后定义一个动画CCAnimation;也可以隻用动画巾贞CCAnimationFrame来定义。动画2019/3/8xxxxxxxxxx39和精灵巾贞CCS动画2019/3/8xxxxxxxxxx40CCAnimate动画动作就是一个动作类。可以通过CCAnimation动画来定义CCAnimate动画动作sprite->runAction(CCRepeatForever::create(CCAnimate::create(animation)));动画2019/3/8xxxxxxxxxx40CCAnimat使用plist配置文件实现动画2019/3/8xxxxxxxxxx41在Mac系统的Cocoa等编程框架中,属性列表文件是一种用来存储串行化后的对象的文件。属性列表文件的扩展名为plist,因此通常被称为plist文件。plist文件通常用于储存用户设置,也可以用于存储捆绑的信息,该功能在旧式的Mac系统中是由资源分支提供的。CCSpriteFrameCache*frameCache=CCSpriteFrameCache::sharedSpriteFrameCache();frameCache->addSpriteFramesWithFile("animations/grossini.plist");frameCache->addSpriteFramesWithFile("animations/grossini_gray.plist");frameCache->addSpriteFramesWithFile("animations/grossini_blue.plist");CCAnimationCache::purgeSharedAnimationCache();CCAnimationCache*animCache=CCAnimationCache::sharedAnimationCache();animCache->addAnimationsWithFile("animations/animations.plist");使用plist配置文件实现动画2019/3/8xxxxxxx2019/3/8xxxxxxxxxx42<?xmlversion="1.0"encoding="utf-8”?><!DOCTYPEplistPUBLIC"-//Ap
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论