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