cocos-creator使用记录3_Action动画



1.cocos creator的Action动画
官方说明文档地址如下
http://docs.cocos.com/creator/manual/zh/scripting/actions.html


Action动画适宜使用的地方:
UI控件节点动画,比如点击一个按钮,按钮飞出屏幕。
在比如模仿星星闪动、旋转、渐隐、渐显。


其分为:
(1)容器动作  比较常用的是cc.sequence(按顺序执行)、cc.spawn(同时执行)
(2)时间间隔动作
(3)缓动动作
(4)即时动作
详细情况查看如下
http://docs.cocos.com/creator/manual/zh/scripting/action-list.html


通常比较常用的是其前3个的组合,比如
(1)缩放
var delay1 = cc.delayTime(0.5); //延迟0.5秒
var toBigAction1 = cc.scaleTo(0.3, 3); //0.3秒变成3倍大小(默认是线性的放大,即匀速放大)
var action1 = cc.sequence(delay1, toBigAction1); //按顺序执行,先延迟1秒,后缩放
this.birdNode1.runAction(action1); //this.birdNode1执行以上动作
注意:这里缩放没有使用缓动动作,默认按线性。


(2)移动
var delay_startBtn = cc.delayTime(0.2); //延迟0.2秒
//0.75秒内x移动0,y移动-1200,移动曲线按cc.easeCubicActionIn()
var startBtnAction = cc.moveBy(0.75, cc.p(0, -1200)).easing(cc.easeCubicActionIn()); 
this.startBtn.runAction(cc.sequence(delay_startBtn, startBtnAction)); //this.startBtn执行以上动作
注意:这里移动使用了缓动动作,通常也就设计到运动学的情况会用到缓动动作,比如抛物线运动、弹簧。


(3)透明度
var delay2 = cc.delayTime(0.3); //延迟0.3秒
var fadeAction2 = cc.fadeTo(0.25, 0); //0.25秒透明度从255降到0
var action2 = cc.sequence(delay2, fadeAction2);
this.heartNode1.runAction(action2);
this.heartNode2.runAction(action2.clone()); //这里不能直接用action2,必须action2.clone()
注意:action不能同名,同名的话只会执行最后一个。需要重复使用时,可用上面的clone()。


(4)回调函数
onLoad: function(){
var delay3 = cc.delayTime(0.3);
var fadeAction3 = cc.fadeTo(0.25, 255);
var callback1 = cc.callFunc(this.ladderAnimation, this); //回调函数
var action3 = cc.sequence(delay3, fadeAction3, callback1);
this.mileageNode.runAction(action3);
},
ladderAnimation: function(){
....
},
注意:回调函数是一个很有用的设定,比如你可以在点击按钮后,先将按钮飞出屏幕,然后执行跳转场景的函数。


(5)震屏
var quakeAction = cc.repeat(
cc.sequence(cc.moveBy(0.05,cc.p(2,2)), 
cc.moveBy(0.1,cc.p(-4,4)), 
cc.moveBy(0.05,cc.p(2,2)), 
cc.moveBy(0.1,cc.p(0,-6))),
2);
this.bgNode.runAction(quakeAction);
注意:这里用了cc.repeat,其执行了2次。


更多的动画需要你自己去发挥想象力了。


2.缓动动作
http://gad.qq.com/article/detail/18537
http://www.cocoachina.com/bbs/read.php?tid-462623.html
cc.easeIn
cc.easeOut
cc.easeInOut
cc.easeExponentialIn
cc.easeExponentialOut
cc.easeExponentialInOut
cc.easeSineIn
cc.easeSineOut
cc.easeSineInOut
cc.easeElasticIn
cc.easeElasticOut
cc.easeElasticInOut
cc.easeBounceIn API
cc.easeBounceOut
cc.easeBounceInOut
cc.easeBackIn
cc.easeBackOut
cc.easeBackInOut
cc.easeBezierAction
cc.easeQuadraticActionIn
cc.easeQuadraticActionOut
cc.easeQuadraticActionInOut
cc.easeQuarticActionIn
cc.easeQuarticActionOut
cc.easeQuarticActionInOut
cc.easeQuinticActionIn
cc.easeQuinticActionOut
cc.easeQuinticActionInOut
cc.easeCircleActionIn
cc.easeCircleActionOut
cc.easeCircleActionInOut
cc.easeCubicActionIn
cc.easeCubicActionOut
cc.easeCubicActionInOut


3.使用中的问题
3.1.同一个节点的Action动画没执行完,再执行一次会发生什么
在cocos creator中新建一个HelloWorld项目,将脚本改为以下
HelloWorld.js-------------
cc.Class({
    extends: cc.Component,
    properties: {
        label: cc.Label,
        text: 'Hello, World!',
cocos: cc.Node,
    },
    onLoad: function () {
this.time = 0;
this.cocos.runAction(cc.moveTo(2, cc.p(100, 0)));
this.scheduleOnce(function(){
this.cocos.runAction(cc.moveTo(2, cc.p(100, 0)));
},1);
    },
    update: function (dt) {
this.time += dt;
if(this.time > 0.2){
this.time = 0;
var str = "x=" + this.cocos.x + ",y" + this.cocos.y;
this.label.string = str;
cc.log(str);
}
    },
});
由上,屏幕上显示的文本的x值为150。
由此可见,同一个节点的动画没执行完,再执行一次其结果会叠加,结束时间
按前一次算。


3.2.如何判断一个节点是否处于Action动画中
(1)给每个action设置tag,保存当前播放的action tag,通过tag获得当前action,执行以下 
action->isDone() 返回true则action执行完毕。
var action = cc.moveTo(0.1, cc.p(100, 1));
action.setTag(1);
this.action2 = action.clone();
this.node.runAction(action);
var action1 = this.node.getActionByTag(1);
if(action1.isDone()){
cc.log("执行完毕");
}
if(this.action2.getTarget() != null){
cc.log("Action有目标");
}
//通过节点的事件来判断
this.node.runAction(cc.moveBy(2, cc.p(100,100)).setTag(123)); 
this.node.on("position-changed", function(event){
cc.log('移动了哦');
var action3 = event.currentTarget.getActionByTag(123);
if(action3.isDone()){
cc.log("执行完毕");
}
});


3.3.带回调函数的Action是否回调函数的执行也算在Action时间中
cc.Class({
    extends: cc.Component,
    properties: {
        label1: cc.Label,
        label2: cc.Label,
label3: cc.Label,
label4: cc.Label,
label5: cc.Label,
cocos: cc.Node,
    },
    onLoad: function () {
var action = cc.sequence(cc.moveTo(2, cc.p(100, 0)), cc.callFunc(this.doSomething, this));
action.setTag(1);
this.cocos.runAction(action);
this.scheduleOnce(function(){
var action = cc.sequence(cc.moveTo(2, cc.p(100, 0)), cc.callFunc(this.doSomething, this));
action.setTag(1);
this.cocos.runAction(action);
},1);

this.cocos.on("position-changed", function(event){
var action3 = event.currentTarget.getActionByTag(1);
if(action3 != null){
this.label2.string = "action3 is not null";
if(action3.isDone()){
this.label2.string = "action3执行完毕";
cc.log("action3执行完毕");
}
}else{
this.label2.string = "action3 is null";
}
}, this);
    },
doSomething: function(){
cc.log("doSomething执行开始");
for(var i = 0; i < 100; i++){
cc.sys.localStorage.setItem('i', i);
}
this.label5.string = "doSomething执行完毕";
cc.log("doSomething执行完毕");
},
    update: function (dt) {
var action4 = this.cocos.getActionByTag(1);
if(action4 != null){
this.label3.string = "cocos has action";
if(action4.isDone()){
this.label4.string = "action4执行完毕";
cc.log("action4执行完毕");
}
}else{
this.label3.string = "cocos has not action";
}
    },
});
由上可见,action的执行时间包含了回调函数的执行时间。即action的isDone会在回调函数执行完,
值才为true。


3.4.使用for循环执行带有Action动画的函数,Action中带有的回调函数的执行情况
cc.Class({
    extends: cc.Component,
    properties: {
        label1: cc.Label,
        label2: cc.Label,
label3: cc.Label,
label4: cc.Label,
label5: cc.Label,
cocos: cc.Node,
cocos1: cc.Node,
cocos2: cc.Node,
cocos3: cc.Node,
cocos4: cc.Node,
cocos5: cc.Node,
cocos6: cc.Node,
cocos7: cc.Node,
cocos8: cc.Node,
cocos9: cc.Node,
cocos10: cc.Node,
cocos11: cc.Node,
cocos12: cc.Node,
cocos13: cc.Node,
cocos14: cc.Node,
cocos15: cc.Node,
    },
onLoad: function () {
var isMoved = null;
cc.log("开始--------");
for(var i = 0; i < 1; i++){
this.doAction();
isMoved = true;
cc.log("for" + i);
}
if(isMoved){
cc.log("执行isMoved");
}
cc.log("结束--------");
    },
doSomething: function(){
cc.log("doSomething执行开始");
for(var i = 0; i < 100; i++){
cc.sys.localStorage.setItem('i', i);
}
this.label5.string = "doSomething执行完毕";
cc.log("doSomething执行完毕");
},
doAction: function(){
var action = cc.sequence(cc.moveTo(2, cc.p(100, 0)), cc.callFunc(this.doSomething, this));
this.cocos1.runAction(action);
this.cocos2.runAction(action.clone());
this.cocos3.runAction(action.clone());
this.cocos4.runAction(action.clone());
this.cocos5.runAction(action.clone());
this.cocos6.runAction(action.clone());
this.cocos7.runAction(action.clone());
this.cocos8.runAction(action.clone());
this.cocos9.runAction(action.clone());
this.cocos10.runAction(action.clone());
this.cocos11.runAction(action.clone());
this.cocos12.runAction(action.clone());
this.cocos13.runAction(action.clone());
this.cocos14.runAction(action.clone());
this.cocos15.runAction(action.clone());
},
});
输出:
开始--------
for0
执行isMoved
结束--------
doSomething执行开始
doSomething执行完毕  //执行15次


由上可见,在for循环中执行Action,Action的执行会在for循环外面。for循环只是启动所有Action,就立刻退出了
循环。





猜你喜欢

转载自blog.csdn.net/haibo19981/article/details/80435534