Cocos2dx—动作类Action

动作体系对于一款游戏的成功与否,有着非常重要的影响。下面就是对2dx中的动作进行相关简介。
先看关系图:
关系图

现在就对这些类进行简单的介绍,在后续的小节中还会进行详细的分析的。

  • Ref和Clonable:涉及的是内存管理问题;(后面的文章会提及)
  • Action:所有动作的父类,定义了公共的操作;
  • FiniteTimeAction:瞬时动作和延时动作的父类,可以定义动作的时间变化;
  • Follow:跟随节点的动作;
  • Speed:改变一个动作的时间,比如实现慢动作回放或者快进;
  • ActionInstant:瞬间完成动作,中间没有任何动画效果;
  • ActionInterval:动作会在指定的时间内完成,中间会有动画效果;
  • FlipX:X轴方向翻转;
  • MoveTo:移动动作;
  • ……
接下来结合代码讲解:
1. Action类的主要成员函数;
2. 瞬时动作:
    ActionInstant是瞬时动作类。瞬时动作表示瞬间完成动作,中间没有任何动画效果;ActionInstant的子类较多,下面就是讲解一个Hide(),其余的原理是一样的;瞬时动作是只能够立刻完成的动作,这类动作是在下一帧立刻完成的动作,如设定位置、设定缩放等。把它们包装成动作后,可以与其他动作类组合为复杂动作。(组合动作)瞬时动作,不像其他的动作一样有一定明显的变化过程,但是也增加了游戏的画面吸引力,瞬时动作包含:Hide()隐藏、Show()显示、ToggleViibility()切换可见性动作(意思是原来不可见的物体执行此动作后变成可见,原来可见的物体执行此动作后变成不可见)。FlipX()围绕X轴翻转、Place()创建一个重置位置的动作、RemoveSelf()删除自身动作对象......

<span style="font-size:12px;"> sprite->runAction(Hide::create());
 label->setString("使用Hide方法瞬时变化");
 break;</span>

3. 延时动作:

    1.  动作会在指定的时间内完成,中间会有动画效果。延时动作通过属性值的逐渐变化来实现动画效果。需要注意的是XXTo和XXBy的区别在于XXTo是表示最终值,而XXBy则表示向量-改变值。如下:

<span style="font-size:12px;"> sprite_01->runAction(MoveTo::create(2, vec(300, 300)));
 label->setString("使用MoveTO方法延时变化");
 break;
 
 sprite_02->runAction(MoveBy::create(2, vec(300, 300)));
 label->setString("使用MoveBy方法延时变化");
 break;</span>
    2.  自身变换相关的几个基本动作:RotateTo()、RotateBy()、SkewTo()、SkewBy()、ScaleBy()、ScaleTo()、Blink();

         自身颜色变化的一些基本动作:FadeOut()淡出、FadeIn()淡入、FadeTo()透明度变化的对象、TintTo()从当前色彩变化到指定色彩(目标值)、TintBy()从当前色彩变化到指定色彩(增量值)


    3. 贝塞尔曲线动作

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

       

<span style="font-size:12px;">cocos2d::ccBezierConfig bezier;
bezier.controlPoint_1 = Point(200, 300);
bezier.controlPoint_2 = Point(400, 400);
bezier.endPosition = Point(50, 200);</span>

4. 缓冲动作:

    在游戏中,很多时候会使用加速或者减速的动作效果。在2dx中已经为我们封装好了

   ActionEase类可以实现动作的速度由快到慢、速度随时间改变的匀速运动。该类包含5类运动:

  • 指数缓冲;
  • Sine缓冲;
  • 弹性缓冲;
  • 跳跃缓冲;
  • 回震缓冲。

    每类运动都包含3个不同时期的变换:In、Out和InOut。

  • In表示开始的时候加速;
  • Out表示结束的时候加速;
  • InOut表示开始和结束的时候加速。

上述5类运动分别对应以下的类:

  • 指数缓冲:EaseExponentialInEaseExponentialOutEaseExponentialInOut
  •     EaseExponentialIn表现的效果为速度越来越快;
  •       EaseExponentialOut表现的效果为速度越来越慢;
  •       EaseExponentialInOut表现的效果为中间速度非常快,两头速度较慢。

  • Sine缓冲:EaseSineInEaseSineOutEaseSineInOut
  • 弹性缓冲:EaseElasticInEaseElasticOutEaseElasticInOut
  • 跳跃缓冲:EaseBounceInEaseBounceOutEaseBounceInOut
  • 回震缓冲:EaseBackInEaseBackOutEaseBackInOut

案例:

#ifndef __Hello_o1__ActionScene__
#define __Hello_o1__ActionScene__

#include "cocos2d.h"

class ActionScene : public cocos2d::Layer
{
public:
    ActionScene();
    ~ActionScene();
    static cocos2d::Scene* createScene();
    virtual bool init();
    void menuCloseCallback(cocos2d::Ref* pSender);
    CREATE_FUNC(ActionScene);
    
public:
    void Apply(cocos2d::Ref* pSender);
    
public:
    cocos2d::Sprite* sprite;
    cocos2d::Sprite* sprite_01;
    cocos2d::Sprite* sprite_02;
    int actionIndex;
    cocos2d::LabelTTF* label;
    cocos2d::ccBezierConfig bezier1;         //创建一个贝塞尔曲线对象
    
    
};

#endif // __HELLOWORLD_SCENE_H__

#include "ActionScene.h"

USING_NS_CC;


ActionScene::ActionScene()
{
    actionIndex = 0;
}

ActionScene::~ActionScene()
{
    
}

Scene* ActionScene::createScene()
{
    auto scene = Scene::create();
    auto layer = ActionScene::create();
    scene->addChild(layer);
    return scene;
}

bool ActionScene::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    //创建层
    auto layer1 = LayerGradient::create(Color4B(150,0,0,255), Color4B(0,200,0,255), Point(0.7f, 0.7f));
   	this->addChild(layer1, 0);
    
    //添加主角
    sprite = Sprite::create("run_1.png");
    sprite->setPosition(Point(origin.x + 50, visibleSize.height/2 + origin.y - 60));
    this->addChild(sprite, 0, 0);
    
    //添加主角2
    sprite_01 = Sprite::create("run_1.png");
    sprite_01->setPosition(Point(origin.x + 50, visibleSize.height/2 + origin.y - 160));
    this->addChild(sprite_01, 0, 0);
    
    //添加主角3
    sprite_02 = Sprite::create("run_1.png");
    sprite_02->setPosition(Point(origin.x + 50, visibleSize.height/2 + origin.y + 40));
    this->addChild(sprite_02, 0, 0);
    
    //添加文本
    label = LabelTTF::create("\u6b64\u5904\u5c06\u663e\u793a\u52a8\u4f5c\u7684\u540d\u79f0", "Arial", 48);
    label->setPosition(Point(visibleSize.width/2, visibleSize.height-100));
    this->addChild(label);
    
    //添加按钮
    auto nextItem = MenuItemImage::create("right.png",
                                          "right.png",
                                          CC_CALLBACK_1(ActionScene::Apply, this));
    nextItem->setPosition(Point(origin.x + visibleSize.width - nextItem->getContentSize().width/2 ,origin.y + nextItem->getContentSize().height/2));
    
    auto nextMenu = Menu::create(nextItem, NULL);
    nextMenu->setPosition(Point::ZERO);
    this->addChild(nextMenu, 1);
    
    return true;
}

void ActionScene::Apply(cocos2d::Ref *pSender)
{
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    switch(actionIndex)
    {
            //隐藏
        case 0:
            label->setString("主角一使用Hide方法,主角二使用Show变化");
            sprite->runAction(Hide::create());
            sprite->runAction(Show::create());
            break;
            
            //出现
        case 1:
            label->setString("使用延时变化");
            sprite->runAction(MoveBy::create(2, Vec2(100, 0)));
            break;
            
            //绕X轴翻转
        case 2:
            label->setString("使用延时变化");
            bezier1.controlPoint_1 = Point(200, 100);
            bezier1.controlPoint_2 = Point(300, 250);
            bezier1.endPosition = Point(400, visibleSize.height/2 + origin.y - 60);
            sprite->runAction(BezierTo::create(2, bezier1));
            break;
            
            //绕Y轴翻转
        case 3:
        {
            label->setString("缓冲动作");
            auto action1 = MoveTo::create(2, Vec2(500, visibleSize.height/2 + origin.y - 60));
            auto action2 = MoveTo::create(2, Vec2(500, visibleSize.height/2 + origin.y - 160));
            auto action3 = MoveTo::create(2, Vec2(500, visibleSize.height/2 + origin.y + 40));
                                          
            sprite->runAction(EaseExponentialIn::create(action1));
            sprite_01->runAction(EaseExponentialOut::create(action2));
            sprite_02->runAction(EaseExponentialInOut::create(action3));
            break;
        }
            
            //切换可见性动作,就是不可见变得可见,可见变得不可见
        case 4:
            sprite->runAction(ToggleVisibility::create());
            label->setString("使用ToggleVisibility方法瞬时变化,切换可见性动作");
            break;
            
        case 5:
            sprite->runAction(ToggleVisibility::create());
            label->setString("使用ToggleVisibility方法瞬时变化,切换可见性动作");
            break;
            
            //重置位置动作
        case 6:
            sprite->runAction(Place::create(Point(200, 200)));
            label->setString("使用ToggleVisibility方法瞬时变化,重置位置动作");
            break;
            
             //删除对象
        case 7:
            sprite->runAction(RemoveSelf::create(true));
            label->setString("使用RemoveSelf方法瞬时变化");
            break;
            
    }
    actionIndex++;
    if(actionIndex == 8)
    {
        CCLOG("完成了");
        label->setString("结束了");
    }

}

运行结果:



        

       



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值