今天也要直播魔法,求科学的!
欢迎来到小妖精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;
}
拥有上面的全部组件后,一台通用的状态机就搭建完毕了。米娜桑赶紧去试试吧,能做出各种花样的人工智能哦~
什么?你还没听懂?回去试试就懂了,代码怎么可能学懂嘛,要实践才行哒!
那么,下周我们再见面咯~~