FrameAnimation.ts 3.33 KB


const { ccclass, menu, property } = cc._decorator;

@ccclass
@menu("扩展组件/FrameAnimation")
/**序列侦动画组件,用于相同时间间隔序列侦动画 */
export default class FrameAnimation extends cc.Component {

    @property({ tooltip: "动画标记" })
    tag: string = 'animation';
    @property({ type: cc.SpriteFrame, tooltip: "精灵帧数组" })
    spriteframes: cc.SpriteFrame[] = [];
    @property({ type: cc.Float, tooltip: "帧动画切换图片的时间,即间隔时间" })
    frameTime: number = 0.1; //帧动画切换图片的时间,即间隔时间
    @property({ tooltip: "是否循环播放" })
    loop: boolean = false;     //是否循环播放
    @property({ tooltip: "是否加载完自动播放" })
    playOnLoad: boolean = false;

    private _isPlaying: boolean;
    private _loopCount: number;
    get isPlaying() { return this._isPlaying }
    private _time: number;
    get time() { return this._time; }
    private _sprite: cc.Sprite;
    private _endCallback?: (loopCount?: number) => void;

    onLoad() {
        this._isPlaying = false;  //是否在播放
        this._time = 0;   //播放时间控制
        this._sprite = this.getComponent(cc.Sprite);//获取组件
        if (!this._sprite) {       //若组件为空则为其添加组件
            this._sprite = this.addComponent(cc.Sprite);
        }
        if (this.playOnLoad) {  //如果用户选择playload属性则在场景开始时播放动画
            this.play();
        }
    }

    play(callback?: (loopCount?: number) => void, loop?: boolean) {
        if (this.spriteframes.length < 0) {
            return;
        }
        if (loop !== undefined) this.loop = loop;
        this._endCallback = callback;
        this._loopCount = 0;
        this._isPlaying = true;
        this._time = 0;
        this._sprite.spriteFrame = this.spriteframes[0];
    }

    stop() {
        this._isPlaying = false
    }

    update(dt: number) {
        if (!this._isPlaying) { //判断是否正在播放,不在播放可以直接返回
            return;
        }
        if (this.spriteframes.length < 0) { //判断精灵帧长度是否合法
            return;
        }
        this._time += dt; //获取播放时间
        var index = Math.floor(this._time / this.frameTime); //取整获得图片位置
        if (!this.loop) {//非循环播放
            if (index >= this.spriteframes.length) { //播放完毕
                this._isPlaying = false;
                if (this._endCallback) { //执行回调函数
                    this._endCallback();
                }
            }
            else {//动画正在播放
                this._sprite.spriteFrame = this.spriteframes[index];
            }
        }
        else {//循环播放
            while (index >= this.spriteframes.length) {
                //使索引回到之前对应的索引
                index -= this.spriteframes.length;
                //数组长度 *间隔时间 = 一段时间段
                this._time -= (this.spriteframes.length * this.frameTime);//使时间段回到之前对应的时间段
                this._loopCount++;
                if (this._endCallback) { //执行回调函数
                    this._endCallback(this._loopCount);
                }
            }
            this._sprite.spriteFrame = this.spriteframes[index];//更新索引
        }
    }
}