加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx-3.0(28) 动作类 Action

发布时间:2020-12-14 17:20:32 所属栏目:百科 来源:网络整理
导读:转自:http://blog.csdn.net/ac_huang/article/details/37972017 ~~~~我的生活,我的点点滴滴!! 我们简单看看Action的继承树状图: 动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作。动作作用于Node,因此每个动作都需要由Node对象执行

转自:http://blog.csdn.net/ac_huang/article/details/37972017


~~~~我的生活,我的点点滴滴!!


我们简单看看Action的继承树状图:


动作类(Action)是所有动作的基类,它创建的一个对象代表一个动作。动作作用于Node,因此每个动作都需要由Node对象执行。动作类(Action)作为基类,实际上是一个接口,动作类的大多数实现类都派生于有限时间动作类(FiniteTimeAction)。

但是在实际开发中我们通常用到两类动作-即时动作和持续动作,它们均继承于有限时间动作类。


一、即时动作

即时动作是能够立刻完成的动作,这类动作是在下一帧立刻完成的动作,如设定位置、设定缩放等。把它们包装成动作后,可以与其他动作类组合为复杂动作。


下面介绍一些常用即时动作


1、Place

该动作用于将节点放置到某个指定位置,其作用与修改节点的position属性相同。例如,将节点放到屏幕坐标(50,200)处的代码如下:

[cpp] view plain copy
  1. //在Point(50,200)处放一个node
  2. autoplaceAction=Place::create(Point(50,200));
  3. autosprite_1=Sprite::create("role1.png");
  4. //先添加
  5. this->addChild(sprite_1);
  6. //类似于setPosition功能
  7. sprite_1->runAction(placeAction);

相当于把这个精灵放到 (50,200)处。


2、FlipX和FlipY

这两个动作分别用于将精灵沿X轴和Y轴反向显示,其作用与设置精灵的FlipX和FlipY属性相同,将其封装成动作接口是为了便于与其他动作进行组合。

下面代码将一个精灵移动到一端后反向显示再进行移回的动作:

copy
//开启翻转
  • autoflipxAction=FlipX::create(true);
  • //移到Point(400,200),使用2s
  • automoveToActionGo=MoveTo::create(2.0f,Point(300,500));
  • //移到Point(50,50),248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> automoveToActionBack=MoveTo::create(2.0f,Point(50,50));
  • //Sequence是动作序列,以NULL表示参数传入结束
  • autoaction=Sequence::create(moveToActionGo,flipxAction,moveToActionBack,NULL);
  • autosprite_2=Sprite::create("role1.png");
  • this->addChild(sprite_2);
  • sprite_2->runAction(action);

  • 3、Show和Hide

    这两个动作分别用于显示和隐藏节点,其作用与设置节点的visible属性作用一样。例如:为了使精灵完成移动后隐藏起来。

    代码如下:

    copy
    //隐藏
  • autohideAction=Hide::create();
  • //显示
  • autoshowAction=Show::create();
  • //移到Point(100,100),使用1s
  • automoveToAction_1=MoveTo::create(1.0f,Point(100,100));
  • //移到Point(200,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> automoveToAction_2=MoveTo::create(1.0f,Point(200,0); background-color:inherit">//移到Point(300,300),248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> automoveToAction_3=MoveTo::create(1.0f,300));
  • //Sequence是动作序列,以NULL表示参数传入结束,移到_1后隐藏,移动_2后显示
  • autoaction=Sequence::create(moveToAction_1,hideAction,moveToAction_2,showAction,moveToAction_3,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> autosprite_3=Sprite::create("role1.png");
  • this->addChild(sprite_3);

  • 4、CallFunc与CallFuncN

    在cocos2dx 3.x版本后CallFunc系列动作只包括CallFunc、CallFuncN两个动作,CallFuncN需要添加一个node节点作为参数,传递给调用函数,他们都是用来在动作中进行方法调用,如在游戏中为了节约内存资源,

    我们可以在动作完成后调用相应函数清理内存等一系列操作。

    在2.x版本中的CallFuncND 和 CallFuncO 都可以通过 CallFunc 和 CallFuncN 进行实现。

    4.1CallFunc

    copy
    /**createstheactionwiththecallbackoftypestd::function<void()>.
  • Thisisthepreferredwaytocreatethecallback.
  • *Whenthisfuntionboundinjsorlua,theinputparamwillbechanged
  • *Injs:varcreate(varfunc,varthis,var[data])orvarcreate(varfunc)
  • *Inlua:localcreate(localfuncID)
  • */
  • staticCallFunc*create(conststd::function<void()>&func);

  • 看完声明后,我们看看几种CallFunc使用的不同写法

    copy
    //写法1
  • autoaction1=CallFunc::create(CC_CALLBACK_0(MyClass::callback_0,this));
  • autoaction2=CallFunc::create(CC_CALLBACK_0(MyClass::callback_1,153); background-color:inherit; font-weight:bold">this,additional_parameters));
  • //写法2
  • autoaction1=CallFunc::create(std::bind(&MyClass::callback_0,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> autoaction2=CallFunc::create(std::bind(&MyClass::callback_1,0); background-color:inherit">//lambdas表达式写法
  • autoaction1=CallFunc::create(
  • [&](){
  • autos=Director::getInstance()->getWinSize();
  • autolabel=LabelTTF::create("called:lambdacallback","MarkerFelt",16);
  • label->setPosition(ccp(s.width/4*1,s.height/2-40));
  • this->addChild(label);
  • });

  • 4.2 CallFuncN

    copy
    */
  • staticCallFuncN*create(void(Node*)>&func);

  • 注意到该回调动作带有一个Node*参数。

    假设回调函数:

    copy
    voidHelloWorld::callback(Node*sender,intnum);
    copy
    autoaction=Sequence::create(
  • MoveBy::create(2.0f,Point(150,0)),
  • CallFuncN::create(CC_CALLBACK_1(ActionCallFuncN::callback,153); background-color:inherit; font-weight:bold">this)),
  • NULL);
  • CallFuncN::create(std::bind(&ActionCallFuncN::callback,std::placeholders::_1)),0); background-color:inherit">//写法3
  • CallFuncN::create([&](Node*sender){
  • //回调动作代码
  • //dosomething
  • }),248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> NULL);

  • 受益于C++11的新语法特性 std::bind ; CallFuncND 和 CallFuncO 都可以通过 CallFunc 和 CallFuncN 进行实现。

    4.3、CallFuncND

    回调动作中带有一个Node*参数和一个void*参数。

    实现过程类似于 CallFuncN

    假设回调函数是 :

    void HelloWorld::doRemoveFromParentAndCleanup(Node* sender,bool cleanup);

    那么在回调动作中:

    CallFuncN::create( CC_CALLBACK_1(HelloWorld::doRemoveFromParentAndCleanup,this,true));

    这样就实现了等价于 CallFuncND 的回调动作。


    4.4、CallFuncO

    回调动作中带有一个Object*参数。

    实现过程类似于 CallFunc

    假设回调函数是: void HelloWorld::callback(Node* node,bool cleanup);

    那么在回调动作中:

    _grossini 为那个object对象

    CallFunc::create( CC_CALLBACK_0(HelloWorld::callback,_grossini,true)

    这样就实现了等价于 CallFuncO 的回调动作。


    二、持续动作

    属性变化动作:属性变化动作通过属性值的逐渐变化来实现动画效果。需要注意的是XXTo和XXBy的区别在于XXTo是表示最终值,而XXBy则表示向量-改变值。

    1、MoveTo和MoveBy


    用于使节点做直线运动,设置了动作时间和终点位置,在规定时间内会移动到终点,它们的初始化方法如下:
    [cpp] view plain copy
    1. //移动到Position的地方
    2. MoveTo::create(floatduration,constPoint&position);
    3. //移动的改变值为Position
    4. MoveBy::create(constPoint&position);

    很多时候他两的效果相似。


    2、JumpTo和JumpBy


    使节点以一定的轨迹跳跃到指定位置,JumpTo 是跳到Position位置,JumpBy 是跳起一段距离改变值为Position。

    先看看他们声明:
    copy
    JumpTo::create(constPoint&position,87); background-color:inherit; font-weight:bold">floatheight,87); background-color:inherit; font-weight:bold">intjumps);
  • JumpBy::create(intjumps);

  • 看下面的代码:
    copy
    //以抛物线方式跳到Point(400,最大高度200,跳2次跳到
  • autojumpTo=JumpTo::create(3.0f,Point(400,200,2);
  • autoactionTo=Sequence::create(jumpTo,NULL);
  • autosprite_5=Sprite::create("role1.png");
  • this->addChild(sprite_5);
  • sprite_5->setPosition(Point(50,50));
  • sprite_5->runAction(actionTo);
  • ////以抛物线方式跳动Point(400,最大高度200,跳4次跳到
  • autojumpBy=JumpBy::create(4.0f,4);
  • autoactionBy=Sequence::create(jumpBy,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> autosprite_6=Sprite::create("role1.png");
  • this->addChild(sprite_6);
  • sprite_6->setPosition(Point(50,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> sprite_6->runAction(actionBy);

  • 3、BezierTo和BezierBy


    使节点进行曲线运动,运动的轨迹由贝塞尔曲线描述。
    每条贝塞尔曲线都包含一个起点和一个终点。在一条曲线中,起点和终点各自包含一个控制点,而控制点到端点的连线称作控制线。
    控制点决定了曲线的形状,包含角度和长度两个参数。
    如下图:

    使用时,我们要先创建ccBezierConfig结构体,设置好终点endPosition以及两个两个控制点controlPoint_1和controlPoint_2后,再把结构体传入BezierTo或BezierBy的初始化方法中:
    copy
    //先声明一个贝尔结构体
  • ccBezierConfigbezier;
  • //设置目标位置
  • bezier.endPosition=Point(50,400);
  • //设置控制点1
  • bezier.controlPoint_1=Point(0,0);
  • //设置控制点2
  • bezier.controlPoint_2=Point(200,50);
  • autobezierTo=BezierTo::create(2.0f,bezier);
  • autosprite_7=Sprite::create("role1.png");
  • this->addChild(sprite_7);
  • sprite_7->runAction(bezierTo);

  • BezierBy基本与BezierTo一样写法

    4、ScaleTo和ScaleBy


    产生缩放效果,使节点的缩放系数随时间线性变化,对应初始化方法为:
    copy
    //缩放时间,缩放比例
  • ScaleTo::create(floats);
  • ScaleBy::create(floats);

  • 使用样例:
    copy
    //原地缩放
  • autoscaleTo=ScaleTo::create(4.0f,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> autoactionTo=Sequence::create(scaleTo,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> autosprite_8=Sprite::create("role1.png");
  • this->setPosition(Point(200,200));
  • this->addChild(sprite_8);
  • sprite_8->runAction(actionTo);


  • 5、RotateTo和RotateBy


    产生旋转效果,对应初始化方法为:
    copy
    RotateTo::create(floatdeltaAngle);
  • RotateBy::create(floatdeltaAngle);

  • 先让其缩放,然后在旋转:
    copy
    //原地缩放2倍
  • //原地旋转90度
  • autorotateTo=RotateTo::create(2.0f,90.0f);
  • sprite_8->runAction(actionTo);


  • 三、视觉特效动作

    下面这些类用来实现某些特定的视觉效果

    1、FadeIn,FadeOut和FateTo

    产生淡入淡出效果,和透明变化效果,对应的初始化方法为:
    copy
    //淡入
  • FadeIn::create(floatd);
  • //淡出
  • FadeOut::create(//一定时间内透明度变化
  • FadeTo::create(
  • 样例代码:
    copy
    //淡入3s完成
  • autofadeIn=FadeIn::create(3.0f);
  • //淡出4s完成
  • autofadeOut=FadeOut::create(4.0f);
  • //在5s里,透明度变化100
  • autofadeTo=FadeTo::create(5.0f,100);
  • sprite_8->runAction(actionTo);

  • 2、TintTo和TintBy


    设置色调(着色)变化,这个动作较少使用,初始化方法为:
    copy
    //RGB的取值范围都是0-255
  • TintTo::create( TintBy::create(
  • 样例:
    copy
    //着色
  • autotintTo=TintTo::create(2.0f,100,30);

  • 3、Blink


    使节点闪烁,其初始化方法为:
    copy
    //blinks为闪烁次数
  • Blink::create(intblinks);

  • 样例:
    copy
    //使其闪烁,2s内让闪烁10次
  • autoblink=Blink::create(2.0f,10);

  • 4、Animation


    以帧动画形式实现动画效果,以下代码用两种方法实现精灵帧动画效果
    第一种:
    copy
    //创建一个空精灵
  • autosprite_9=Sprite::create();
  • sprite_9->setPosition(Point(160,320));
  • this->addChild(sprite_9);
  • //创建一个空的动画
  • autoanimation=Animation::create();
  • charszName[50];
  • for(inti=1;i<=18;++i)
  • {
  • memset(szName,153); background-color:inherit; font-weight:bold">sizeof(szName));
  • sprintf(szName,"role%d.png",i);
  • animation->addSpriteFrameWithFile(szName);
  • }
  • //18个精灵3s播完
  • animation->setDelayPerUnit(3.0/18);
  • //设置播放完保存原始图片
  • animation->setRestoreOriginalFrame(true);
  • //注意这里是使用Animate,前面是Animation
  • autoanimationAction=Animate::create(animation);
  • //播放一遍后就会消失
  • sprite_9->runAction(Sequence::create(animationAction,animationAction->reverse(),NULL));

  • 第二种使用plist文件
    copy
    //文件创建动画
  • autocache=AnimationCache::getInstance();
  • cache->addAnimationsWithFile("animations.plist");
  • autoanimation2=cache->getAnimation("dance_1");
  • autoaction2=Animate::create(animation2);
  • sprite_9->runAction(Sequence::create(action2,action2->reverse(),NULL));

  • 动画创建后需要一个动画播放器来播放这些动画,这个播放器就是Animate

    四、复合动作

    通常在开发中我们需要将各种动作组合起来再让节点执行,复合动作的作用就是将各种动作组合在一起。而且,复合动作本身也是动作。因此可以作为一个普通动作嵌入到其他动作中。
    特别注意:Sequence动作不能嵌入其他复合动作内使用,DelayTime不属于复合动作,但是只能在复合动作内使用。

    1、DelayTime

    延时动作其实什么都不做,提供一段空白期,它只有一个初始化方法:
    copy
    DelayTime::create(floatd);
    d表示需要延时的时间。

    2、Repeat/RepeatForever

    反复执行某个动作,通常我们用Repeat和RepeatForever这两个方法执行:
    copy
    //循环次数
  • Repeat::create(FiniteTimeAction*action,unsignedinttimes);
  • //无限循环
  • RepeatForever::create(ActionInterval*action);
  • copy
    autorep=RepeatForever::create(Sequence::create(animationAction,NULL));
  • sprite_9->runAction(rep);

  • 3、Spawn


    使一批动作同时执行,他的两个初始化方法: copy
    Spawn::create(FiniteTimeAction*action1,...);
  • Spawn::create(constVector<FiniteTimeAction*>&arrayOfActions);
  • 看参数大概就知道是什么样子的了,这里就不给出样例代码了

    4、Sequence

    让各种动作有序执行,以下为它的两个初始化方法: copy
    Sequence::create(FiniteTimeAction*action1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> Sequence::create(constVector<FiniteTimeAction*>&arrayOfActions);
    上面使用他无数次了,往前回顾

    五、变速动作

    变速动作和复合动作类似,也是一种特殊的动作,它可以把任何动作按照改变后的速度执行。

    1、Speed


    用于线性的改变某个动作的速度,为了改变一个动作的速度,首先需要将目标动作包装到Speed动作中:
    copy
    autorepeat=RepeatForever::create(animation);
  • autospeed=Speed::create(repeat,0.5f);
  • sprite->run(speed);
  • 第二个参数为变速比例,设置为0.5f则速度为原来一半。


    2、ActionEase


    Speed虽然能改变动作的速度,但是只能按比例改变速度,ActionEase可以实现动作的速度由快到慢、速度随时间改变的匀速运动。
    该类包含5类运动:
    指数缓冲;
    Sine缓冲;
    弹性缓冲;
    跳跃缓冲;
    回震缓冲;
    每类运动都包含3个不同时期的变换:In、Out和InOut。
    由于这个实在太多了,我就只举一个例子
    InSine例子:
    copy
    autosineIn=EaseSineIn::create(action);
  • sprite->runAction(sineIn);


  • 到此就总结的差不多了,如果后续还有,继续补充~~~~~~

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读