cocos2d-x 提升篇 (16) actions动作讲解

总共加起来有53个测试用例,那就按照它的序号来吧。

基本上所有的子类都实现父类的虚函数onEnter进行具体的操作,所以要改代码的话也是改这一块。

1. ActionMove

void ActionMove::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto s = Director::getInstance()->getWinSize();

    auto actionTo = MoveTo::create(2, Vec2(s.width-40, s.height-40));
    auto actionBy = MoveBy::create(2, Vec2(80,80));
    auto actionByBack = actionBy->reverse();

    _tamara->runAction( actionTo);
    _grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));
    _kathia->runAction(MoveTo::create(1, Vec2(40,40)));
}

第一碰到就是centerSprites()函数,这个函数的实现很简单,创建了三个人物,

_tamara, _kathia, _grossini,这种蹩脚的命名方法竟然存在?以下划线开头命名一个变量,第一次见到。

通过传递数字确定几个人显示在桌面上,这里是3个。

其余的已经在基础系列讲过了。

第一个动作是从基本上是移动到右上角,

第二个动作是向上向右偏移(80, 80)个像素。

第三个动作是向左下角移动到(80, 80)这个地方。

有一个Sequence类创建一系列的动作,移动,最后以nullptr结尾。

void ActionsDemo::centerSprites(unsigned int numberOfSprites)
{
    auto s = Director::getInstance()->getWinSize();

    if( numberOfSprites == 0 )
    {
        _tamara->setVisible(false);
        _kathia->setVisible(false);
        _grossini->setVisible(false);
    } 
    else if ( numberOfSprites == 1 ) 
    {
        _tamara->setVisible(false);
        _kathia->setVisible(false);
        _grossini->setPosition(s.width/2, s.height/2);
    }
    else if( numberOfSprites == 2 ) 
    {        
        _kathia->setPosition(s.width/3, s.height/2);
        _tamara->setPosition(2*s.width/3, s.height/2);
        _grossini->setVisible(false);
    } 
    else if( numberOfSprites == 3 ) 
    {
        _grossini->setPosition(s.width/2, s.height/2);
        _tamara->setPosition(s.width/4, s.height/2);
        _kathia->setPosition(3 * s.width/4, s.height/2);
    }
}

2. ActionMove3D

可以看到和2D基本上一样,就是坐标有变化,Vec2变成Vec3,没有其余任何变化。

在图片显示上也没有什么变化,负值应该向内,

void ActionMove3D::onEnter()
{
    ActionsDemo::onEnter();
    
    centerSprites(3);
    
    auto s = Director::getInstance()->getWinSize();
    
    _tamara->setPosition3D(Vec3(s.width-40, s.height-40, 0));
    _kathia->setPosition3D(Vec3(40, 40, 0));
    
    auto actionTo = MoveTo::create(2, Vec3(s.width-40, s.height-40, -100));
    auto actionBy = MoveBy::create(2, Vec3(80, 80, -100));
    auto actionByBack = actionBy->reverse();
    
    _tamara->runAction(actionTo);
    _grossini->runAction(Sequence::create(actionBy, actionByBack, nullptr));
    _kathia->runAction(MoveTo::create(1, Vec3(40, 40, -100)));
}
3. ActionRotate

旋转create第一个参数表示时间,第二个表示角度。

void ActionRotate::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto actionTo = RotateTo::create( 2, 45);
    auto actionTo2 = RotateTo::create( 2, -45);
    auto actionTo0 = RotateTo::create(2 , 0);
    _tamara->runAction( Sequence::create(actionTo, actionTo0, nullptr));

    auto actionBy = RotateBy::create(2 ,  360);
    auto actionByBack = actionBy->reverse();
    _grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));

    _kathia->runAction( Sequence::create(actionTo2, actionTo0->clone(), nullptr));
}
4. ActionRotateBy3D‘

分别沿着x轴, y轴, z轴旋转360度,reverse是一个逆过程。

void ActionRotateBy3D::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto actionBy1 = RotateBy::create(4, Vec3(360, 0, 0));
    auto actionBy2 = RotateBy::create(4, Vec3(0, 360, 0));
    auto actionBy3 = RotateBy::create(4 ,Vec3(0, 0, 360));

    _tamara->runAction( Sequence::create(actionBy1, actionBy1->reverse(), nullptr));
    _grossini->runAction( Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
    _kathia->runAction( Sequence::create(actionBy3, actionBy3->reverse(), nullptr));
}

5. ActionScale

缩放,第二个参数是x轴的倍数,第三个参数是y轴的参数。

void ActionScale::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto actionTo = ScaleTo::create(2.0f, 0.5f);
    auto actionBy = ScaleBy::create(2.0f, 1.0f, 10.0f);
    auto actionBy2 = ScaleBy::create(2.0f, 5.0f, 1.0f);

    _grossini->runAction( actionTo);
    _tamara->runAction( Sequence::create(actionBy, actionBy->reverse(), nullptr));
    _kathia->runAction( Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
}

中间的男士叫做grossini, 左手边叫做tamara, 右手边叫做kathia.


6. SkewTo

描述Skews a Node object to given angles by modifying it's skewX and skewY attributes

翻译过来是倾斜的意思。

 static SkewTo* create(float t, float sx, float sy);

倾斜一定的角度,沿着x或者是y轴。

画了一个简单的理解图,同时需要理解to 和by的区别。


void ActionSkew::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto actionTo = SkewTo::create(2, 37.2f, -37.2f);
    auto actionToBack = SkewTo::create(2, 0, 0);
    auto actionBy = SkewBy::create(2, 0.0f, -90.0f);
    auto actionBy2 = SkewBy::create(2, 45.0f, 45.0f);
    auto actionByBack = actionBy->reverse();

    _tamara->runAction(Sequence::create(actionTo, actionToBack, nullptr));
    _grossini->runAction(Sequence::create(actionBy, actionByBack, nullptr));

    _kathia->runAction(Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
}

7. ActionRotationalSkew

旋转的过程中倾斜,比较不好理解。

void ActionRotationalSkew::onEnter()
{
    ActionsDemo::onEnter();

    this->centerSprites(3);

    auto actionTo = RotateTo::create(2, 180, 180);
    auto actionToBack = RotateTo::create(2, 0, 0);
    auto actionBy = RotateBy::create(2, 0.0f, 360);
    auto actionByBack = actionBy->reverse();

    auto actionBy2 = RotateBy::create(2, 360, 0);
    auto actionBy2Back = actionBy2->reverse();

    _tamara->runAction( Sequence::create(actionBy, actionByBack, nullptr) );
    _grossini->runAction( Sequence::create(actionTo, actionToBack, nullptr) );
    _kathia->runAction( Sequence::create(actionBy2, actionBy2Back, nullptr) );
}

8. ActionRotationalSkewVSStandardSkew

真心搞不懂它们的区别在哪里。

以后有空需要用到再研究吧,现在还不是研究几何关系的时候。

9. Skew Rotate  Scale同时进行

    auto actionTo = SkewTo::create(2, 0.f, 2.f);
    auto rotateTo = RotateTo::create(2, 61.0f);
    auto actionScaleTo = ScaleTo::create(2, -0.44f, 0.47f);

    auto actionScaleToBack = ScaleTo::create(2, 1.0f, 1.0f);
    auto rotateToBack = RotateTo::create(2, 0);
    auto actionToBack = SkewTo::create(2, 0, 0);

    box->runAction(Sequence::create(actionTo, actionToBack, nullptr));
    box->runAction(Sequence::create(rotateTo, rotateToBack, nullptr));
    box->runAction(Sequence::create(actionScaleTo, actionScaleToBack, nullptr));

10. jump的几个参数

慢慢地跳到目的地

class CC_DLL JumpTo : public JumpBy
{
public:
    /** 
     * Creates the action.
     * @param duration Duration time, in seconds.
     * @param position The jumping destination position.
     * @param height The jumping height.
     * @param jumps The jumping times.
     * @return An autoreleased JumpTo object.
     */
    static JumpTo* create(float duration, const Vec2& position, float height, int jumps);
最后一个表示跳几次

void ActionJump::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    auto actionTo = JumpTo::create(2, Vec2(300,300), 50, 4);
    auto actionBy = JumpBy::create(2, Vec2(300,0), 50, 4);
    auto actionUp = JumpBy::create(2, Vec2(0,0), 80, 4);
    auto actionByBack = actionBy->reverse();

    _tamara->runAction( actionTo);
    _grossini->runAction( Sequence::create(actionBy, actionByBack, nullptr));
    _kathia->runAction( RepeatForever::create(actionUp));
}

11.  CardinalSplineBy 

这个比较不好理解,不好从字面上理解,使用array指定路径,人物会沿着这个路径行走,

tension这个参数不好理解。贴图说面,大概是tension为0时,曲线比较光滑,曲线为1时是方形的。

左边是tension为0的图。


void ActionCardinalSpline::onEnter()
{
    ActionsDemo::onEnter();
    
    this->centerSprites(2);
    
    auto s = Director::getInstance()->getWinSize();
    
    auto array = PointArray::create(20);
    
    array->addControlPoint(Vec2(0, 0));
    array->addControlPoint(Vec2(s.width/2-30, 0));
    array->addControlPoint(Vec2(s.width/2-30, s.height-80));
    array->addControlPoint(Vec2(0, s.height-80));
    array->addControlPoint(Vec2(0, 0));
    
    //
    // sprite 1 (By)
    //
    // Spline with no tension (tension==0)
    //
    
    auto action = CardinalSplineBy::create(3, array, 0);
    auto reverse = action->reverse();
    
    auto seq = Sequence::create(action, reverse, nullptr);
    
    _tamara->setPosition(50, 50);
    _tamara->runAction(seq);
    
    auto drawNode1 = DrawNode::create();
    drawNode1->setPosition(Vec2(50,50));
    drawNode1->drawCardinalSpline(array, 0, 100, Color4F(1.0, 0.0, 1.0, 1.0));
    this->addChild(drawNode1);
    
    //
    // sprite 2 (By)
    //
    // Spline with high tension (tension==1)
    //
    
    auto action2 = CardinalSplineBy::create(3, array, 1);
    auto reverse2 = action2->reverse();
    
    auto seq2 = Sequence::create(action2, reverse2, nullptr);
    
    _kathia->setPosition(s.width/2, 50);
    _kathia->runAction(seq2);
    
    auto drawNode2 = DrawNode::create();
    drawNode2->setPosition(Vec2(s.width/2, 50));
    drawNode2->drawCardinalSpline(array, 1, 100, Color4F(1.0, 0.0, 1.0, 1.0));
    this->addChild(drawNode2);
}

12. CatmullRomBy

可以看到是一种特殊的cardinal spline

 An action that moves the target with a CatmullRom curve by a certain distance.
 A Catmull Rom is a Cardinal Spline with a tension of 0.5.


13. BezierBy

@class BezierBy
 @brief An action that moves the target with a cubic Bezier curve by a certain distance.

14. blink

是闪烁的意思,第一个参数指定秒数,第二个参数是闪烁几次。

15. FadeIn/FadeOut

渐变消失或者出现,其中FadeIn是消失。

16. TintBy/TintTo

Tints a Node that implements the NodeRGB protocol from current tint to a custom one.

给图片蒙上了一层奇怪的颜色。

void ActionTint::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(2);

    auto action1 = TintTo::create(2, 255, 0, 255);
    auto action2 = TintBy::create(2, -127, -255, -127);
    auto action2Back = action2->reverse();

    _tamara->runAction( action1);
    _kathia->runAction( Sequence::create( action2, action2Back, nullptr));
}


基本上Action的使用很简单,使用相关的类,调用create,需要传递正确的参数,然后相关的实体调用runAction()方法。


17. File Animation / Manual animation

加载15张图片到szName中,然后把szName传递给animation的addSpriteFrameWithFile方法。

void ActionAnimate::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    //
    // Manual animation
    //
    auto animation = Animation::create();
    for( int i=1;i<15;i++)
    {
        char szName[100] = {0};
        sprintf(szName, "Images/grossini_dance_%02d.png", i);
        animation->addSpriteFrameWithFile(szName);
    }
    // should last 2.8 seconds. And there are 14 frames.
    animation->setDelayPerUnit(2.8f / 14.0f);
    animation->setRestoreOriginalFrame(true);

    auto action = Animate::create(animation);
    _grossini->runAction(Sequence::create(action, action->reverse(), nullptr));
    
    //
    // File animation
    //
    // With 2 loops and reverse
    auto cache = AnimationCache::getInstance();
    cache->addAnimationsWithFile("animations/animations-2.plist");
    auto animation2 = cache->getAnimation("dance_1");

    auto action2 = Animate::create(animation2);
    _tamara->runAction(Sequence::create(action2, action2->reverse(), nullptr));

    _frameDisplayedListener = EventListenerCustom::create(AnimationFrameDisplayedNotification, [](EventCustom * event){
        auto userData = static_cast<AnimationFrame::DisplayedEventInfo*>(event->getUserData());
        
         log("target %p with data %s", userData->target, Value(userData->userInfo).getDescription().c_str());
    });

后面的等以后需要再掌握吧。这样一个一个记忆效果不好。

ADD_TEST_CASE(ActionSequence);
    ADD_TEST_CASE(ActionSequence2);
    ADD_TEST_CASE(ActionSequence3);
    ADD_TEST_CASE(ActionRemoveSelf);
    ADD_TEST_CASE(ActionSpawn);
    ADD_TEST_CASE(ActionSpawn2);
    ADD_TEST_CASE(ActionReverse);
    ADD_TEST_CASE(ActionDelayTime);
    ADD_TEST_CASE(ActionRepeat);
    ADD_TEST_CASE(ActionRepeatForever);
    ADD_TEST_CASE(ActionRotateToRepeat);
    ADD_TEST_CASE(ActionCallFunction);
    ADD_TEST_CASE(ActionCallFuncN);
    ADD_TEST_CASE(ActionCallFuncND);
    ADD_TEST_CASE(ActionReverseSequence);
    ADD_TEST_CASE(ActionReverseSequence2);
    ADD_TEST_CASE(ActionOrbit);
    ADD_TEST_CASE(ActionFollow);
    ADD_TEST_CASE(ActionFollowWithOffset);
    ADD_TEST_CASE(ActionTargeted);
    ADD_TEST_CASE(ActionTargetedReverse);
    ADD_TEST_CASE(ActionMoveStacked);
    ADD_TEST_CASE(ActionMoveJumpStacked);
    ADD_TEST_CASE(ActionMoveBezierStacked);
    ADD_TEST_CASE(ActionCardinalSplineStacked);
    ADD_TEST_CASE(ActionCatmullRomStacked);
    ADD_TEST_CASE(PauseResumeActions);
    ADD_TEST_CASE(ActionResize);
    ADD_TEST_CASE(Issue1305);
    ADD_TEST_CASE(Issue1305_2);
    ADD_TEST_CASE(Issue1288);
    ADD_TEST_CASE(Issue1288_2);
    ADD_TEST_CASE(Issue1327);
    ADD_TEST_CASE(Issue1398);
    ADD_TEST_CASE(Issue2599)
    ADD_TEST_CASE(ActionFloatTest);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值