cocos2d-x中的动作细说

cocos2d-x中的动作细说,第1张

概述Action类如其名,它可以改变Node对象的属性,Action对象是随着时间改变Node的属性。任何一个以Node为基类的对象都有可执行的动作对象。例如,你可以在一个时间段内将Sprite精灵从一个位置移动到另一个位置。 如下为MoveTo和MoveBy两个动作的实例: 1 2 3 4 5 6 7 // Move sprite to position 50,10 in 2 seconds. au

Action类如其名,它可以改变Node对象的属性,Action对象是随着时间改变Node的属性。任何一个以Node为基类的对象都有可执行的动作对象。例如,你可以在一个时间段内将Sprite精灵从一个位置移动到另一个位置。

如下为MovetoMoveBy两个动作的实例:

1 2 3 4 5 6 7 // Move sprite to position 50,10 in 2 seconds. auto moveto = Moveto::create(2,Vec2(50,10)); mySprite1->runAction(moveto); // Move sprite 20 points to right in 2 seconds auto moveBy = MoveBy::create(2,Vec2(20,0)); mySprite2->runAction(moveto);
By和To的区别

或许你已经注意到了每个动作都有By和To两个状态。为什么呢?因为它们所执行的结果是不同的。By相当于这个节点是相对的。To是绝对的,意思是它并不考虑到这个节点的当前状态。让我们看一个具体的例子:

7 8 9 10 11 12 13 14 15
auto mySprite = Sprite::create( "mysprite.png" ); mySprite->setposition(Vec2(200,256)); // MoveBy - lets move the sprite by 500 on the x axis over 2 seconds // MoveBy is relative - since x = 200 + 200 move = x is Now 400 after the move auto moveBy = MoveBy::create(2,Vec2(500,mySprite->getpositionY())); // Moveto - lets move the new sprite to 300 x 256 over 2 seconds // Moveto is absolute - The sprite gets moved to 300 x 256 regardless of // where it is located Now. auto moveto = Moveto::create(2,Vec2(300,mySprite->getpositionY())); auto seq = Sequence::create(moveBy,delay,moveto,nullptr); mySprite->runAction(seq);

基本动作以及如何执行动作

基本动作通常是一个单一的动作,只完成一个目标。让我们看看几个例子:

移动(Move)

在规定的时间内移动Node的位置。

11
auto mySprite = Sprite::create( "mysprite.png" ); // Move a sprite to a specific location over 2 seconds. auto moveto = Moveto::create(2,0)); mySprite->runAction(moveto); // Move a sprite 50 pixels to the right,and 0 pixels to the top over 2 seconds. auto moveBy = MoveBy::create(2,0)); mySprite->runAction(moveBy);

旋转(Rotate)

在2秒内顺时针旋转Node

9
// Rotates a Node to the specific angle over 2 seconds auto rotateto = Rotateto::create(2.0f,40.0f); mySprite->runAction(rotateto); // Rotates a Node clockwise by 40 degree over 2 seconds auto rotateBy = RotateBy::create(2.0f,40.0f); mySprite->runAction(rotateBy);

缩放(Scale)

在两秒内将Node放大10倍

15 16 17
// Scale uniformly by 3x over 2 seconds auto scaleBy = ScaleBy::create(2.0f,3.0f); mySprite->runAction(scaleBy); // Scale X by 5 and Y by 3x over 2 seconds auto scaleBy = ScaleBy::create(2.0f,3.0f,3.0f); mySprite->runAction(scaleBy); // Scale to uniformly to 3x over 2 seconds auto scaleto = Scaleto::create(2.0f,3.0f); mySprite->runAction(scaleto); // Scale X to 5 and Y to 3x over 2 seconds auto scaleto = Scaleto::create(2.0f,3.0f); mySprite->runAction(scaleto);

淡入淡出

Node淡入

FadeIn修改透明度的值(0~255之间)。与之相反的动作是“淡出”

// fades in the sprite in 1 secondsauto fadeIn = FadeIn::create(1.0f);mySprite->runAction(fadeIn);// fades out the sprite in 2 secondsauto fadeOut = FadeOut::create(2.0f);mySprite->runAction(fadeOut);

色调(Tint)

Tint使节点的NodeRGB从当前值改变到用户设置值。

// Tints a node to the specifIEd RGB valuesauto tintTo = TintTo::create(2.0f,120.0f,232.0f,254.0f);mySprite->runAction(tintTo);// Tints a node BY the delta of the specifIEd RGB values.auto tintBy = TintBy::create(2.0f,254.0f);mySprite->runAction(tintBy);

动画(Animate)

通过Animate可以很容易地实现精灵的帧动画效果。只要简单的每隔一段时间替换_display frame_即可。如下例子:

@H_301_437@ 17 18 19 20 21 22 23 24 25
// Now lets animate the sprite we moved Vector<SpriteFrame*> animFrames; animFrames.reserve(12); animFrames.pushBack(SpriteFrame::create( "Blue_Front1.png" ,Rect(0,65,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Front2.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Front3.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_left1.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_left2.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_left3.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Back1.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Back2.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Back3.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Right1.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Right2.png" ,81))); animFrames.pushBack(SpriteFrame::create( "Blue_Right3.png" ,81))); @H_419_566@ // create the animation out of the frames Animation* animation = Animation::createWithSpriteFrames(animFrames,0.1f); Animate* animate = Animate::create(animation); // run it and repeat it forever mySprite->runAction(RepeatForever::create(animate));

很难以文字形式描述一个动画,所以请运行《开发者指南示例》中动作部分的代码查看动作效果。

减速(Easing)

Easing用一个给定的加速度来使动画更加顺畅。需要记住的是,无论速度快慢,ease动作总是同时开始和结束。在游戏中如果你想模拟一些物理特效,但又不想过度且麻烦地使用多个非常基本的动作,那么此时Ease动作将是模拟物理特效的一个很好的方法。这里有另一个给菜单和按钮添加动画的很好的例子。

下图显示了一些常用的减速功能:

Cocos2d-x支持上图中所显示的大部分减速功能。这些功能也是容易实现的。让我们一起看看一个特殊的用例。屏幕的上方添加一个Sprite对象,并使其上下跳动。

19
// create a sprite auto mySprite = Sprite::create( "mysprite.png" ); // create a MoveBy Action to where we want the sprite to drop from. auto move = MoveBy::create(2,Vec2(200,dirs->getVisibleSize().height - newSprite2->getContentSize().height)); auto move_back = move->reverse(); // create a BounceIn Ease Action auto move_ease_in = EaseBounceIn::create(move->clone() ); // create a delay that is run in between sequence events auto delay = DelayTime::create(0.25f); // create the sequence of actions,in the order we want to run them auto seq1 = Sequence::create(move_ease_in,move_ease_in_back, delay->clone(),nullptr); // run the sequence and repeat forever. @H_419_566@ mySprite->runAction(RepeatForever::create(seq1));

运行“开发者指南示例”中的这部分的代码可以查看动作效果。

序列动作以及如何执行它

Sequence可以使一系列的动作对象按顺序执行。这一系列对象可以是任何数量的动作对象、函数,甚至是另外一个序列动作。函数?是的!Cocos2d-x中有一个CallFunc对象,它允许你创建一个function()函数并可以传递到Sequence中执行。这就允许你在序列动作对象中添加自己的函数功能,而不是仅仅局限于Cocos2d-x中提供的动作对象。如下例为序列动作被执行时的状态:

序列动作的例子

21
// create a few actions. auto jump = JumpBy::create(0.5,Vec2(0,0),100,1); auto rotate = Rotateto::create(2.0f,10); // create a few callbacks auto callbackJump = CallFunc::create([](){ log ( "Jumped!" ); }); auto callbackRotate = CallFunc::create([](){ log ( "Rotated!" ); }); // create a sequence with the actions and callbacks auto seq = Sequence::create(jump,callbackJump,rotate,callbackRotate,nullptr); @H_419_566@ // run it mySprite->runAction(seq);

那么,Sequence对象做了什么呢?

它可以按顺序执行如下动作:

Jump->callbackJump->Rotate->callbackRotate

运行“开发者指南示例”中的代码查看动作效果。

Spawn

SpawnSequence类似,不同的是使用Spawn时所有动作是同时执行的。你可以有很多动作对象,甚至其他Spawn对象。

Spawn的作用与运行多个连续的runAction()语句所产生的结果是相同的。然而,使用Spawn的优点在于你可以将其放到一个序列中,从而实现特定的效果。而runAction()是不可以的。将SpawnSequence结合使用讲会实现很多强大的功能。

举例:

4
// create 2 actions and run a Spawn on a Sprite auto mySprite = Sprite::create( "mysprite.png" ); auto moveBy = MoveBy::create(10,Vec2(400,100));

使用Spawn:

3
// running the above Actions with Spawn. auto mySpawn = Spawn::createWithTwoActions(moveBy,fadeto); mySprite->runAction(mySpawn);

使用连贯的runAction()语句:

// running the above Actions with consecutive runAction() statements.mySprite->runAction(moveBy);mySprite->runAction(fadeto);

两个产生的效果是相同的。但是,其中一个可以在Sequence中使用Spawn。如下流程图所示:

16
// create a Sprite auto mySprite = Sprite::create( "mysprite.png" ); // create a few Actions auto moveBy = MoveBy::create(10,100)); auto fadeto = Fadeto::create(2.0f,120.0f); auto scaleBy = ScaleBy::create(2.0f,3.0f); // create a Spawn to use auto mySpawn = Spawn::createWithTwoActions(scaleBy,fadeto); // tIE everything together in a sequence auto seq = Sequence::create(moveBy,mySpawn,moveBy,nullptr); // run it mySprite->runAction(seq);

Reverse(逆序)

Reverse的作用完全像它的名字一样,例如运行一系列动作时,你完全可以调用reserve()函数使动作逆序执行。然而,这并不只是简单的逆序运行,实际上还将原始的SequenceSpawn的属性也转换为逆序。

Using theSpawnexample above reversing is simple. 上面Spawn中的例子使用逆序就会很简单:

2
// reverse a sequence,spawn or action mySprite->runAction(mySpawn->reverse());

大部分ActionSequence对象都是可逆的!

使用很简单,但是让我们来验证一下是不是这样,如下:

20
// create a Sprite auto mySprite = Sprite::create( "mysprite.png" ); mySprite->setposition(50,56); // create a few Actions auto moveBy = MoveBy::create(2.0f,0)); auto scaleBy = ScaleBy::create(2.0f,2.0f); auto delay = DelayTime::create(2.0f); // create a sequence auto delaySequence = Sequence::create(delay,delay->clone(), delay->clone(),nullptr); auto sequence = Sequence::create(moveBy,scaleBy,delaySequence,nullptr); // run it newSprite2->runAction(sequence); @H_419_566@ // reverse it newSprite2->runAction(sequence->reverse());

发生了什么呢?如下步骤清单或许对我们有帮助:

创建mySprite 设置mySprite位置为(50,56) 开始运行sequence 在两秒内sequence将mySprite移动了500个像素,mysprite新位置为(550,56) sequence延迟2秒 在两秒内sequence将mySprite扩大两倍 延迟了6秒多(注意,这里我们运行了另外一个sequence来完成这个) 在sequence上运行一reverse,因此我们可以向后重新运行每个动作。 sequence被延迟了6秒 在2秒内sequence将mySprite扩大了两倍 sequence延迟了两秒 在两秒内,sequence移动mySprite了-500个像素,mySprite的新位置为(50,56)

你可以看到reverse()用起来很简单,但是其实逻辑上并不简单。Cocos2d-x已经为你完成了这复杂的逻辑


转自cocos引擎中文官网

总结

以上是内存溢出为你收集整理的cocos2d-x中的动作细说全部内容,希望文章能够帮你解决cocos2d-x中的动作细说所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1043771.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存