什么是状态机?
做产品的时候,我们总能遇到一些比较复杂的逻辑问题,而普通的流程图,或时序图对于对象和状态的解读缺乏直观的描述。
这里我们推荐使用简单的状态图来对逻辑问题进行描述:
有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。
简易状态机
public class FSMLite
{
public delegate void FSMCallfunc(params object[] param);
class FSMState
{
public string Name;
public FSMState(string name)
{
Name = name;
}
public readonly Dictionary<string, FSMTranslation> TranslationDict = new Dictionary<string, FSMTranslation>();
}
public class FSMTranslation
{
public string FromState;
public string Name;
public string ToState;
public FSMCallfunc OnTranslationCallback; // 回调函数
public FSMTranslation(string fromState, string name, string toState, FSMCallfunc onTranslationCallback)
{
FromState = fromState;
ToState = toState;
Name = name;
OnTranslationCallback = onTranslationCallback;
}
}
string mCurState;
public string State
{
get { return mCurState; }
}
Dictionary<string, FSMState> mStateDict = new Dictionary<string, FSMState>();
public void AddState(string name)
{
mStateDict[name] = new FSMState(name);
}
public void AddTranslation(string fromState, string name, string toState, FSMCallfunc callfunc)
{
mStateDict[fromState].TranslationDict[name] = new FSMTranslation(fromState, name, toState, callfunc);
}
public void Start(string name)
{
mCurState = name;
}
public void HandleEvent(string name, params object[] param)
{
if (mCurState != null && mStateDict[mCurState].TranslationDict.ContainsKey(name))
{
var tempTranslation = mStateDict[mCurState].TranslationDict[name];
tempTranslation.OnTranslationCallback(param);
mCurState = tempTranslation.ToState;
}
}
public void Clear()
{
mStateDict.Clear();
}
}
使用(伪代码)
mPlayerFsm = new FSMLite();
// 添加状态
mPlayerFsm.AddState(STATE_DIE);
mPlayerFsm.AddState(STATE_RUN);
mPlayerFsm.AddState(STATE_JUMP);
mPlayerFsm.AddState(STATE_DOUBLE_JUMP);
mPlayerFsm.AddState(STATE_DIE);
// 添加跳转
mPlayerFsm.AddTranslation(STATE_RUN, EVENT_TOUCH_DOWN, STATE_JUMP, JumpThePlayer);
mPlayerFsm.AddTranslation(STATE_JUMP, EVENT_TOUCH_DOWN, STATE_DOUBLE_JUMP, DoubleJumpThePlayer);
mPlayerFsm.AddTranslation(STATE_JUMP, EVENT_LAND, STATE_RUN, RunThePlayer);
mPlayerFsm.AddTranslation(STATE_DOUBLE_JUMP, EVENT_LAND, STATE_RUN, RunThePlayer);
// 启动状态机
mPlayerFsm.Start(STATE_RUN);
有限状态机维护的是一个跳转图, 好比我从 STATE_RUN 到 STATE_JUMP 跑到跳的状态,那么当接收到 TOUCH_DOWN 事件的时候,则开始转换状态。
发现一个很大的缺点是,一旦这个图复杂后,这些状态的转换将会非常复杂,所以有限状态机并不太适合很复杂的 ai 逻辑。