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