• 状态机的实现


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

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

  • 相关阅读:
    火车头采集器如何采集QQ群成员中的QQ号
    Unix目录结构的来历
    加速Windows 2003关机速度的设置方法
    win2003 序列号 windows2003 sp2可用序列号大全(准版与企业版)
    自己动手在win2003系统中添加虚拟网卡
    Windows Server 2003下DHCP服务器的安装与简单配置图文教程
    win2003远程桌面怎么切换到多用户?
    Win2003打开网页时总是提示添加网址到信任站点的设置方法
    我们正在招聘java工程师,想来美团工作吗?
    JUC回顾之-AQS同步器的实现原理
  • 原文地址:https://www.cnblogs.com/junzitandandan/p/4036806.html
Copyright © 2020-2023  润新知