Ver código fonte

帧动画播放组件

薛鸿潇 5 anos atrás
pai
commit
1d15c69d8d

+ 245 - 0
mk_framework/assets/script/game/component/tween/FrameAnimation.ts

@@ -0,0 +1,245 @@
+const { ccclass, property, executeInEditMode, playOnFocus } = cc._decorator;
+
+/**
+ * 帧动画播放组件
+ * ### 开放的接口;
+ * #### play 播放
+ * #### stop 停止播放
+ * #### gotoAndPlay 跳转到某帧并播放
+ * #### gotoAndStop 跳转到某帧并停止播放
+ * #### isPlayEnd 是否播放结束
+ * @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();
+    /** 编辑器预览 bug待修复*/
+    // private _edit_play: boolean = false;
+    // @property({ displayName: '编辑器预览' })
+    // get edit_play(): boolean {
+    //     if (this._edit_play && this.frameNum) {
+    //         this.play();
+    //         this._edit_play = false;
+    //         cc.log(this._edit_play)
+    //     }
+    //     this.running = this._edit_play;
+    //     return this._edit_play;
+    // }
+    // set edit_play(v: boolean) {
+    //     this._edit_play = v;
+    // }
+
+    /** 动画帧数量 */
+    public frameNum: number = 0;
+    /** 当前帧下标 */
+    public frameIndex: number = 0;
+    /** 下一帧下标 */
+    public nextFrameIndex: number = 0;
+
+    public running: boolean = true;
+
+    private m_render: cc.Sprite;
+
+    private time: number = 0;
+
+    public completeTimesCallback: Function;
+
+    public completeCallback: Function;
+
+    public frameCallback: Function;
+
+    private currentTimes: number = 0;
+
+    onLoad() {
+        this.m_render = 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.m_render.spriteFrame = this.images[this.frameIndex];
+
+        if (this.m_render.spriteFrame) {
+            var rect: cc.Rect = this.m_render.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;
+        }
+    }
+
+    /**
+     * 开始播放
+     * @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.m_render) {
+            this.m_render = this.getComponent(cc.Sprite);
+        }
+
+        if (this.m_render)
+            this.m_render.spriteFrame = this.images[0];
+
+
+        if (this.m_render.spriteFrame) {
+            var rect: cc.Rect = this.m_render.spriteFrame.getRect();
+            this.node.width = rect.width;
+            this.node.height = rect.height;
+        }
+
+    }
+
+    /**
+     * 跳转到某帧并开始播放
+     * @param frameIndex 帧下标
+     */
+    public gotoAndPlay(frameIndex: number) {
+        if (!this.m_render) {
+            this.m_render = 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.m_render) {
+            this.m_render = this.getComponent(cc.Sprite);
+        }
+
+        this.m_render.spriteFrame = this.images[this.frameIndex];
+
+        if (this.m_render.spriteFrame) {
+            var rect: cc.Rect = this.m_render.spriteFrame.getRect();
+            this.node.width = rect.width;
+            this.node.height = rect.height;
+        }
+
+        this.running = false;
+    }
+    /**
+     * 是否播放结束
+     * @returns 
+     */
+    public isPlayEnd(): boolean {
+        return this.frameIndex == this.frameNum;
+    }
+}

+ 9 - 0
mk_framework/assets/script/game/component/tween/FrameAnimation.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "efc32dc9-6839-4b3d-8821-f47b199f43cb",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}