在上一篇介绍帧动画的文章中,我们已经介绍了如何给一个节点添加帧动画,忘记的小伙伴可以再去看看:让蔡徐坤来教你实现游戏中的帧动画(上),那么今天我们来给大家讲解一下如何通过脚本控制帧动画。
由于官网对通过脚本控制帧动画的讲解还是比较清晰的,这篇文章主要是带大家使用一下这些 API,想具体了解的小伙伴可以去官网查看:https://docs.cocos.com/creator/manual/zh/animation/scripting-animation.html,本文用到的资源可以去公众号后台回复「蔡徐坤」获得,下面正文开始:
1.首先创建一个主界面,可以在上篇文章的基础上直接进行修改,主要是添加了 10 个控制按钮,用于实现对 player 的不同控制,如果对 Button 组件使用不是特别熟悉的同学,可以去看一下我之前写的 Button 组件使用的讲解:UI 组件 | Button,Button 节点的名字按照图中顺序命名即可,对应 Scene 中是按照从左往右,从上往下排列的:
2.添加好按钮后,还需要再添加一个帧动画,因为这次我们要同时实现对两个帧动画的控制:
2.1 新创建一个 rotation 动画,将 Clips 修改为 2;
2.2 将两个动画拖到属性面板对应位置上,开始对 rotation 动画进行编辑,play 动画使用之前的即可;
2.3 添加一个 rotation 属性;
2.4 分别在 0 秒和 2 秒的位置添加关键帧;
2.5 最后将 2 秒位置的关键帧在属性面板将 rotation 属性大小设置为 360。
3.下面开始编写脚本:
3.1 播放 play 动画:
1 cbPlayPlay(){ 2 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 3 anim.play('play'); 4 },
注:在对动画操作之前,首先要获取 Animation 组件,下面不再对这个进行说明。
只需调用 play( ) 方法即可,如果不设置制定动画,并且有设置 defaultClip 的话,则会播放 defaultClip 动画:
1 anim.play();
还可以设置从第几秒开始播放:
1 anim.play('play', 1);
3.2 播放 rotation 动画:
1 cbPlayRotation(){ 2 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 3 anim.play('rotation'); 4 },
使用 play 接口播放一个动画时,如果还有其他的动画正在播放,则会先停止其他动画,如果 play 动画正在播放中,播放 rotation 动画,play 动画就会停止播放。
3.3 & 3.4 同时播放 play 和 rotation 动画:
1 // 同时播放 play 2 cbPlayAdditivePlay(){ 3 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 4 anim.playAdditive('play'); 5 }, 6 7 // 同时播放 rotation 8 cbPlayAdditiveRotation(){ 9 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 10 anim.playAdditive('rotation'); 11 },
除了使用 play( ) 之外,还可以使用 playAdditive( ) 方法对动画进行播放,使用 playAdditive 播放动画时,不会停止其他动画的播放。如果还有其他动画正在播放,则同时会有多个动画进行播放。如果 play 动画正在播放中,播放 rotation 动画,可以发现 play 动画不会停止播放。
3.5 & 3.6 & 3.7 暂停、停止和恢复:
1 // 暂停 play 2 cbPause(){ 3 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 4 anim.pause('rotation'); 5 }, 6 7 // 停止播放所有动画 8 cbStop(){ 9 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 10 anim.stop(); 11 }, 12 13 // 恢复所有动画 14 cbResume(){ 15 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 16 anim.resume('rotation'); 17 },
可以通过 pause( )、stop( ) 和 resume( ) 实现对动画暂停、停止和恢复的控制:
暂停会暂时停止动画的播放,当恢复动画的时候,动画会继续从当前时间往下播放。而停止则会终止动画的播放,再对这个动画进行播放的时候会重新从开始播放动画。
注:resume( ) 只会恢复暂停的动画,对已经停止的动画没有作用。
3.8 设置动画当前时间:
1 cbSetCurrentTime(){ 2 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 3 anim.setCurrentTime(1,'rotation'); 4 },
可以在任何时候使用 setCurrentTime(1,'clip') 对动画设置当前时间,但是动画不会立刻根据设置的时间进行状态的更改,需要在下一个动画的 update 中才会根据这个时间重新计算播放状态。
3.9 & 3.10 设置播放次数和循环次数:
1 // 修改播放速度为2 2 cbSpeed(){ 3 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 4 var animState = anim.getAnimationState('rotation'); 5 animState.speed = 2; 6 }, 7 8 // 设置循环次数为2 9 cbRepertCount(){ 10 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 11 var animState = anim.getAnimationState('rotation'); 12 animState.repeatCount = 2; 13 },
首先引入一个 AnimationState 的概念:
如果说 AnimationClip 作为动画数据的承载,那么 AnimationState 则是 AnimationClip 在运行时的实例,它将动画数据解析为方便程序中做计算的数值。 Animation 在播放一个 AnimationClip 的时候,会将 AnimationClip 解析成 AnimationState。 Animation 的播放状态实际都是由 AnimationState 来计算的,包括动画是否循环,怎么循环,播放速度 等。
那么如何获取 AnimationState 呢?Cocos 提供了两种获取的方式:
1 var anim = this.getComponent(cc.Animation); 2 // play 会返回关联的 AnimationState 3 var animState = anim.play('test'); 4 5 // 或是直接获取 6 var animState = anim.getAnimationState('test');
之后就可以通过获取到的 AnimationState 对 Animation 的播放状态进行改变了,本文只是设置了播放次数和循环次数,感兴趣的小伙伴还可以对其他状态进行改变。
附完整脚本:
1 // main.js 2 3 cc.Class({ 4 extends: cc.Component, 5 6 properties: { 7 }, 8 9 // LIFE-CYCLE CALLBACKS: 10 11 onLoad () { 12 this.node.getChildByName('play-play').on('click',this.cbPlayPlay,this); 13 this.node.getChildByName('play-rotation').on('click',this.cbPlayRotation,this); 14 this.node.getChildByName('play-addtive-play').on('click',this.cbPlayAdditivePlay,this); 15 this.node.getChildByName('play-addtive-rotation').on('click',this.cbPlayAdditiveRotation,this); 16 this.node.getChildByName('pause-play').on('click',this.cbPause,this); 17 this.node.getChildByName('stop-all').on('click',this.cbStop,this); 18 this.node.getChildByName('resume-all').on('click',this.cbResume,this); 19 this.node.getChildByName('setCurrentTime').on('click',this.cbSetCurrentTime,this); 20 this.node.getChildByName('speed').on('click',this.cbSpeed,this); 21 this.node.getChildByName('loop').on('click',this.cbRepertCount,this); 22 }, 23 24 start () { 25 26 }, 27 28 // update (dt) {}, 29 30 // 播放 play 31 cbPlayPlay(){ 32 console.log('0'); 33 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 34 anim.play('play'); 35 }, 36 37 // 播放 rotation 38 cbPlayRotation(){ 39 console.log('1'); 40 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 41 anim.play('rotation'); 42 }, 43 44 // 同时播放 play 45 cbPlayAdditivePlay(){ 46 console.log('2'); 47 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 48 anim.playAdditive('play'); 49 }, 50 51 // 同时播放 rotation 52 cbPlayAdditiveRotation(){ 53 console.log('3'); 54 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 55 anim.playAdditive('rotation'); 56 }, 57 58 // 暂停 play 59 cbPause(){ 60 console.log('4'); 61 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 62 anim.pause('rotation'); 63 }, 64 65 // 停止播放所有动画 66 cbStop(){ 67 console.log('5'); 68 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 69 anim.stop(); 70 }, 71 72 // 恢复所有动画 73 cbResume(){ 74 console.log('6'); 75 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 76 anim.resume('rotation'); 77 }, 78 79 // 设置 rotation 当前时间为第一秒 80 cbSetCurrentTime(){ 81 console.log('7'); 82 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 83 anim.setCurrentTime(1,'rotation'); 84 }, 85 86 // 修改播放速度为2 87 cbSpeed(){ 88 console.log('8'); 89 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 90 var animState = anim.getAnimationState('rotation'); 91 animState.speed = 2; 92 }, 93 94 // 设置循环次数为2 95 cbRepertCount(){ 96 console.log('9'); 97 var anim = this.node.getChildByName('player').getComponent(cc.Animation); 98 var animState = anim.getAnimationState('rotation'); 99 animState.repeatCount = 2; 100 }, 101 });
4.之后将编写好的脚本挂载到 Canvas 就可以运行了,图中我只是简单的进行了一下操作,具体操作小伙伴们可以自己尝试:
推荐阅读:
我是「Super于」,立志做一个每天都有正反馈的人!