• 让蔡徐坤来教你实现游戏中的帧动画(中)


    在上一篇介绍帧动画的文章中,我们已经介绍了如何给一个节点添加帧动画,忘记的小伙伴可以再去看看:让蔡徐坤来教你实现游戏中的帧动画(上),那么今天我们来给大家讲解一下如何通过脚本控制帧动画。

    由于官网对通过脚本控制帧动画的讲解还是比较清晰的,这篇文章主要是带大家使用一下这些 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 就可以运行了,图中我只是简单的进行了一下操作,具体操作小伙伴们可以自己尝试:

     


    推荐阅读:

    让蔡徐坤来教你实现游戏中的帧动画(上)

    UI 组件 | Button

    一文教你实现「飞机大战」里战机的控制逻辑

    一文带你实现游戏中的音乐、音效设置


     

    我是「Super于」,立志做一个每天都有正反馈的人!

  • 相关阅读:
    C#基础:单例模式与多线程
    C#基础:线程同步
    C#基础:C#中的数据结构
    C#基础:GC中什么是代,一共分几代
    C#基础:Dispose方法和Finalize方法在何时被调用
    C#基础:.NET中GC的运行机制
    C#基础:简述.NET中堆栈和堆的特点和差异
    PLSQL_基础系列05_视图控制WITH CHECK OPTION(案例)
    PLSQL_基础系列04_时间间隔INTERVAL(案例)
    PLSQL_基础系列03_合并操作UNION / UNION ALL / MINUS / INTERSET(案例)
  • 原文地址:https://www.cnblogs.com/yu97271486/p/11411893.html
Copyright © 2020-2023  润新知