主页


状态机的实现

现在很多人在利用比较流行的开源游戏引擎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 状态机基类  
///  
/// \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);  
    }  
};  

  这个是状态机的基类,使用的时候只需要在每个具体实例中申明一个状态机的类,然后完成自己的状态类的填写,即可完成一个高质量的状态机。

posted @ 2014-10-20 11:33  百年工作经验  阅读(408)  评论(0编辑  收藏  举报