状态机的实现

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

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

时间: 2024-10-10 10:21:43

状态机的实现的相关文章

简易状态机

SimpleFSM 包含状态切换以及事件驱动传递参数 下面的代码是登录的状态码 1 using System; 2 using UnityEngine; 3 using System.Collections; 4 5 public class LoginState : SingletonPrivider<LoginState>, GameState 6 { 7 private delegate void LoginEventHandler(object sender, LoginEventAr

MediaPlayer 状态机 API 详解 示例

简介 public class android.media.MediaPlayer extends Object implements VolumeAutomation 可能需要的权限: One may need to declare a corresponding(相应) WAKE_LOCK permission <uses-permission> element. <uses-permission android:name="android.permission.WAKE_

人生就是一个状态机

从出生到死亡人生走的是一个过程. 从宏观来看,人分为幼年.青年.中年和老年:从微观来看.人每天吃饭.睡觉.学习.工作和娱乐.古语有云:良田千倾只是一日三餐.广厦万间仅仅睡卧榻三尺.不是必需我一己私利而贪得无厌.而我看来人生就如同一个大型状态机. 人生的状态机从大的方面看,它的输入为时间,输出为做出的成果.而人生的不同年龄为所处的状态.时间我们能够看做连续的,也能够看做离散的.时间在不知不觉中流逝,也在分秒钟跳变.而时间人生的输入,他使我们从孩童成长为青年,又使我们从青年变为老年,时间不会停止.输

停车场门禁控制系统的状态机

其状态机如下图: #include<iostream>using namespace std;void main(){ char enter_or_out; //1表示入闸传感器ture,0表示出闸传感器ture int up_or_downt = 0; //1表示起落杆升起,0表示起落杆落下 cout << "状态初始化..." << '\n'; cout << "当前状态为起落杆落下,红灯状态,禁止通行" <

UNITY 状态机 + SVN + 码云 下篇

上篇说到自己写的一个FSM状态机,这篇写怎么把代码和码云联系在一起! 首先,我们应该知道为什么使用码云? 码云是开源中国社区2013年推出的基于 Git 的完全免费的代码托管服务,这个服务是基于 Gitlab 开源软件所开发的,我们在 Gitlab 的基础上做了大量的改进和定制开发,目前已经成为国内最大的代码托管系统,致力于为国内开发者提供优质稳定的托管服务. 码云除了提供最基础的 Git 代码托管之外,还提供代码在线查看.历史版本查看.Fork.Pull Request.打包下载任意版本.Is

001-初识状态机

状态机 FPGA的灵魂 状态机的设计贯穿FPGA设计的始终 一.状态机的概念 1.状态机简述 状态机:描述状态变迁的状态转移图,体现系统对外界事件的反应和行为. 有限状态机(FSM):状态节点数和输入.输出范围有限的状态机. 2.状态机的组成六要素 (1)状态集合   (必备要素):包含了状态机所能达到的所有状态. (2)初态         (必备要素):是整个状态机开始工作的起点.初态是一个相对的参考态. (3)终态   () :状态机的结束状态.事实上,大部分运行在FPGA上的状态机是没有

【slighttpd】基于lighttpd架构的Server项目实战(8)—状态机机制回顾

有限状态机FSM(Finite State Machine) 关于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成.状态机通过响应一系列事件而"运行".每个事件都在属于"当前" 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集.函数返回"下一个"(也许是同一个)节点.这些节点中至少有一个必须是终态.当到达终态, 状态机停止. 传统应用程序的控制流程基本是顺序的:遵循事先设定的逻辑,从头到尾地执行.很少有事

三、状态机的设计指导原则

---恢复内容开始--- 1.状态机设计关键是什么? 如何才能把一个电路系统抽象为一个或者多个相互配合嵌套的状态机和组合系统模块?是关键. ---恢复内容结束--- 1.状态机设计关键是什么? 如何才能把一个电路系统抽象为一个或者多个相互配合嵌套的状态机和组合系统模块?是关键.

用状态机来设计cell动画

前言 一个cell可能有好几种状态,比方说选中状态与未选中状态,以及失效状态等等状态,我们将这些不同的情形抽象成一个个状态机,用状态机切换逻辑来设计复杂的动画效果,达到简化设计的目的,大大增加程序可维护性. * 大家需要注意一点,cell因为是可以复用的控件,因为存在复用,所以里面存在较为恶心的复用逻辑,设计动画接口时是需要注意这些小细节的.(亲手写过的人一定会深有体会) 效果 源码 https://github.com/YouXianMing/CellStateAnimation // //

处理浮点数的状态机

这个问题来自于 leetcode 065: Valid Number 如果用正则表达式来写一个浮点数的解析,大概是这样的: [+-]?(([0-9]+\.?) | (\.[0-9]))[0-9]*([eE][+-]?[0-9]+)? 我自己使用 dot 画了一个状态机出来: 如果编写代码来模拟这个状态机,可以拆分为 “eE" 前后两部分分开处理: “eE” 前面的部分,还可以拆成 “.” 前后两部分(如果有点)来编写. 这道题目在 leetcode 上难度为 Hard,可以看出来这种不起眼的小细