综合---有限状态机实例(附带普通状态模式)
来源:互联网 发布:对冲平仓 知乎 编辑:程序博客网 时间:2024/06/05 04:30
1.枚举的切换条件
//有哪些状态切换条件
public enum ETransition
{
NullTransition =0,
SawPlayer,//看见主角
LosePlay//丢失主角
}
2.枚举的所有状态(唯一状态)
//状态id,表示有哪些状态,每一个状态的唯一标志,
public enum EStateID
{
NullStateID = 0,
Patrol,//巡逻状态
Chase//追逐状态
}
3.抽象的状态类State
public abstract class FSMState{
//状态对应的ID,我们为了方便的获取FSMState
protected EStateID m_stateID;
//指定某个状态是由哪个状态机控制的,哪怕是同一类的两个敌人,也有两个状态机
public FSMSystem m_system;
public EStateID m_StateID { get{return m_stateID; }}
protected Dictionary<ETransition, EStateID> m_tranDic;
protected FSMState()
{
m_tranDic = new Dictionary<ETransition, EStateID>();
}
//1.添加一个在该状态可以通过某个条件切换到某个状态
public void _AddTransition(ETransition tran,EStateID id)
{
if (tran == ETransition.NullTransition || id == EStateID.NullStateID)
{
Debug.LogError("you add a null ERtansition or a null EStateID");
return;
}
if (m_tranDic.ContainsKey(tran))
{
Debug.LogError("m_tranDic is alreadey contains the key");
return;
}
m_tranDic.Add(tran, id);
}
//2.删除一个在该状态的切换条件
public void _DeleteTransition(ETransition tran)
{
if (m_tranDic.ContainsKey(tran) == false)
{
Debug.LogWarning("you want to delete a not exist key" + tran);
return;
}
m_tranDic.Remove(tran);
}
//3.通过某个切换条件得到这个条件要切换的状态
public EStateID _GetStateID(ETransition tran)
{
if (m_tranDic.ContainsKey(tran))
{
return m_tranDic[tran];
}
return EStateID.NullStateID;
}
//在某个状态进入之前要做的动作
public virtual void _OnEnterBefore() { }
//在某个状态持续中要做的动作
public abstract void _OnStayUpdate();
//在某个状态即将推出的时候要做的动作
public virtual void _OnQuitBefore() { }
}
4.所有的状态管理类:状态机System
public class FSMSystem
{
//当前状态机有哪些状态
private Dictionary<EStateID, FSMState> m_statesDic;
//状态机处于什么状态
private FSMState m_currentState;
public FSMState m_CurrentState {get{ return m_currentState;} }
public FSMSystem()
{
m_statesDic = new Dictionary<EStateID, FSMState>();
}
//1.在一个特定的某个角色的状态机上,标志哪个状态是开始状态
public void _StartFSM(EStateID startStateID)//即为图中的Register方法,注意的是:只指定开始状态是谁,而不是指定状态机是谁
{
FSMState state;
bool isGet = m_statesDic.TryGetValue(startStateID,out state);
if (state == null)
{
Debug.Log(startStateID + " not exist fsmState");
}
else
{
m_currentState = state;
m_currentState._OnEnterBefore();
}
}
//2.给某个角色状态机添加一个状态(该状态的枚举和该状态)
public void _AddStateID(FSMState state)
{
if (state == null)
{
Debug.LogError("id is null of nullStateID");
return;
}
if (m_statesDic.ContainsKey(state.m_StateID))
{
Debug.Log(state + "the staete is already exist");
}
m_statesDic.Add(state.m_StateID, state);
//设置这个状态的状态机是谁,每个敌人的状态机都是不相同的,这就是初始化的过程
state.m_system = this;
}
public void _DeleteState(FSMState state)
{
if (m_statesDic.ContainsKey(state.m_StateID) == false)
{
Debug.Log(state + " is not exist");
}
else
m_statesDic.Remove(state.m_StateID);
}
//3.在当前状态下给予一个切换条件,如果成立,则切换到另外状态
public void _PerformTransition(ETransition tran)
{
if (tran == ETransition.NullTransition)
{
Debug.Log("tran is nullTransiion"); return;
}
EStateID id = m_currentState._GetStateID(tran);
if (id == EStateID.NullStateID)
{
Debug.Log("transition is not be happend"); return;
}
FSMState state;
m_statesDic.TryGetValue(id, out state);
//当前状态退出
m_CurrentState._OnQuitBefore();
//切换到一个新状态
m_currentState = state;
m_currentState._OnEnterBefore();
}
}
5.继承了状态类的某个NPC
public class NPCControl : MonoBehaviour {
private FSMSystem m_fsm;
public GameObject m_npc;
public Transform[] m_pathPointTras;
public Transform m_target;
void Start()
{
_InitFSM();
}
void Update()
{
//调用当前状态的持续方法
m_fsm.m_CurrentState._OnStayUpdate();
}
void _InitFSM()
{
m_fsm = new FSMSystem();
PatrolState patrolState = new PatrolState(m_pathPointTras,m_npc,m_target);
patrolState._AddTransition(ETransition.SawPlayer, EStateID.Chase);
ChaseState chaseState = new ChaseState(m_npc,m_target);
chaseState._AddTransition(ETransition.LosePlay, EStateID.Patrol);
m_fsm._AddStateID(patrolState);
m_fsm._AddStateID(chaseState);
m_fsm._StartFSM(EStateID.Patrol);
}
}
6.该NPC的行为之一:巡逻
需要在里面设置他所属的的State
做具体的事情以及切换到其他状态
7.该NPC的行为之二:追逐
做具体的事情以及切换到其他状态
附带普通的状态模式
//一个引用状态的类
class Context
{
IState state;
//指定初始化的状态
public void _SetState(IState state)
{
this.state = state;
}
public void _Show(int arg)
{
state._Show(arg);
}
}
//状态类接口
interface IState
{
void _Show(int arg);
}
class StateA:IState
{
Context c;
//指定他所属于哪个调用他的类
public StateA(Context c)
{
this.c = c;
}
public void _Show(int arg)
{
if (arg > 10)
{
Debug.Log("开始处理");
}
else
{
Debug.Log("处理不了,开始转换");
//否则的话切换状态
c._SetState(new StateB(c));
}
}
}
class StateB : IState
{
Context c;
public StateB(Context c)
{
this.c = c;
}
public void _Show(int arg)
{
if (arg < 10)
{
Debug.Log("开始处理");
}
else
{
Debug.Log("处理不了,开始转换");
c._SetState(new StateA(c));
}
}
}
//调用在unity里调用
public class StatePattern : MonoBehaviour {
void Start()
{
Context c = new Context();
c._SetState(new StateA(c));
c._Show(15);
c._Show(5);
c._Show(5);
c._Show(35);
c._Show(25);
}
}
- 综合---有限状态机实例(附带普通状态模式)
- Atitit. 有限状态机 fsm 状态模式
- 状态模式学习笔记 --有限状态机的实现
- 有限状态机(使用状态模式C++实现)
- 有限状态机(使用状态模式C++实现)
- 设计模式——状态模式(有限状态机)
- 状态模式与有限状态机-应用(游戏开发)
- 状态模式使用实例
- 设计模式----状态模式 实例
- php设计模式实例详解(综合)
- 精通23种设计模式综合实例
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
- 【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现
- 【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现
- 【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现
- 【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现
- 状态模式的实例学习
- 使用Spring的@Scheduled实现定时任务
- 使用JDBC进行数据库的事务操作(2)
- Android 优化之 纹理
- linux中vi怎么根据关键词查找
- inout用法浅析
- 综合---有限状态机实例(附带普通状态模式)
- hdu 1269 迷宫城堡 java
- top命令动态监控进程
- 配置数据源
- 五分钟学GIS | iMobile for ReactNative安装及使用
- android studio ndk 资料整理
- Eclipse使用EGit插件连接Github的设置(一):Push篇
- ROS Robotics Projects(9)虚拟现实VR头戴设备和Leap Motion手势操控
- Re:从0开始的微服务架构:(一)重识微服务架构 http://www.infoq.com/cn/articles/micro-service-architecture-from-zero#0-you