一 定义
有限状态机就是一个具有有限数量状态,而且可以依据对应的操作从一个状态变换到还有一个状态。
而在同一时刻仅仅能处在一种状态下的智能体。
英文: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了。