程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 狀態機的實現

狀態機的實現

編輯:C++入門知識

現在很多人在利用比較流行的開源游戲引擎cocos2d-x開發游戲,在游戲中免不了使用狀態機,這裡給大家一種我自認為好的狀態機的實現O(∩_∩)O~。

先貼上代碼:


[cpp]
#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 

#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~。簡單的只有 三個主要調用的函數,進入,執行,離開。

然後我們繼續查看下狀態機的基類,廢話不多說,先上代碼,這樣新手可以直接拿走直接使用。、


[cpp]
#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 

#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
這個是狀態機的基類,使用的時候只需要在每個具體實例中申明一個狀態機的類,然後完成自己的狀態類的填寫,即可完成一個高質量的狀態機。注釋很全有中文的也有英文的,有興趣的童鞋可以討論下這個設計是否合理。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved