現在很多人在利用比較流行的開源遊戲引擎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
這個是狀态機的基類,使用的時候隻需要在每個具體執行個體中申明一個狀态機的類,然後完成自己的狀态類的填寫,即可完成一個高品質的狀态機。注釋很全有中文的也有英文的,有興趣的童鞋可以讨論下這個設計是否合理。