美文网首页Cocos2d-X与游戏开发Cocos Creator
Cocos Creator封装自己的帧动画组件播放动画

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

作者: Thomas游戏圈 | 来源:发表于2020-08-20 10:13 被阅读0次

    前言

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

    一、 帧动画播放组件

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

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

    3: 属性设置:

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

    4: 接口设置:

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

    二、 帧动画播放原理

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

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

    [图片上传失败...(image-172f06-1597889249322)]

    三、 自己封装帧动画组件

    const {ccclass, property} = cc._decorator;
    
    @*ccclass*
    
    export default class FrameAnim extends *cc*.*Component* {
    
        @property({type: [cc.*SpriteFrame*], tooltip:"帧动画图片数组"})
    
    spriteFrames : *Array*<*cc*.*SpriteFrame*> = [];
    
        @property({tooltip:"每一帧的时长"})
    
    duration : *number* = 0.1;
    
        @property({tooltip:"是否循环播放"})
    
        loop : *boolean* = false;
    
        @property({tooltip:"是否在加载的时候就开始播放"})
    
    playOnload : *boolean* = false;
    
        // 播放完后的回调函数
    
        private endFunc : *any* = null;
    
        // 动画播放需要的精灵组件
    
        private sprite : *cc*.*Sprite*;
    
        // 动画播放的状态,正在播放还是停止
    
        private isPlaying : *boolean* = false;
    
        // 记录已经播放的时间
    
    private playTime : *number* = 0;
    
        onLoad () {
    
            // 获取当前动画组件挂载的节点上的Sprite组件,如果没有则添加
    
            *this*.sprite = *this*.node.getComponent(cc.Sprite);
    
            if(!*this*.sprite){
    
                *this*.sprite = *this*.node.addComponent(cc.Sprite);
    
            }
    
            // 判断是否是预加载播放
    
            if(*this*.playOnload){
    
                if(*this*.loop){
    
                    *this*.playLoop();        // 循环播放
    
                }else{
    
                    *this*.playOnce(null);    // 只播放一次
    
                }
    
            }
    
    }
    
        public playLoop() : *void* {
    
            *this*.initFrame(true, null);
    
    }   
    
        public playOnce(*endf* : *any*) : *void* {
    
            *this*.initFrame(false, endf);
    
    }
    
        private initFrame(*loop*:*boolean*, *endf* : *any*) : *void*{
    
            if(*this*.spriteFrames.length <= 0){
    
                return;
    
            }
    
            *this*.isPlaying = true;
    
            *this*.playTime = 0;
    
            *this*.sprite.spriteFrame = *this*.spriteFrames[0];
    
            *this*.loop = loop;
    
            *this*.endFunc = endf;
    
    }
    
    start () {
    
    }
    
        update (*dt*) {
    
            if(!*this*.isPlaying){
    
                return;
    
            }
    
            // 累计时间,通过时间计算应该取哪一张图片展示
    
            *this*.playTime += dt;
    
            let index : *number* = Math.floor(*this*.playTime / *this*.duration);
    
            if(*this*.loop){  // 循环播放
    
                if(index >= *this*.spriteFrames.length){
    
                    index -= *this*.spriteFrames.length;
    
                    *this*.playTime -= (*this*.duration * *this*.spriteFrames.length);
    
                }
    
                *this*.sprite.spriteFrame = *this*.spriteFrames[index];
    
            }else{          // 播放一次
    
                if(index >= *this*.spriteFrames.length){
    
                    *this*.isPlaying = false;
    
                    // 如果有回调函数的处理,则调用回调函数
    
                    if(*this*.endFunc){
    
                        *this*.endFunc();
    
                    }
    
                }else{
    
                    *this*.sprite.spriteFrame = *this*.spriteFrames[index];
    
                }
    
            }
    
        }
    
    }
    

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

    勾选PlayOnLoad和去掉的区别,勾选Loop和去掉的区别,可以发现预加载和循环播放。

    如何在代码中控制?

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

    import FrameAnim from "./FrameAnim";
    
    const {ccclass, property} = cc._decorator;
    
    @*ccclass*
    
    export default class GameMgr extends *cc*.*Component* {
    
        @property({type: [*FrameAnim*], tooltip:"帧动画数组"})
    
        anim : *Array*<*FrameAnim*> = [];
    
    // onLoad () {}
    
        endPlay(){
    
            *console*.log("动画播放完毕!!");
    
        }
    
        start () {
    
            //this.anim[0].playOnce(this.endPlay);
    
            //this.anim[1].playOnce(this.endPlay);
    
            //this.anim[0].playOnce(null);
    
            //this.anim[1].playOnce(null);
    
            //this.anim[0].playLoop();
    
            //this.anim[1].playLoop();
    
            if(*this*.anim.length > 1){
    
                *this*.anim[1].duration = 0.5;
    
                *this*.anim[1].playOnce(*this*.endPlay);
    
            }
    
            if(*this*.anim.length > 0){
    
                *this*.anim[0].playLoop();
    
            }
    
        }
    
    }
    

    相关文章

      网友评论

        本文标题:Cocos Creator封装自己的帧动画组件播放动画

        本文链接:https://www.haomeiwen.com/subject/thhsjktx.html