>>>>>
脚本组件,挂载即用。
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
>>>>>