Files
rougelike-demo/client/assets/scripts/Framework/FSM/FSM.ts
2025-12-14 22:38:43 +08:00

140 lines
3.6 KiB
TypeScript

import { IState } from "./IState";
/**
* 有限状态机 (Finite State Machine)
* 管理状态的添加、移除和切换
*/
export class FSM {
/**
* 存储所有状态的Map,键为状态名称
*/
private _states: Map<string, IState>;
/**
* 当前活动的状态
*/
private _currentState: IState | null;
/**
* 构造函数
*/
constructor() {
this._states = new Map<string, IState>();
this._currentState = null;
}
/**
* 添加状态
* @param state 要添加的状态
*/
addState(state: IState): void {
if (this._states.has(state.name)) {
console.warn(`[FSM] 状态 "${state.name}" 已存在,将被覆盖`);
}
this._states.set(state.name, state);
console.log(`[FSM] 添加状态: ${state.name}`);
}
/**
* 移除状态
* @param stateName 要移除的状态名称
*/
removeState(stateName: string): void {
if (!this._states.has(stateName)) {
console.warn(`[FSM] 状态 "${stateName}" 不存在,无法移除`);
return;
}
// 如果当前状态就是要移除的状态,先退出
if (this._currentState && this._currentState.name === stateName) {
this._currentState.onExit();
this._currentState = null;
}
this._states.delete(stateName);
console.log(`[FSM] 移除状态: ${stateName}`);
}
/**
* 切换状态
* @param stateName 要切换到的状态名称
* @param params 可选参数,传递给新状态的onEnter方法
*/
changeState(stateName: string, params?: any): void {
const newState = this._states.get(stateName);
if (!newState) {
console.error(`[FSM] 状态 "${stateName}" 不存在,无法切换`);
return;
}
// 退出当前状态
if (this._currentState) {
this._currentState.onExit();
}
// 切换到新状态
this._currentState = newState;
this._currentState.onEnter(params);
}
/**
* 获取当前状态
* @returns 当前活动的状态,如果没有状态则返回null
*/
getCurrentState(): IState | null {
return this._currentState;
}
/**
* 获取当前状态名称
* @returns 当前状态名称,如果没有状态则返回null
*/
getCurrentStateName(): string | null {
return this._currentState ? this._currentState.name : null;
}
/**
* 检查是否存在指定状态
* @param stateName 状态名称
* @returns 如果状态存在返回true,否则返回false
*/
hasState(stateName: string): boolean {
return this._states.has(stateName);
}
/**
* 获取状态
* @param stateName 状态名称
* @returns 状态实例,如果不存在则返回undefined
*/
getState(stateName: string): IState | undefined {
return this._states.get(stateName);
}
/**
* 更新状态机
* 如果当前状态实现了onUpdate方法,则调用它
* @param dt 距离上一帧的时间增量(秒)
*/
update(dt: number): void {
if (this._currentState && this._currentState.onUpdate) {
this._currentState.onUpdate(dt);
}
}
/**
* 清空所有状态
*/
clear(): void {
// 退出当前状态
if (this._currentState) {
this._currentState.onExit();
this._currentState = null;
}
this._states.clear();
console.log('[FSM] 已清空所有状态');
}
}