mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-25 19:04:43 +00:00
161 lines
4.8 KiB
TypeScript
161 lines
4.8 KiB
TypeScript
import { sp } from "cc";
|
|
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "./GFSMBase";
|
|
import GObject from "../GObject";
|
|
import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
|
|
|
|
|
|
//动画流程信息
|
|
export interface GFSMProcessAnimInfo extends GFSMProcessInfo{
|
|
//动画名称
|
|
animName:string;
|
|
//是否循环播放
|
|
isLoop?:boolean;
|
|
//与下一个动作的融合值
|
|
mixs?:number[];
|
|
//播放的轨道
|
|
track?:sp.spine.TrackEntry;
|
|
//条件跳转
|
|
ifTo?:(() => boolean)[];
|
|
}
|
|
|
|
//动画状态机基类
|
|
export abstract class GFSMAnimBase extends GFSMBase{
|
|
|
|
//轨道的索引
|
|
trackIndex:number;
|
|
|
|
//动画Root
|
|
spine:sp.Skeleton;
|
|
|
|
events:{[key:string]:Function[]}= {};
|
|
starts:{[key:string]:Function[]}= {};
|
|
ends:{[key:string]:Function[]}= {};
|
|
|
|
constructor(spine:sp.Skeleton,trackIndex:number = 0){
|
|
super();
|
|
this.spine = spine;
|
|
this.trackIndex = trackIndex;
|
|
|
|
spine.timeScale = 1.25;
|
|
|
|
//设置监听
|
|
this.spine.setEventListener(this.onEventListener.bind(this));
|
|
//设置结束监听
|
|
this.spine.setCompleteListener(this.onEndListener.bind(this));
|
|
// //因为SpineBUG所以不使用Spine监听 采用自己调用
|
|
// this.spine.setStartListener(this.onStartListener.bind(this));
|
|
}
|
|
|
|
open(){
|
|
super.open();
|
|
//重置
|
|
Object.values(this.process).forEach(info => {
|
|
info.track = null;
|
|
})
|
|
}
|
|
|
|
//添加事件监听
|
|
addEventListener(event:string,fun:Function){
|
|
if(!this.events[event]) this.events[event] = [];
|
|
this.events[event].push(fun);
|
|
}
|
|
|
|
//监听动画开始播放
|
|
addStartListener(name:string,fun:Function){
|
|
if(!this.starts[name]) this.starts[name] = [];
|
|
this.starts[name].push(fun);
|
|
}
|
|
//监听动画结束播放
|
|
addEndListener(name:string,fun:Function){
|
|
if(!this.ends[name]) this.ends[name] = [];
|
|
this.ends[name].push(fun);
|
|
}
|
|
|
|
//删除事件监听
|
|
delEventListener(event:string,fun:Function){
|
|
if(!this.events[event]) this.events[event] = [];
|
|
let index = this.events[event].indexOf(fun);
|
|
if(index >= 0) this.events[event].splice(index,1)
|
|
}
|
|
|
|
//删除动画开始播放
|
|
delStartListener(name:string,fun:Function){
|
|
if(!this.starts[name]) this.starts[name] = [];
|
|
let index = this.starts[name].indexOf(fun);
|
|
if(index >= 0) this.starts[name].splice(index,1)
|
|
}
|
|
//删除动画结束播放
|
|
delEndListener(name:string,fun:Function){
|
|
if(!this.ends[name]) this.ends[name] = [];
|
|
let index = this.ends[name].indexOf(fun);
|
|
if(index >= 0) this.ends[name].splice(index,1)
|
|
}
|
|
|
|
onEventListener(entry: sp.spine.TrackEntry, ev: sp.spine.Event){
|
|
if(!this.events[ev.data.name]) this.events[ev.data.name] = [];
|
|
this.events[ev.data.name].forEach(fun => {
|
|
fun();
|
|
});
|
|
}
|
|
|
|
onStartListener(entry: sp.spine.TrackEntry){
|
|
if(!this.starts[entry.animation.name]) this.starts[entry.animation.name] = [];
|
|
this.starts[entry.animation.name].forEach(fun => {
|
|
fun();
|
|
});
|
|
}
|
|
|
|
onEndListener(entry: sp.spine.TrackEntry){
|
|
if(!this.ends[entry.animation.name]) this.ends[entry.animation.name] = [];
|
|
this.ends[entry.animation.name].forEach(fun => {
|
|
fun();
|
|
});
|
|
}
|
|
|
|
// 流程图
|
|
process: { [key: number]: GFSMProcessAnimInfo; } = {}
|
|
|
|
execute(process:GFSMProcessAnimInfo,dt:number,frame:JNFrameInfo){
|
|
process.ifTo = process.ifTo || [];
|
|
process.to = process.to || [];
|
|
process.mode = GFSMProcessMode.WaitExecute;
|
|
process.execute = this.tick.bind(this);
|
|
super.execute(process,dt,frame);
|
|
}
|
|
|
|
//-1 继续播放 0 重新执行流程 * 指定分支
|
|
tick(dt:number,info:GFSMProcessAnimInfo,frame:JNFrameInfo){
|
|
|
|
//判断是否会切换动画 (默认不切换)
|
|
let to = GFSMProcessEnum.Wait;
|
|
info.ifTo.forEach((run,index) => {
|
|
if(run()){
|
|
to = info.to[index];
|
|
}
|
|
});
|
|
|
|
if(to >= 0) {
|
|
//和下一个动作融合
|
|
let mix = info.mixs[to - 1] || 0;
|
|
if(mix){
|
|
//设置融合
|
|
this.spine.setMix(info.animName,this.process[to].animName,mix);
|
|
}
|
|
info.track = null;
|
|
return to;
|
|
}
|
|
|
|
//播放动画
|
|
if(!info.track){
|
|
// console.log(`${frame.index} 播放动画-${this.spine.getComponent(GObject).nId}-`,info);
|
|
info.track = this.spine.setAnimation(this.trackIndex,info.animName,!!info.isLoop);
|
|
this.onStartListener(info.track);
|
|
}
|
|
|
|
return to;
|
|
|
|
}
|
|
|
|
}
|
|
|