现在很多人在利用比较流行的开源游戏引擎cocos2d-x开发游戏,在游戏中免不了使用状态机,这里给大家一种我自认为好的状态机的实现O(∩_∩)O~。
#ifndef BASESTATE_H
#define BASESTATE_H
template <class entity_type>
class BaseState
{
public:
//BaseState(void){};
virtual void Enter(entity_type*)=0;
virtual void Execute(entity_type*)=0;
virtual void Exit(entity_type*)=0;
virtual ~BaseState(void){};
};
#endif // !BASESTATE_H
以上为状态类代码,O(∩_∩)O~。简单的只有 三个主要调用的函数,进入,执行,离开。
然后我们继续查看下状态机的基类,废话不多说,先上代码,这样新手可以直接拿走直接使用。
#ifndef BASESTATEMACHINE_H
#define BASESTATEMACHINE_H
//
//
/// @file 状态机基类
/// @brief 负责状态机的跳转
/// @version 2.0
//
#include "BaseState.h"
#include <assert.h>
//
/// @class BaseStateMachine
/// @brief 状态机基类
///
/// \n本类负责模板状态机的所有处理
template <class entity_type>
class BaseStateMachine
{
private:
entity_type *m_pOwner; ///<指向拥有这个了实例的智能体的指针
BaseState<entity_type> *m_pCurrentState; ///<智能体的当前状态
BaseState<entity_type> *m_pPreviousState; ///<智能体的上一个状态
BaseState<entity_type> *m_pGlobalState; ///<每次FSM被更新时,这个状态被调用
public:
BaseStateMachine(entity_type* owner):
m_pOwner(owner),
m_pCurrentState(nullptr),
m_pPreviousState(nullptr),
m_pGlobalState(nullptr)
{
}
///@brief 设置当前状态
///@param [in]s 要设置的状态
///@return 无返回值
void SetCurrentState(BaseState<entity_type> *s)
{
m_pCurrentState = s;
}
///@brief 设置全局状态
///@param [in]s 要设置的状态
///@return 无返回值
void SetGlobalState(BaseState<entity_type> *s)
{
m_pGlobalState = s;
}
///@brief 设置前面的状态
///@param [in]s 要设置的状态
///@return 无返回值
void SetPreviousState(BaseState<entity_type> *s)
{
m_pPreviousState = s;
}
///@brief 更新状态
///
///@return 无返回值
void Update()const
{
if (m_pGlobalState)
{
m_pGlobalState->Execute(m_pOwner);
}
if (m_pCurrentState)
{
m_pCurrentState->Execute(m_pOwner);
}
}
///@brief 改变状态
///@param [in]s 要设置的状态
///@return 无返回值
void ChangeState(BaseState<entity_type> *pNewState)
{
//assert(PNewState && "<BaseStateMachine::ChangeState>:trying to change to a null state");
///保留前一个状态记录
m_pPreviousState = m_pCurrentState;
///调用现有状态的退出方法
m_pCurrentState->Exit(m_pOwner);
///改变到一个新状态
m_pCurrentState= pNewState;
///调用新状态的进入方法
m_pCurrentState->Enter(m_pOwner);
}
///@brief 改变到上一状态
///
///@return 无返回值
void RevertToPreviousState()
{
ChangeState(m_pPreviousState);
}
///@brief 查看当前状态
///
///@return BaseState<entity_type>*当前状态
BaseState<entity_type>* CurrentState() const
{
return m_pCurrentState;
}
///@brief 查看全局状态
///
///@return BaseState<entity_type>* 全局状态
BaseState<entity_type>* GlobalState() const
{
return m_pGlobalState;
}
///@brief 查看前一状态
///
///@return BaseState<entity_type>*前一状态
BaseState<entity_type>* PreviousState() const
{
return m_pPreviousState;
}
//class passed as a parameter.
bool isInState(const BaseState<entity_type>& st)const
{
return typeid(*m_pCurrentState) == typeid(st);
}
};
#endif // !BASESTATEMACHINE_H
这个是状态机的基类,使用的时候只需要在每个具体实例中申明一个状态机的类,然后完成自己的状态类的填写,即可完成一个高质量的状态机。注释很全有中文的也有英文的,有兴趣的童鞋可以讨论下这个设计是否合理。