You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.5 KiB
113 lines
3.5 KiB
|
1 week ago
|
//************************
|
||
|
|
// 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;
|
||
|
|
}
|
||
|
|
}
|