现在很多人在利用比较流行的开源游戏引擎cocos2d-x开发游戏,在游戏中免不了使用状态机,这里给大家一种我自认为好的状态机的实现O(∩_∩)O~。
先贴上代码:
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){}; };
以上为状态类代码,O(∩_∩)O~。简单的只有 三个主要调用的函数,进入,执行,离开。
然后我们继续查看下状态机的基类
////////////////////////////////////////////////////////////////////////// // /// @file 状态机基类 /// @brief 负责状态机的跳转 /// @version 2.0 ////////////////////////////////////////////////////////////////////////// #include "BaseState.h" #include <assert.h> ////////////////////////////////////////////////////////////////////////// /// @class BaseStateMachine /// @brief 状态机基类 /// /// 本类负责模板状态机的所有处理 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); } };
这个是状态机的基类,使用的时候只需要在每个具体实例中申明一个状态机的类,然后完成自己的状态类的填写,即可完成一个高质量的状态机。