有限状态机/FSM(Finite State Machine)

有限状态机(Finite State Machine, FSM)是一种用于描述对象在不同状态之间转换的模型,广泛应用于游戏开发、嵌入式系统、协议设计等领域。FSM 通过预定义的状态和事件触发机制,控制对象的行为和响应。


🧠 基本概念

概念 含义
状态(State) 对象在某一时刻的行为特征或行为模式
事件(Event/Trigger) 触发状态变化的外部或内部条件
转移(Transition) 状态之间的切换过程
动作(Action) 在进入某个状态或发生转移时执行的操作

🔄 示例:游戏中的角色状态机

一个简单的角色 FSM 可能包含以下内容:

  • 状态

    • Idle(空闲)
    • Walking(行走)
    • Running(奔跑)
    • Jumping(跳跃)
    • Attacking(攻击)
  • 事件

    • KeyPress.W
    • KeyPress.Shift
    • KeyPress.Space
    • AttackButton
  • 转移规则

    • Idle + KeyPress.W → Walking
    • Walking + KeyPress.Shift → Running
    • Walking + KeyPress.Space → Jumping
    • Walking + AttackButton → Attacking
  • 动作

    • 进入 Walking 时播放行走动画
    • 进入 Jumping 时播放跳跃音效
    • 进入 Attacking 时触发伤害判定

⚙️ FSM 的实现方式

1. 枚举 + 条件判断(简单实现)

ts
 
enum PlayerState { Idle, Walking, Running, Jumping, Attacking } let state = PlayerState.Idle; function onKeyPress(key: string) { if (state === PlayerState.Idle && key === 'W') { state = PlayerState.Walking; playWalkAnimation(); } }

2. 状态类 + 接口(面向对象实现)

ts
 
interface State { onEnter(): void; onExit(): void; onUpdate(deltaTime: number): void; } class IdleState implements State { onEnter() { console.log("进入空闲状态"); } onExit() {} onUpdate(dt) {} } class WalkingState implements State { onEnter() { playWalkAnimation(); } onExit() {} onUpdate(dt) {} } class FSM { private currentState: State; changeState(newState: State) { this.currentState.onExit(); this.currentState = newState; this.currentState.onEnter(); } update(dt: number) { this.currentState.onUpdate(dt); } }

3. 使用 FSM 库 / 引擎支持

很多游戏引擎(如 Unity、Cocos Creator、Godot)都提供了 FSM 插件或内置状态机系统,例如:

  • Unity 的 Animator + StateMachine
  • Cocos Creator 的 FSM 插件
  • 自定义 FSM 工具库(如 XState

🎮 FSM 在游戏开发中的典型应用场景

场景 使用 FSM 的好处
玩家角色控制 明确状态切换逻辑,避免“if-else”地狱
敌人 AI 行为 定义巡逻、追击、攻击等状态及其转换条件
UI 状态管理 控制界面显示、隐藏、过渡动画等
游戏流程控制 如加载中、主菜单、游戏中、结算等全局状态
技能冷却系统 管理技能处于可用、冷却、激活等状态

✅ FSM 设计建议

建议 说明
清晰划分状态边界 每个状态只负责单一职责,避免重叠
统一状态变更入口 提供统一的 changeState() 方法,便于调试和日志记录
支持异步状态切换 某些状态可能需要动画或网络请求完成后才切换
可视化配置工具 使用图形化编辑器定义状态和转移,提升可维护性
状态间解耦 避免状态直接调用其他状态的方法,通过事件通信

🧩 将 FSM 应用于当前项目 GameManager.ts

你当前的游戏管理器可以引入 FSM 来管理以下状态:

状态定义:

ts
 
enum GameState { Idle, Coloring, Checking, Success, NextLevel, Victory, Fail }

状态行为示例:

ts
 
class ColoringState implements State { onEnter() { // 开始颜色调整逻辑 } onExit() { // 停止粒子效果 } } class SuccessState implements State { onEnter() { playSuccessEffect(); scheduleNextState(VictoryState, 3); } }

切换逻辑:

ts
 
if (tolerance < toleranceThreshold) { fsm.changeState(new SuccessState()); }

📌 总结

特性 FSM 的优势
结构清晰 明确状态与转换逻辑
易于维护 新增状态只需扩展,不修改原有逻辑
可复用性强 可封装为通用模块供多个对象使用
便于调试 支持状态日志输出、可视化调试

如果你希望我帮助你将 GameManager.ts 中的状态逻辑重构为 FSM 模式,我可以进一步提供详细代码结构和实现方案。

posted @ 2025-07-17 10:24  我的五年  阅读(215)  评论(0)    收藏  举报