小妖精的完美游戏教室——人工智能,状态机实现篇

  今天也要直播魔法,求科学的!

  欢迎来到小妖精Balous的完美游戏教室!

  上一次,小妖精Balous讲述了有关状态机的理论,现在,就让我们来看看状态机是如何实现的吧(^_^)!

  在这之前,我们需要明确一点,状态机除了能用于怪物的人工智能外,还能用于控制游戏的状态,比如游戏进行中,游戏暂停等,还能用于章节选择,比如现在是标题画面,现在是第一章,现在是隐藏章节等。所以说,状态机的用处非常广,为了适应不同的需求,我们要把状态机做成泛型类:

  public class StateMachine<T> { }

  就像上面这个样子。然后,一台状态机需要控制不同状态之间的自动转换,所以,我们还需要一个抽象的状态泛型类:

  public abstract class State<T> { }

  有了这两个类,就能实现状态机了。

  State<T>类有三个方法,分别是Enter(),Execute(),Exit(),其中Enter()只会在进入本状态时调用一次,Exit()只会在退出本状态时调用一次,Execute()则会在本状态时不断调用。这种3E结构基本能应对你遇到的绝大多数情况。State<T>的完整定义如下:

  public abstract class State<T>
  {
    public virtual void Enter(T owner) { }
    public abstract void Execute(T owner);
    public virtual void Exit(T owner) { }
  }

  接下来,是StateMachine<T>类了,这个类负责State的自动转换,这个过程不需要程序员去控制,代码完全能够实现自动化。既然是负责State的自动转换,那么StateMachine<T>里面肯定就要有State的引用,所以,StateMachine<T>里面的成员变量有:

  private T owner; 

  public State<T> currentState
  {
    set
    {
      _previousState = _currentState;
      if (_currentState != null) _currentState.Exit(owner);
      _currentState = value;
      _currentState.Enter(owner);
    }
    get{ return _currentState; }
  }
  private State<T> _currentState;

  public State<T> previousState
  {
    get{ return _previousState; }
  }
  private State<T> _previousState;

  public State<T> globalState
  {
    set;
    get;
  }

  从设计角度来说,全局状态globalState是非常有用的,而上一个状态previousState则能让我们可以撤销返回。所以,上面就是完整的StateMachine<T>的成员变量了。

  接下来是成员方法,成员方法负责自动实现状态转换与刷新,并提供撤销返回:

  public void Refresh()
  {
    if (globalState != null) globalState.Execute(owner);
    if (currentState != null) currentState.Execute(owner);
  }

  public void RevertToPreviousState()
  {
    currentState = previousState;
  }

  最后就是构造器了:

  public StateMachine(T owner)
  {
    this.owner = owner;
    _currentState = null;
    _previousState = null;
    globalState = null;
  }

  拥有上面的全部组件后,一台通用的状态机就搭建完毕了。米娜桑赶紧去试试吧,能做出各种花样的人工智能哦~

  什么?你还没听懂?回去试试就懂了,代码怎么可能学懂嘛,要实践才行哒!

  那么,下周我们再见面咯~~

原文地址:https://www.cnblogs.com/balous/p/6713321.html