一 定义
有限状态机就是一个具有有限数量状态,而且可以依据对应的操作从一个状态变换到还有一个状态。
而在同一时刻仅仅能处在一种状态下的智能体。
英文:Finite State Machine
简称:FSM
二 最简单的状态机
最简单的状态机:if-else实际上if-else就是一个最有两种状态的状态机。各自是true和false
三 伪状态机
当两种情况不能满足我们的需求时,我们能够用if-else if -...-else,只是,为了方便,我们能够使用switch-case取代
首先,定义一组不同的状态,我们能够使用宏定义或者枚举:
enum EState{ eState_Min, // 未初始化状态 eState_One, eState_Two, ... eState_Max, // 用于异常检測 };
定义一个对象,保存当前的状态:
EState curState = eState_Min;
如今,就能够在switch中检測当前的状态,并做出对应的处理
void update(){ switch(curState){ case eState_One: onStateOne(); break; case eState_Min: onStateTwo(); break; ... case eState_Max: break; default: // 报错 } }
然后对每种状态做不同的处理,
void onStateOne(){ } void onStateTwo(){ } ...
比如,对于一个野怪。状态一时,能够让它来回走动,并检測是否有英雄单位靠近。
当检測到有英雄靠近时,转换为状态二,攻击英雄。
全部,我们还须要一个转换状态的函数
void converToState(EState dstState){ curState = dstState; }
上面的状态机是基于C语言的实现方式,当出现一个新的状态时,须要改动对应的代码,
这样的游戏框架结构,使用与一般的小游戏。
当游戏规模较大,逻辑非常复杂后。在switch结构就会变得非常复杂。
三 真正的状态机
以下是一种用利用面向对象的多态性实现的一种状态机。首先,我们须要定义一个状态的基类,并定义一个纯虚函数。
这个纯虚函数用来处理当前状态的一些逻辑。
class BaseState{ public: virtual ~BaseState() = 0; virtual void execute() = 0; BaseState::~BaseState(){} };
然后,我们定义一个状态机类。来控制状态的转换
class FSM{ public: void converToState(BaseState *state){ if state then delete m_curState; m_curState = NULL; end m_curState = state; } void update(){ m_curState->onState() } protected: BaseState* m_curState; };
这种话我们假设须要加入一个新的状态,仅仅须要新加一个类,继承自BaseState就能够了。
比如:定义一个Monster
class Monster{ public: void update(){ m_SFM->update() } protected: FSM* m_SFM; };
再定义两个状态类,在当中运行当前状态的函数。并检測状态是否发生变化,
假设状态变化了,则切换到其它状态。
class StateMove:BaseState{ public: ~BaseState(){} void execute(){ // move,check } }; class StateFight:BaseState{ public: ~BaseState(){} void execute(){ // fight。check } };
这样,一个基于状态机的游戏框架就OK了。