zoukankan      html  css  js  c++  java
  • Unity---游戏设计模式(8)之状态模式(有限状态机FSM)




    概述参考请看 参考博客

    1、原型

    原型代码

    
    /// <summary>
    /// 转换条件(就是UML图中的箭头)
    /// </summary>
    public enum Transition
    {
        NullTransition = 0,
    }
    /// <summary>
    /// 要转换到的状态(就是箭头所指的状态)
    /// </summary>
    public enum StateID
    {
        NullStateID = 0,
    }
    
    /// <summary>
    /// 代表一个角色状态
    /// </summary>
    public abstract class FSMState
    {
        //存储这个状态的所有转变条件和转变后的状态
        protected Dictionary<Transition, StateID> mMap = new Dictionary<Transition, StateID>();
        //表示此类为哪个状态
        protected StateID mStateID;
        public StateID StateID { get { return mStateID; } }
    
        /// <summary>
        /// 向字典中添加状态转变条件
        /// </summary>
        public void AddTransition(Transition trans, StateID id)
        {
            if (trans == Transition.NullTransition)
            {
                Debug.LogError("FSMState ERROR: NullTransition 不可添加");
                return;
            }
    
            if (id == StateID.NullStateID)
            {
                Debug.LogError("FSMState ERROR: NullStateID 不可添加");
                return;
            }
    
            if (mMap.ContainsKey(trans))
            {
                Debug.LogError("FSMState ERROR: State " + mStateID.ToString() + "已经有这个转换条件" + trans.ToString());
                return;
            }
            mMap.Add(trans, id);
        }
    
        /// <summary>
        /// 向字典中删除状态转变条件
        /// </summary>
        public void DeleteTransition(Transition trans)
        {
            if (mMap.ContainsKey(trans) == false)
            {
                Debug.LogError("删除转换条件时,转换条件" + trans + "不存在");
                return;
            }
            mMap.Remove(trans);
        }
    
        /// <summary>
        /// 根据状态转变条件得到状态
        /// 根据key得到value
        /// </summary>
        public StateID GetOutputState(Transition trans)
        {
            if (mMap.ContainsKey(trans))
            {
                return mMap[trans];
            }
            return StateID.NullStateID;
        }
    
        /// <summary>
        /// 进入状态时的执行
        /// </summary>
        public virtual void DoBeforeEntering() { }
    
        /// <summary>
        /// 离开状态时的执行
        /// </summary>
        public virtual void DoBeforeLeaving() { }
    
        /// <summary>
        /// 在这个状态时所要执行的游戏逻辑
        /// </summary>
        public abstract void Act(GameObject player, GameObject npc);
    
        /// <summary>
        /// 判断当前状态是否需要转变为其他状态
        /// </summary>
        public abstract void Reason(GameObject player, GameObject npc);
    
    }
    
    /// <summary>
    /// 状态管理系统
    /// </summary>
    public class FSMSystem
    {
        private List<FSMState> mStates;
    
    	private StateID mCurrentStateID;
        public StateID CurrentStateID { get { return mCurrentStateID; } }
        private FSMState mCurrentState;
        public FSMState CurrentState { get { return mCurrentState; } }
    
        public FSMSystem()
        {
            mStates = new List<FSMState>();
        }
    
        /// <summary>
        /// 添加状态
        /// </summary>
        public void AddState(FSMState state)
        {
            if (state == null)
            {
                Debug.LogError("SoldierFSMSystem Error,状态不能为空");
                return;
            }
            if (mStates.Count == 0)
            {
                mStates.Add(state);
                mCurrentState = state;
    			mCurrentStateID = state.StateID;
                return;
            }
            //判断此状态是否已经存在
            foreach (FSMState s in mStates)
            {
                if (s.StateID == state.StateID)
                {
                    Debug.LogError("要添加的状态ID[" + s.StateID + "]已经添加");
                    return;
                }
            }
            mStates.Add(state);
        }
    
        /// <summary>
        /// 删除状态
        /// </summary>
        public void DeleteState(StateID id)
        {
            if (id == StateID.NullStateID)
            {
                Debug.LogError("要删除的状态ID为空" + id);
                return;
            }
            foreach (FSMState s in mStates)
            {
                if (s.StateID == id)
                {
                    mStates.Remove(s);
                    return;
                }
            }
            Debug.LogError("要删除的StateID不存在集合中:" + id);
        }
    
        /// <summary>
        /// 执行状态的转变
        /// </summary>
        public void PerformTransition(Transition trans)
        {
            if (trans == Transition.NullTransition)
            {
                Debug.LogError("要执行的转换条件为空 : " + trans);
                return;
            }
            StateID nextStateID = mCurrentState.GetOutputState(trans);
            if (nextStateID == StateID.NullStateID)
            {
                Debug.LogError("在转换条件 [" + trans + "] 下,没有对应的转换状态");
                return;
            }
    		
    		mCurrentStateID = nextStateID;
            foreach (FSMState s in mStates)
            {
                if (s.StateID == nextStateID)
                {
                    mCurrentState.DoBeforeLeaving();
                    mCurrentState = s;
                    mCurrentState.DoBeforeEntering();
                    return;
                }
            }
        }
    }
    
  • 相关阅读:
    java Map集合学习
    java web 中的WEB-INF文件夹
    java web 通过前台输入的数据(name-value)保存到后台 xml文件中
    java web前端调试手段
    java学习之多线程
    java 反射学习
    java web前端easyui(layout+tree+双tabs)布局+树+2个选项卡tabs
    java socket编程(也是学习多线程的例子)详细版----转
    rman
    oracle 分区 查询
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/11693446.html
Copyright © 2011-2022 走看看