一 定义
有限状态机就是一个具有有限数量状态,
并且能够根据相应的操作从一个状态变换到另一个状态,
而在同一时刻只能处在一种状态下的智能体。
英文: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了。
时间: 2024-11-12 21:27:08