cocos2d-js 3.x 动作

源代码下载http://www.oschina.net/code/snippet_2288842_48335

Action 对象就像它看起来的一样,  让 Node 执行一个对属性的变化. Action 对象允许及时地转化Node 属性。继承自 Node 的对都可以在上面执行 Action对象。 举个例子, 你可以移动在一个段时间内把Sprite一个从一个坐标移动到另一个坐标。

MoveToMoveBy 动作的例子:

// 在2秒内移动精灵到坐标50,10
var moveTo = cc.moveTo(2,cc.p(50, 10));
mySprite1.runAction(moveTo);

// 在2秒内向右移动20个点
var moveBy = cc.moveBy(2, cc.p(20,0));
mySprite2.runAction(moveBy);

By和To有什么区别呢?

你将会注意到每一个 Action 都有一个 ByTo 版本.。为什么呢?他们有不同的实现方式。 By是相对于 Node的当前状态。 To action 是绝对的, 这意味着不用考虑 Node的当前状态。让我们看一个具体的例子:

var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(cc.p(200, 256));
this.addChild(mySprite);
var showPosition = cc.callFunc(function () {
    cc.log("("+ this.getPositionX()+ "," + this.getPositionY()+")");
}, mySprite);

cc.log("(" + mySprite.getPositionX() + "," + mySprite.getPositionY() + ")");
// MoveBy - 让我们2秒内在x坐标上移动精灵200像素
// MoveBy 是相对的 - x = 200 + 200 ,在移动后是400
var  moveBy = cc.moveBy(2, cc.p(200, 0));

// MoveTo - 让我们2秒内移动精灵到(300,256)
// MoveTo 是绝对 - 不管现在在什么位置,精灵都将移动到(200,256)
var moveTo = cc.moveTo(2, cc.p(300, mySprite.getPositionY()));

var seq = cc.sequence(moveBy,showPosition, moveTo, showPosition);
mySprite.runAction(seq);

基本动作以及如何让它们执行起来

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

Move

在一段时间内移动Node 的坐标。

var mySprite1 = new cc.Sprite(res.node_png);
mySprite1.setPosition(cc.p(winSize.width / 4 , winSize.height / 4));
this.addChild(mySprite1);

var mySprite2 = new cc.Sprite(res.node_png);
mySprite2.setPosition(cc.p(winSize.width / 4 , winSize.height / 4 * 3));
this.addChild(mySprite2);
// 在2秒内移动精灵到指定位置
var moveTo = cc.moveTo(2, cc.p(50, 0));
mySprite1.runAction(moveTo);

// 在2秒内向右移动精灵50像素
var moveBy = cc.moveBy(2, cc.p(50, 0));

mySprite2.runAction(moveBy);

Rotate

在2秒内顺时针旋转一个 Node

var mySprite1 = new cc.Sprite(res.node_png);
mySprite1.setPosition(cc.p(winSize.width / 4 , winSize.height / 4));
this.addChild(mySprite1);

var mySprite2 = new cc.Sprite(res.node_png);
mySprite2.setPosition(cc.p(winSize.width / 4 , winSize.height / 4 * 3));
this.addChild(mySprite2);

// Rotates a Node to the specific angle over 2 seconds
var  rotateTo = cc.rotateTo(2.0 , 40.0);
mySprite1.runAction(rotateTo);

// Rotates a Node clockwise by 40 degree over 2 seconds
var rotateBy = cc.rotateBy(2.0, 40.0);
mySprite2.runAction(rotateBy);

Scale

在2秒内放大3倍 Node 然后再在2秒内x轴缩小为0.5,y轴缩小为0.3。

var mySprite1 = new cc.Sprite(res.node_png);
mySprite1.setPosition(cc.p(winSize.width / 4 , winSize.height / 4));
this.addChild(mySprite1);

var mySprite2 = new cc.Sprite(res.node_png);
mySprite2.setPosition(cc.p(winSize.width / 4 , winSize.height / 4 * 3));
this.addChild(mySprite2);

// Scale uniformly by 3x over 2 seconds
var scaleBy1 = cc.scaleBy(2.0, 3.0);

// Scale X by 0.5 and Y by 0.3 over 2 seconds
var scaleBy2 = cc.scaleBy(2.0, 0.5, 0.3);


var scaleBySeq1 = cc.sequence(scaleBy1, scaleBy2);
mySprite1.runAction(scaleBySeq1);

// Scale to uniformly to 3x over 2 seconds
var scaleTo1 = cc.scaleTo(2.0, 3.0);

// Scale X to 0.5 and Y to 0.3 over 2 seconds
var scaleTo2 = cc.scaleTo(2.0, 0.5, 0.3);
var scaleBySeq2 = cc.sequence(scaleTo1, scaleTo2);
mySprite2.runAction(scaleBySeq2);

Fade In/Out

淡入一个 Node.

它从0到255修改透明度. 这一动作的反向是淡出。

var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(winSize.width / 2 , winSize.height / 2 );
this.addChild(mySprite);

// fades in the sprite in 1 seconds
var fadeIn = cc.fadeIn(1);

// fades out the sprite in 2 seconds
var fadeOut = cc.fadeOut(2);

//连续动作
var seq = cc.sequence(fadeOut, fadeIn);
mySprite.runAction(seq);

Tint

改变一个Node的RGB从当前颜色到一个自定义的着色。

var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(winSize.width / 2 , winSize.height / 2 );
this.addChild(mySprite);

//等待两秒
var sleep = cc.delayTime(2);
var showlog1 = cc.callFunc(function(){
    cc.log("tintTo end");
});
var showlog2 = cc.callFunc(function(){
    cc.log("tintBy start");
},mySprite);

// Tints a node to the specified RGB values
var tintTo = cc.tintTo(2.0, 120.0, 232.0, 254.0);

// Tints a node BY the delta of the specified RGB values.
var tintBy = cc.tintBy(2, 120, 232, 254);

//连续动作
var seq = cc.sequence(tintTo, showlog1, sleep, showlog2, tintBy);
mySprite.runAction(seq);

Animate

使用Animate 可以让你的 Sprite 对象做简单的原始动画。这只是在动画期间每隔一段时间替换显示帧。让我们细想下这个例子吧。

cc.spriteFrameCache.addSpriteFrames(res.running_plist);
var mySprite = new cc.Sprite(res.runner_png);
mySprite.setPosition(winSize.width / 2 , winSize.height / 2 );
this.addChild(mySprite);

// now lets animate the sprite we moved
var SpriteFrame = [];
for (var i = 0; i < 8 ; i++ ){
    var str = "runner" + i + ".png";
    var frame = cc.spriteFrameCache.getSpriteFrame(str);
    SpriteFrame.push(frame);
}

// create the animation out of the frames
var animation = new cc.Animation(SpriteFrame, 0.1);
var animate = cc.animate(animation);
// run it and repeat it forever
mySprite.runAction(cc.repeatForever(animate));

很难在文本描述动画,所以请运行这个动作的示例代码来查看效果。

Easing

Easing是指定加速度的动画,以使动画平滑。 请记住无论是何种速度,ease动作总是在相同的时间开始和结束。Ease 动作是一个在你的游戏里伪造一个物理现象的好方法。或许你需要一些模拟的物理但是又不想增加开锁并增加几个非常基本的动力。 另一个很好的例子是动画菜单和按钮。

下面画片展示了常见的Easing函数:

Cocos2d-js支持Easing比上图提供的更多。它们也很容易实现。让我们来看看一个特定的用例吧。我们让一个Sprite对象从屏幕的顶端掉下来并反弹。

// create a sprite
var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(winSize.width / 2, winSize.height - mySprite.getContentSize().height / 2);
this.addChild(mySprite);
// create a MoveBy Action to where we want the sprite to drop from.
var move = cc.moveBy(2, cc.p(0, - mySprite.getPositionY() + mySprite.getContentSize().height / 2 ));
var move_back = move.reverse();

// create a BounceIn Ease Action
var move_ease_in = move.easing(cc.easeIn(2));
var move_ease_in_back = move_back.easing(cc.easeOut(2));

// create a delay that is run in between sequence events
var delay =cc.delayTime(0.25);

// create the sequence of actions, in the order we want to run them
var seq1 = cc.sequence(move_ease_in, delay, move_ease_in_back, delay);

// run the sequence and repeat forever.
mySprite.runAction(cc.repeatForever(seq1));

请运行这个动作的示例代码来查看效果。

Sequences以及如何来运行他们

Sequences是按顺序来执行一系列 Action 对象。这可以是任意数量的 Action 对象、 Functions 甚至是其他的 Sequence。函数?是的! Cocos2d-js有一个 CallFunc 对象, 它允许你创建一个 function() 并传递给你正要执行的Sequence。除了Cocos2d-js规定的stock Action对象,这允许你增加自己的功能到你的Sequence对象中。下面就是当Sequence执行时的样子:

一个 sequence的例子

var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(winSize.width / 2, winSize.height / 2);
this.addChild(mySprite);

// create a few actions.
var jump = cc.jumpBy(0.5, cc.p(0, 0), 100, 1);

var rotate = cc.rotateTo(2, 10);

// create a few callbacks
var callbackJump = cc.callFunc(function(){
    cc.log("Jumped!");
});

var  callbackRotate = cc.callFunc(function(){
    cc.log("Rotated!");
});

// create a sequence with the actions and callbacks
var seq = cc.sequence(jump, callbackJump, rotate, callbackRotate);

// run it
mySprite.runAction(seq);

所以这个 Sequence 动作做了什么?

它将按顺序执行以下操作:

Jump -> callbackJump -> Rotate -> callbackRotate

请运行这个动作的示例代码来查看效果。

Spawn

Spawn 除了所有动作都在同一时间执行外和 Sequence非常类似。你可以使用任意数量的Action对象甚至是其他的Spawn对象!

Spawn 产生的结果和连续执行多个runAction()语句是相同的。但是,Spawn的好处是可以把它放进一个Sequence里来帮助实现用其他方式不能实现的特定效果。结合SpawnSequence是一个非常强大的特性。

给出的例子:

// create 2 actions and run a Spawn on a Sprite
var mySprite1 = new cc.Sprite(res.node_png);
mySprite1.setPosition(winSize.width / 4, winSize.height * 3 / 4);
this.addChild(mySprite1);

var moveBy1 = cc.moveBy(10, cc.p(400,100));
var fadeTo1 = cc.fadeTo(2, 120);

var mySprite2 = new cc.Sprite(res.node_png);
mySprite2.setPosition(winSize.width / 4, winSize.height * 2 / 4);
this.addChild(mySprite2);

var moveBy2 = cc.moveBy(10, cc.p(400,100));
var fadeTo2 = cc.fadeTo(2, 120);

使用一个Spawn:

// running the above Actions with Spawn.
var mySpawn = cc.spawn(moveBy1, fadeTo1);
mySprite1.runAction(mySpawn);

以及连续的 runAction() 语句:

// running the above Actions with consecutive runAction() statements.
mySprite2.runAction(moveBy2);
mySprite2.runAction(fadeTo2);

两个将会产生相同的结果。 然而,你可以在Sequence使用Spawn 。这个流程图展示它看起来的样子:

// create a Sprite
var mySprite3 = new cc.Sprite(res.node_png);
mySprite3.setPosition(winSize.width / 4, winSize.height * 1 / 4);
this.addChild(mySprite3);

// create a few Actions
var moveBy3 = cc.moveBy(10, cc.p(200,30));
var fadeTo3 = cc.fadeTo(2., 120);
var scaleBy3 = cc.scaleBy(2, 3);

// create a Spawn to use
var mySpawn3 = cc.spawn(scaleBy3, fadeTo3);

// tie everything together in a sequence
var seq3 = cc.sequence(moveBy3, mySpawn3, moveBy3);

// run it
mySprite3.runAction(seq3);

请运行这个动作的示例代码来查看效果。

Reverse

Reverse就像它看起来那样执行。如果你运行一系列动作,你可以调用reverse()来用相反的方向来执行它。然而不仅仅是简单地在相反运行。它实际上也操作在reverse中原始SequenceSpawn的内容。使用上面的Spawn例子来产生反向动作是很简单的。

 // reverse a sequence, spawn or action
mySprite.runAction(mySpawn.reverse());

大多数 ActionSequence 对象都是可逆的。

它使用起来很简单,但是让我们来确认下我们看见发生了什么。给出的例子:

// create a Sprite
var mySprite = new cc.Sprite(res.node_png);
mySprite.setPosition(50, 56);
this.addChild(mySprite);

// create a few Actions
var moveBy = cc.moveBy(2, cc.p(500,0));
var scaleBy = cc.scaleBy(2, 2);
var delay = cc.delayTime(2);

// create a sequence
var delaySequence = cc.sequence(delay, delay.clone(), delay.clone(), delay.clone());

var sequence = cc.sequence(moveBy, delay, scaleBy, delaySequence);

// run it
mySprite.runAction(sequence.repeatForever());

// reverse it
mySprite.runAction(sequence.reverse().repeatForever());

什么正在发生 ?我们列出的步骤的列表可能是有益于理解的:

  1. mySprite被创建

  2. mySprite 的坐标设置成 (50, 56)

  3. sequence 开始执行

  4. sequence 移动 mySprite 向右 500, 用时2秒, mySprite 的新坐标是 (550, 56)

  5. sequence 等待2秒

  6. sequence 在2秒内放大 mySprite 2倍

  7. sequence 等待另外6秒 (注意我们运行另一个序列来完成这一任务)

  8. 我们在sequence上执行reverse, 所以我们运行了每个动作的倒退

  9. sequence 等待6秒

  10. sequence 在2秒内放大 mySprite  -2x

  11. sequence 等待2秒

  12. sequence 向右移动 mySprite -500, 在2秒内, mySprite 的新坐标是 (50, 56)

你可以看到reverse()使用起来很简单,但它的内在逻辑没那么简单。 Cocos2d-js 做了大部分艰巨的任务!

参考:http://cocos2d-x.org/wiki/Actions

转载于:https://my.oschina.net/soarwilldo/blog/418668

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值