Cocos Creator封装自己的帧动画组件播放动画

527 阅读2分钟

前言

在Cocos Creator游戏开发的过程中我们进行需要使用动画效果,虽然可以通过动画编辑器编辑动画效果,但是有时候用户想更灵活的控制帧动画的效果,就需要自己封装帧动画组件。

一、帧动画播放组件

1: creator播放帧动画需要通过动画编辑器去制作;

2: 为了方便控制和使用加入帧动画代码播放组件;

3: 属性设置:

  1. sprite_frames: 帧动画所用到的所有的帧;
  2. duration: 每帧的时间间隔;
  3. loop: 是否循环播放;
  4. play_onload: 是否加载组件的时候播放;

4: 接口设置:

  1. play_once(end_func); // 播放结束后的回掉函数;
  2. play_loop(); // 循环播放;

二、帧动画播放原理

1: 对的时间播放显示对的图片:

假设以三帧动画为例,时间间隔就是duration,

三、自己封装帧动画组件

1.  `const {ccclass, property} = cc._decorator;`

3.  `@ccclass`

4.  `export default class FrameAnim extends cc.Component {`

5.  `    @property({type: [cc.SpriteFrame], tooltip:"帧动画图片数组"})`

6.  `spriteFrames : Array<cc.SpriteFrame> = [];`

8.  `    @property({tooltip:"每一帧的时长"})`

9.  `duration : number = 0.1;`

11.  `    @property({tooltip:"是否循环播放"})`

12.  `    loop : boolean = false;`

14.  `    @property({tooltip:"是否在加载的时候就开始播放"})`

15.  `playOnload : boolean = false;`

17.  `    // 播放完后的回调函数`

18.  `    private endFunc : any = null;`

19.  `    // 动画播放需要的精灵组件`

20.  `    private sprite : cc.Sprite;`

21.  `    // 动画播放的状态,正在播放还是停止`

22.  `    private isPlaying : boolean = false;`

23.  `    // 记录已经播放的时间`

24.  `private playTime : number = 0;`

26.  `    onLoad () {`

27.  `        // 获取当前动画组件挂载的节点上的Sprite组件,如果没有则添加`

28.  `        this.sprite = this.node.getComponent(cc.Sprite);`

29.  `        if(!this.sprite){`

30.  `            this.sprite = this.node.addComponent(cc.Sprite);`

31.  `        }`

33.  `        // 判断是否是预加载播放`

34.  `        if(this.playOnload){`

35.  `            if(this.loop){`

36.  `                this.playLoop();        // 循环播放`

37.  `            }else{`

38.  `                this.playOnce(null);    // 只播放一次`

39.  `            }`

40.  `        }`

41.  `}`

43.  `    public playLoop() : void {`

44.  `        this.initFrame(true, null);`

45.  `}   `

47.  `    public playOnce(endf : any) : void {`

48.  `        this.initFrame(false, endf);`

49.  `}`

51.  `    private initFrame(loop:boolean, endf : any) : void{`

52.  `        if(this.spriteFrames.length <= 0){`

53.  `            return;`

54.  `        }`

55.  `        this.isPlaying = true;`

56.  `        this.playTime = 0;`

57.  `        this.sprite.spriteFrame = this.spriteFrames[0];`

58.  `        this.loop = loop;`

59.  `        this.endFunc = endf;`

60.  `}`

62.  `start () {`

64.  `}`

66.  `    update (dt) {`

67.  `        if(!this.isPlaying){`

68.  `            return;`

69.  `        }`

71.  `        // 累计时间,通过时间计算应该取哪一张图片展示`

72.  `        this.playTime += dt;`

73.  `        let index : number = Math.floor(this.playTime / this.duration);`

75.  `        if(this.loop){  // 循环播放`

76.  `            if(index >= this.spriteFrames.length){`

77.  `                index -= this.spriteFrames.length;`

78.  `                this.playTime -= (this.duration * this.spriteFrames.length);`

79.  `            }`

80.  `            this.sprite.spriteFrame = this.spriteFrames[index];`

81.  `        }else{          // 播放一次`

82.  `            if(index >= this.spriteFrames.length){`

83.  `                this.isPlaying = false;`

84.  `                // 如果有回调函数的处理,则调用回调函数`

85.  `                if(this.endFunc){`

86.  `                    this.endFunc();`

87.  `                }`

88.  `            }else{`

89.  `                this.sprite.spriteFrame = this.spriteFrames[index];`

90.  `            }`

91.  `        }`

92.  `    }`

93.  `}`

四、测试封装的帧动画组件

勾选PlayOnLoad和去掉的区别,勾选Loop和去掉的区别,可以发现预加载和循环播放。如何在代码中控制?

新建GameMgr.ts挂载到Canvas节点上**。**


1.  `import FrameAnim from "./FrameAnim";`

3.  `const {ccclass, property} = cc._decorator;`

4.  `@ccclass`

5.  `export default class GameMgr extends cc.Component {`

7.  `    @property({type: [FrameAnim], tooltip:"帧动画数组"})`

8.  `    anim : Array<FrameAnim> = [];`

9.  `// onLoad () {}`

11.  `    endPlay(){`

12.  `        console.log("动画播放完毕!!");`

13.  `    }`

14.  `    start () {`

15.  `        //this.anim[0].playOnce(this.endPlay);`

16.  `        //this.anim[1].playOnce(this.endPlay);`

17.  `        //this.anim[0].playOnce(null);`

18.  `        //this.anim[1].playOnce(null);`

19.  `        //this.anim[0].playLoop();`

20.  `        //this.anim[1].playLoop();`

21.  `        if(this.anim.length > 1){`

22.  `            this.anim[1].duration = 0.5;`

23.  `            this.anim[1].playOnce(this.endPlay);`

24.  `        }`

25.  `        if(this.anim.length > 0){`

26.  `            this.anim[0].playLoop();`

27.  `        }`

28.  `    }`

29.  `}`