基于状态机的游戏框架

Posted mthoutai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于状态机的游戏框架相关的知识,希望对你有一定的参考价值。

一 定义

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

以上是关于基于状态机的游戏框架的主要内容,如果未能解决你的问题,请参考以下文章

基于ET6框架的声音组件

基于状态机的乐观锁 ——解决幂等性问题

unity动画一个片段播放完怎么让它不会到初始状态

几种有限状态机的实现

Backbone.js 状态管理/基于 url 片段的视图初始化

Unity中状态机的使用