//************************ // Create By 流云 // Time: 2021.01.18 // Desc: 帧动画组件 //************************ import { Component, director, game, Sprite, SpriteFrame, _decorator } from "cc"; const { ccclass, property, executeInEditMode } = _decorator; /** * 帧动画组件 * 使用方法: * 1.挂载该组件到节点上 * 2.在编辑器中,将需要播放的帧动画拖入Frames数组中 * 3.设置PlayOnload为true,即可在节点加载时自动播放 * 4.设置Duration为每帧的时间,默认为0.1秒 * 5.设置IsAllsyn为true,即可保持同步播放 * 6.设置Loop为true,即可循环播放 * 7.代码中可以通过play方法来播放动画,stop方法来停止动画 * 8.也可以通过代码设置Frames数组来动态改变帧动画 */ @ccclass @executeInEditMode export default class ZClips extends Component { @property(SpriteFrame) public Frames: SpriteFrame[] = []; @property public PlayOnload = false; @property public Duration = 0.1; @property private IsAllsyn = false;//保持同步 /*示例用法:场景中有10个金币道具,每个金币都有同样的帧动画,但有可能因为加载的原因,并不一定 10个金币同时play,就会出现看起来有些金币动画先播,有些后播,10个金币动画不整齐,如果将IsAllsyn设置 为true,会将帧索引以全局游戏时间为标准,不管谁先播,谁后播,在同一时间,10个金币的ZClips都会计算得到同一个 Frames的索引,保证10个金币的动画一致整齐 */ @property private Loop = false; @property private clear = false; private _sp: Sprite; private _playing = false; private _total_time = 0; private _default_sp = null; onLoad() { this._sp = this.node.getComponent(Sprite); if (!this._sp) this._sp = this.node.addComponent(Sprite); else { this._default_sp = this._sp.spriteFrame; } if (this.PlayOnload) { this.play(this.Loop, this.Duration, this.IsAllsyn); } } protected onEnable(): void { this.play(this.Loop, this.Duration, this.IsAllsyn); } update(dt) { let self = this; if (self._playing && self.Frames.length > 0) { self._total_time += dt; let index = Math.floor(self._total_time / self.Duration) % self.Frames.length; if (self.IsAllsyn) index = Math.floor(game.totalTime / 1000 / self.Duration) % self.Frames.length; if (self.Loop || index < self.Frames.length) { self._sp.spriteFrame = self.Frames[index]; } if (index >= self.Frames.length - 1 && !self.Loop) self.stop(); } } /** * 播放 * @param loop 是否循环(不传入使用编辑器赋的默认值,传入覆盖默认值) * @param duration 每帧多少秒 * @param isAllsyn 保持同步 * @returns */ play(loop = null, duration = null, isAllsyn = null) { if (this._playing) return; this._total_time = 0; this._playing = true; if (isAllsyn != null) this.IsAllsyn = isAllsyn; if (loop != null) this.Loop = loop; if (duration != null) this.Duration = duration; } stop() { this._playing = false; if (this._default_sp) { this._sp.spriteFrame = this._default_sp; return; } if (this.clear) this._sp.spriteFrame = null; } }