134 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-10-24 19:12:25 +08:00
import { sp } from "cc";
2023-11-01 02:01:35 +08:00
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "./GFSMBase";
import GObject from "../GObject";
2023-10-24 19:12:25 +08:00
//角色动画名称枚举
export enum GFSMBattleAminEnum {
Wait = "std", //等待
Walk = "walk", //移动
Attack = "atk", //攻击
Fly = "jifei", //击飞
}
//动画流程信息
export interface GFSMProcessAnimInfo extends GFSMProcessInfo{
//动画名称
animName:string;
//是否循环播放
isLoop?:boolean;
//与下一个动作的融合值
mixs?:number[];
//播放的轨道
track?:sp.spine.TrackEntry;
2023-10-25 02:31:51 +08:00
//条件跳转
2023-10-24 19:12:25 +08:00
ifTo?:(() => boolean)[];
}
//动画状态机基类
2023-11-01 02:01:35 +08:00
export abstract class GFSMAnimBase extends GFSMBase{
2023-10-25 19:19:52 +08:00
2023-10-24 19:12:25 +08:00
//轨道的索引
trackIndex:number;
//动画Root
spine:sp.Skeleton;
2023-10-25 02:31:51 +08:00
events:{event:string,fun:Function}[] = [];
2023-10-25 19:19:52 +08:00
starts:{name:string,fun:Function}[] = [];
2023-10-25 02:31:51 +08:00
2023-11-01 02:01:35 +08:00
constructor(spine:sp.Skeleton,trackIndex:number = 0){
2023-10-24 19:12:25 +08:00
super();
this.spine = spine;
2023-11-01 02:01:35 +08:00
this.trackIndex = trackIndex;
2023-10-25 02:31:51 +08:00
//设置监听
this.spine.setEventListener(this.onEventListener.bind(this));
2023-10-30 18:53:21 +08:00
//因为SpineBUG所以不使用Spine监听 采用自己调用
2023-10-31 02:34:12 +08:00
this.spine.setStartListener(this.onStartListener.bind(this));
}
open(){
super.open();
//重置
Object.values(this.process).forEach(info => {
info.track = null;
})
2023-10-24 19:12:25 +08:00
}
2023-10-25 02:31:51 +08:00
//添加事件监听
addEventListener(event:string,fun:Function){
this.events.push({
event,
fun,
})
}
2023-10-25 19:19:52 +08:00
//监听动画开始播放
addStartListener(name:string,fun:Function){
this.starts.push({
name,
fun,
})
}
2023-10-25 02:31:51 +08:00
onEventListener(entry: sp.spine.TrackEntry, ev: sp.spine.Event){
this.events.forEach(item => {
if(item.event == ev.data.name){
item.fun();
}
});
}
2023-10-24 19:12:25 +08:00
2023-10-25 19:19:52 +08:00
onStartListener(entry: sp.spine.TrackEntry){
this.starts.forEach(item => {
if(entry.animation.name == item.name){
item.fun();
}
});
}
2023-10-24 19:12:25 +08:00
// 流程图
2023-11-01 02:01:35 +08:00
process: { [key: number]: GFSMProcessAnimInfo; } = {}
2023-10-24 19:12:25 +08:00
execute(process:GFSMProcessAnimInfo,dt:number){
2023-10-25 19:19:52 +08:00
process.ifTo = process.ifTo || [];
process.to = process.to || [];
2023-10-24 19:12:25 +08:00
process.mode = GFSMProcessMode.WaitExecute;
process.execute = this.tick.bind(this);
super.execute(process,dt);
}
//-1 继续播放 0 重新执行流程 * 指定分支
tick(dt:number,info:GFSMProcessAnimInfo){
2023-10-25 19:19:52 +08:00
2023-10-24 19:12:25 +08:00
//判断是否会切换动画 (默认不切换)
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){
2023-10-30 18:53:21 +08:00
console.log(`播放动画-${this.spine.getComponent(GObject).nId}-`,info);
2023-11-01 02:01:35 +08:00
info.track = this.spine.setAnimation(this.trackIndex,info.animName,!!info.isLoop);
2023-10-24 19:12:25 +08:00
}
return to;
}
}