Action
类如其名,它可以改变Node
对象的属性,Action
对象是随着时间改变Node
的属性。任何一个以Node
为基类的对象都有可执行的动作对象。例如,你可以在一个时间段内将Sprite
精灵从一个位置移动到另一个位置。
如下为MoveTo
和MoveBy
两个动作的实例:
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是绝对的,意思是它并不考虑到这个节点的当前状态。让我们看一个具体的例子:
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的位置。
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
。
// 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倍
// 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之间)。与之相反的动作是“淡出”
色调(Tint)
Tint使节点的NodeRGB从当前值改变到用户设置值。
动画(Animate)
通过Animate可以很容易地实现精灵的帧动画效果。只要简单的每隔一段时间替换_display frame_即可。如下例子:
// 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)));
// 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对象,并使其上下跳动。
// 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.
mySprite->runAction(RepeatForever::create(seq1));
|
序列动作以及如何执行它
Sequence
可以使一系列的动作对象按顺序执行。这一系列对象可以是任何数量的动作对象、函数,甚至是另外一个序列动作。函数?是的!Cocos2d-x中有一个CallFunc对象,它允许你创建一个function()函数并可以传递到Sequence
中执行。这就允许你在序列动作对象中添加自己的函数功能,而不是仅仅局限于Cocos2d-x中提供的动作对象。如下例为序列动作被执行时的状态:
序列动作的例子
// 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);
// run it
mySprite->runAction(seq);
|
那么,Sequence
对象做了什么呢?
它可以按顺序执行如下动作:
Jump
->callbackJump
->Rotate
->callbackRotate
Spawn
Spawn
与Sequence
类似,不同的是使用Spawn时所有动作是同时执行的。你可以有很多动作对象,甚至其他Spawn对象。
Spawn
的作用与运行多个连续的runAction()语句所产生的结果是相同的。然而,使用Spawn
的优点在于你可以将其放到一个序列中,从而实现特定的效果。而runAction()是不可以的。将Spawn
和Sequence
结合使用讲会实现很多强大的功能。
举例:
// 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
:
// running the above Actions with Spawn.
auto mySpawn = Spawn::createWithTwoActions(moveBy,fadeTo);
mySprite->runAction(mySpawn);
|
使用连贯的runAction()语句:
两个产生的效果是相同的。但是,其中一个可以在Sequence
中使用Spawn
。如下流程图所示:
// 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()函数使动作逆序执行。然而,这并不只是简单的逆序运行,实际上还将原始的Sequence
和Spawn
的属性也转换为逆序。
Using theSpawn
example above reversing is simple. 上面Spawn
中的例子使用逆序就会很简单:
// reverse a sequence,spawn or action
mySprite->runAction(mySpawn->reverse());
|
大部分Action
和Sequence
对象都是可逆的!
使用很简单,但是让我们来验证一下是不是这样,如下:
// 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);
// 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引擎中文官网
原文链接:https://www.f2er.com/cocos2dx/344221.html