Skip to content

状态模式

通过把“状态”封装成独立类,来让对象在内部状态改变时行为也跟着变化。

适用的场景

  • 游戏角色状态机(攻击状态、移动状态、受伤状态…)

  • 网络连接(连接中、已连接、断开中…)

  • 表单状态、流程节点、动画控制器等

基本结构

  • Context(上下文):持有当前状态对象,根据状态调用对应行为

  • State(抽象状态类):定义所有状态通用的接口

  • ConcreteState(具体状态):各种具体状态,实现具体行为逻辑

示例

csharp
interface IState 
{
    void Handle(Character context);
}

class IdleState : IState 
{
    public void Handle(Character context) 
    {
        Console.WriteLine("站着发呆...");
        context.State = new WalkState(); // 自动转为行走状态
    }
}

class WalkState : IState 
{
    public void Handle(Character context) 
    {
        Console.WriteLine("慢悠悠走路中~");
        context.State = new AttackState();
    }
}

class AttackState : IState 
{
    public void Handle(Character context) 
    {
        Console.WriteLine("挥砍一刀!");
        context.State = new IdleState();
    }
}

class Character {
    public IState State { get; set; }

    public Character(IState initState) 
    {
        State = initState;
    }

    public void Update() 
    {
        State.Handle(this);
    }
}

// 使用:
var hero = new Character(new IdleState());
hero.Update(); // 站着发呆...
hero.Update(); // 慢悠悠走路中~
hero.Update(); // 挥砍一刀!

GDScript示例:

gdscript
class State:
    func handle(owner):
        pass

class IdleState extends State:
    func handle(owner):
        print("呆呆地站着~")
        owner.state = WalkState.new()

class WalkState extends State:
    func handle(owner):
        print("优雅地走着~")
        owner.state = AttackState.new()

class AttackState extends State:
    func handle(owner):
        print("使出必杀技!!")
        owner.state = IdleState.new()

class Character:
    var state: State = IdleState.new()

    func update():
        state.handle(self)
        
# 使用:
func _ready():
    var hero = Character.new()
    hero.update()
    hero.update()
    hero.update()