CocosCreator2.x之帧动画播放组件

>>>>>

脚本组件,挂载即用。

AnimationController.ts

const { ccclass, property, executeInEditMode, playOnFocus } = cc._decorator;

/**
 * 帧动画播放组件
 * ### 开放的接口;
 * #### play 播放
 * #### stop 停止播放
 * #### gotoAndPlay 跳转到某帧并播放
 * #### gotoAndStop 跳转到某帧并停止播放
 * #### isPlayEnd 是否播放结束
 * ### 开放的事件
 * #### completeTimes 单次播完完成事件
 * #### complete 全部次数完成事件
 * @author 薛鸿潇
 */
@ccclass
@executeInEditMode()
@playOnFocus()
export default class FrameAnimation extends cc.Component {

    @property({ displayName: '精灵纹理', type: cc.SpriteFrame }) private images: cc.SpriteFrame[] = [];
    @property({ displayName: '每帧间隔' }) private frameTime: number = 0.1;
    @property({ displayName: '播放次数' }) private playTimes: number = 0;
    @property({ displayName: "是否倒播", tooltip: "勾选,倒着播放,不钩,顺序播放" }) private reverse: boolean = false;
    @property({ displayName: '自动播放' }) private autoPlayOnLoad: boolean = true;
    @property({ displayName: "自动销毁", tooltip: '播完自动销毁' }) private autoDestroy: boolean = false;
    @property({ displayName: "每帧回调", type: cc.Component.EventHandler }) onFrameCall: cc.Component.EventHandler = new cc.Component.EventHandler();
    @property({ displayName: "结束回调", type: cc.Component.EventHandler }) onCompleteCall: cc.Component.EventHandler = new cc.Component.EventHandler();
    /** 编辑器预览 */
    private _edit_play: boolean = false;
    @property({ displayName: '编辑器预览' })
    get edit_play(): boolean {
        if (this._edit_play && !this.edit_playing) {
            this.edit_playing = true;
            this.play();
        }
        this.running = this._edit_play;
        return this._edit_play;
    }
    set edit_play(v: boolean) {
        this._edit_play = v;
    }
    /** 编辑器是否正在播放 */
    private edit_playing = false;

    /** 动画帧数量 */
    public frameNum: number = 0;
    /** 当前帧下标 */
    public frameIndex: number = 0;
    /** 下一帧下标 */
    public nextFrameIndex: number = 0;
    /** 是否允许播放 */
    public running: boolean = true;
    /** 精灵组件 */
    private comp_spr: cc.Sprite;
    /** 播放下一帧的倒计时 */
    private time: number = 0;
    /** 每完成一轮的回调 */
    public completeTimesCallback: Function;
    /** 全部播完回调 */
    public completeCallback: Function;
    /** 每帧回调 */
    public frameCallback: Function;
    /** 当前轮播次数 */
    private currentTimes: number = 0;

    onLoad() {
        this.comp_spr = this.getComponent(cc.Sprite);
    }

    start() {
        if (this.images.length != 0) {
            this.frameNum = this.images.length;
        }
        this.running = this.autoPlayOnLoad;

        if (this.reverse) {
            this.frameIndex = this.frameNum - 1;
            this.nextFrameIndex = this.frameNum - 1;
        }

    }
    /**
     * 更新动画帧
     * @param dt 
     */
    update(dt) {

        if (!this.running) return;
        if (this.images.length == 0) return;
        if (this.playTimes != 0 && this.currentTimes > this.playTimes) {
            this.running = false;
            return;
        }

        this.time -= dt;
        if (this.time <= 0) {
            this.time = this.frameTime;
            if (!this.reverse) {
                this.frameIndex = this.nextFrameIndex % this.frameNum;
                this.nextFrameIndex = this.frameIndex + 1;
            } else {
                this.frameIndex = (this.nextFrameIndex + this.frameNum) % this.frameNum;
                this.nextFrameIndex = this.frameIndex - 1;
            }
            this.playing();
            if (this.frameIndex == 0) {
                this.playEnd();
            }
        }
    }
    /** 播放中 */
    private playing() {
        this.comp_spr.spriteFrame = this.images[this.frameIndex];

        if (this.comp_spr.spriteFrame) {
            var rect: cc.Rect = this.comp_spr.spriteFrame.getRect();
            this.node.width = rect.width;
            this.node.height = rect.height;
        }
        // 事件回调
        this.onFrameCall.emit([]);
        if (this.frameCallback != null) {
            this.frameCallback(this.frameIndex);
        }
    }
    /** 播放结束 */
    private playEnd() {
        this.currentTimes++;

        // 完成一次
        this.node.emit("completeTimes", this.currentTimes);
        if (this.completeTimesCallback != null) {
            this.completeTimesCallback(this.currentTimes);
        }

        // 全部完成
        if (this.playTimes != 0 && this.currentTimes > this.playTimes) {
            // 事件回调
            this.node.emit("complete");
            this.onCompleteCall.emit([]);
            if (this.completeCallback != null) {
                this.completeCallback();
            }

            if (this.autoDestroy && !CC_EDITOR) {
                this.node.destroy();
            }
            // this.edit_play = false;
            this._edit_play = false;
            this.edit_playing = false;
        }
    }

    /**
     * 开始播放
     * @param frameCallback 
     * @param completeCallback 
     */
    public play(frameCallback: Function = null, completeCallback: Function = null) {

        this.frameCallback = frameCallback;
        this.completeCallback = completeCallback;

        this.running = true;
        this.frameIndex = 0;
        this.currentTimes = 0;

        this.time = this.frameTime;

        if (this.images.length != 0) {
            this.frameNum = this.images.length;

            if (this.reverse) {
                this.frameIndex = this.frameNum - 1;
                this.nextFrameIndex = this.frameNum - 1;
            }

        }

        if (!this.comp_spr) {
            this.comp_spr = this.getComponent(cc.Sprite);
        }

        if (this.comp_spr)
            this.comp_spr.spriteFrame = this.images[0];


        if (this.comp_spr.spriteFrame) {
            var rect: cc.Rect = this.comp_spr.spriteFrame.getRect();
            this.node.width = rect.width;
            this.node.height = rect.height;
        }

    }

    /**
     * 跳转到某帧并开始播放
     * @param frameIndex 帧下标
     */
    public gotoAndPlay(frameIndex: number) {
        if (!this.comp_spr) {
            this.comp_spr = this.getComponent(cc.Sprite);
        }

        this.running = true;
        this.frameIndex = frameIndex;
        this.nextFrameIndex = frameIndex;
        this.currentTimes = 0;
    }

    /** 停止 */
    public stop() {
        this.running = false;
    }

    /**
     * 跳转到某帧并停止播放
     * @param frameIndex 帧下标
     */
    public gotoAndStop(frameIndex: number) {
        this.frameIndex = frameIndex;

        if (this.frameIndex < 0)
            this.frameIndex = 0;

        if (this.frameIndex > this.images.length - 1)
            this.frameIndex = this.images.length - 1;

        if (!this.comp_spr) {
            this.comp_spr = this.getComponent(cc.Sprite);
        }

        this.comp_spr.spriteFrame = this.images[this.frameIndex];

        if (this.comp_spr.spriteFrame) {
            var rect: cc.Rect = this.comp_spr.spriteFrame.getRect();
            this.node.width = rect.width;
            this.node.height = rect.height;
        }

        this.running = false;
    }
    /**
     * 是否播放结束
     * @returns 
     */
    public isPlayEnd(): boolean {
        return this.frameIndex == this.frameNum;
    }
}

论坛抄来的,具体来源忘了,略微修改优化了一下,亲测可用,但还是建议用编辑器自带的animation

整理不易,关注收藏不迷路。

目录:CocosCreator经典笔记_神兽白泽-CSDN博客

笔者qq、微信:1302109196

qq群:415468592

>>>>>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值