FSM有限状态机 ---C#、Unity
抽象类State 每个状态类都要继承State 如 GameConnectStart GameConnectIng GameConnectERROR等状态 实现抽象类的方法 在GameStateMachine来存储每个状态 以便于寻找每个状态
public interface State//定义状态接口
{
void Init();//初始化
int GetCurrentStateId();//返回当前状态Id
void ComeEvent(State state);//进入状态
void LeaveEvent(State state);//离开状态
}
抽象类StateMachine 定义抽象接口
public interface StateMachine<T>//定义状态机接口
{
T GetCurrentState();//返回当前状态
T GetPreviousState();//返回上个状态
void Register(T t);//注册状态
void RemoveState(T t);//移除状态
void SwitchState(T t);//切换状态
}
状态机GameStateMachine
public class GameStateMachine:StateMachine<State>//状态机
{
public State CurrentState = null; //当前状态
public State PrevisousState = null;//上一个状态
public Dictionary<int, State> StateDt;//状态存储
public GameStateMachine()
{
StateDt = new Dictionary<int ,State>();
}
public State GetCurrentState()
{
return CurrentState;//返回当前状态
}
public State GetPreviousState()
{
return PrevisousState;//返回上一个状态
}
public void Register(State t)
{
if (StateDt.ContainsKey(t.GetCurrentStateId()))//判断注册状态是不是已经注册 注册过return
return;
StateDt.Add(t.GetCurrentStateId(),t);//添加状态id和状态信息
}
public void RemoveState(State t)
{
if (!StateDt.ContainsKey(t.GetCurrentStateId()))//判断注册状态是不是已经注册 没注册过return
return;
StateDt.Remove(t.GetCurrentStateId());//移除状态id和状态信息
}
public void SwitchState(State t)
{
if (!StateDt.ContainsKey(t.GetCurrentStateId())) //判断当前状态有没有注册
return;
if (CurrentState !=null)//判断是不是第一次
{
if (CurrentState.GetCurrentStateId() == t.GetCurrentStateId())//判断要切换的状态和当前状态是不是相同状态
return;
CurrentState.LeaveEvent(t);//当前状态的离开方法
PrevisousState = CurrentState;//赋值给上一个状态
}
t.Init();//执行初始化
CurrentState = t;//当前状态赋值
CurrentState.ComeEvent(t);//进入状态
}
public void SwitchState(int id)
{
if (!StateDt.ContainsKey(id))//判断当前状态有没有注册
return;
State t = StateDt[id];//通过Id找到这个状态
if (CurrentState != null)
{
if (CurrentState.GetCurrentStateId() == id)
return;
CurrentState.LeaveEvent(t);
PrevisousState = CurrentState;
}
t.Init();//执行初始化
CurrentState = t;
CurrentState.ComeEvent(t);
}
}
状态机状态GameState
public enum GameState
{
GAME_CONNECT_STATE,//开始
GAME_CONNECT_ING,
GAME_CONNECT_ERROR,
GAME_CONNECT_END,
}
GameConnectStart状态
public class GameConnectStart : State
{
public void ComeEvent(State state)
{
Console.WriteLine("进入Start状态");
}
public int GetCurrentStateId()
{
return (int)GameState.GAME_CONNECT_STATE;
}
public void Init()
{
Console.WriteLine("Start状态进行初始化");
}
public void LeaveEvent(State state)
{
Console.WriteLine("Start状态结束" +(GameState)state.GetCurrentStateId() + "状态进来");
}
}
GameConnectIng状态
public class GameConnectIng : State
{
public void ComeEvent(State state)
{
Console.WriteLine("进入ING状态");
}
public int GetCurrentStateId()
{
return (int)GameState.GAME_CONNECT_ING;
}
public void Init()
{
Console.WriteLine("ING状态进行初始化");
}
public void LeaveEvent(State state)
{
Console.WriteLine("ING状态结束" + (GameState)state.GetCurrentStateId() + "状态进来");
}
}
GameConnectERROR状态
public class GameConnectERROR : State
{
public void ComeEvent(State state)
{
Console.WriteLine("进入ERROR状态 开始切换End状态");
SingletonPattern.GetInstace().SwithcStateMachine(GameState.GAME_CONNECT_END);//切换状态结束
}
public int GetCurrentStateId()
{
return (int)GameState.GAME_CONNECT_ERROR;
}
public void Init()
{
Console.WriteLine("ERROR状态进行初始化,抛出错误");
}
public void LeaveEvent(State state)
{
Console.WriteLine("ERROR状态结束" + (GameState)state.GetCurrentStateId() + "状态进来");
}
}
GameConnectEnd状态
public class GameConnectEnd : State
{
public void ComeEvent(State state)
{
Console.WriteLine("进入END状态");
}
public int GetCurrentStateId()
{
return (int)GameState.GAME_CONNECT_END;
}
public void Init()
{
Console.WriteLine("END状态进行初始化");
}
public void LeaveEvent(State state)
{
Console.WriteLine("END状态结束" + (GameState)state.GetCurrentStateId() + "状态进来 /n");
}
}
创建一个单利来执行这个状态机 (怎么执行都行~自己看着方便就行)
SingletonPattern(单利)
public class SingletonPattern
{
static SingletonPattern Instance;
GameStateMachine gameStateMachine = new GameStateMachine();//状态机
//四种状态
GameConnectStart gameConnectStart = new GameConnectStart();
GameConnectIng gameConnectIng = new GameConnectIng();
GameConnectERROR gameConnectERROR = new GameConnectERROR();
GameConnectEnd gameConnectEnd = new GameConnectEnd();
//单利
public static SingletonPattern GetInstace()
{
if (Instance == null)
{
Instance = new SingletonPattern();
}
return Instance;
}
/// <summary>
/// 状态注册
/// </summary>
public void Init()
{
gameStateMachine.Register(gameConnectStart);
gameStateMachine.Register(gameConnectIng);
gameStateMachine.Register(gameConnectERROR);
gameStateMachine.Register(gameConnectEnd);
}
/// <summary>
/// 切换状态
/// </summary>
/// <param name="state"> 状态类型 </param>
public void SwithcStateMachine(GameState state)
{
gameStateMachine.SwitchState((int)state);
}
}
在 主程序中运行
static void Main(string[] args)
{
SingletonPattern.GetInstace().Init();//注册
SingletonPattern.GetInstace().SwithcStateMachine(0);
SingletonPattern.GetInstace().SwithcStateMachine((GameState)1);
SingletonPattern.GetInstace().SwithcStateMachine((GameState)2);
Console.ReadKey();
}
FSM有限状态机 ---C#、Unity的更多相关文章
- Unity中FSM有限状态机
什么是FSM FSM 即有限状态机,它是一个状态管理系统,表示一个对象的几种状态在指定条件下转移行为,即随着条件的不断改变内部状态不断地切换. FSM用处或者使用背景 通常使用FSM去实现一些简单的A ...
- Unity——FSM有限状态机
FSM有限状态机 一.设计思路 1.共同的状态父类,提供可重写的进入,保持,退出该状态的生命周期方法: 2.状态机,管理所有状态(增删查改),状态机运行方法(Run): 3.在角色控制器中,实例化状态 ...
- FSM有限状态机
1.什么是有限状态机 有限状态机(Finite State Machine),简称FSM,它由一组有限个状态.输入和根据输入及现有状态转换为下一个状态的转换函数组成,当然,通常每个状态机都必须有一个初 ...
- Unity FSM 有限状态机
翻译了一下unity wiki上对于有限状态机的案例,等有空时在详细写一下.在场景中添加两个游戏物体,一个为玩家并修改其Tag为Player,另一个为NPC为其添加NPCControl脚本,并为其将玩 ...
- 使用 Unity 3D 开发游戏的架构设计难点
Unity 3D 引擎对于开发者来说,入手非常快,因为它采用的是 C# 作为开发语言,这也大大降低了开发者的门槛.但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D ...
- Lua中使用状态机FSM简单例子
FSM 有限状态机: 一个有限状态机是一个设备,或者是一个设备模型,具有有限数量的状态,它可以在任何给定的时间根据输入进行操作,使得一个状态变换到另一个状态,或者是使一个输入或者一种行为的发生.一个有 ...
- 新FSM的一些思路
好久之前写过一篇关于状态机的小例子,可以看这里http://www.cnblogs.com/mawanli/p/5966080.html,这篇博客首先感谢需要感谢当时看到凉鞋的笔记博客, 凉鞋的博客地 ...
- U3D-FSM有限状态机的简单设计
http://coder.beitown.com/archives/592 在之前的文章里介绍了一个基础U3D状态机框架(Unity3D游戏开发之状态流框架)即大Switch的枚举状态控制.这种方法虽 ...
- Unity 游戏框架搭建 (十) QFramework v0.0.2小结
从框架搭建系列的第一篇文章开始到现在有四个多月时间了,这段时间对自己来说有很多的收获,好多小伙伴和前辈不管是在评论区还是私下里给出的建议非常有参考性,在此先谢过各位. 说到是一篇小节,先列出框架的概要 ...
随机推荐
- 拎壶冲冲冲专业砸各种培训机构饭碗篇----python自学(一)
本人一直从事运维工程师,热爱运维,所以从自学的角度站我还是以python运维为主. 一.python自学,当然少不了从hello world开始,话不多说,直接上手练习 1.这个可以学会 print( ...
- 百度艾尼(ERNIE)常见问题汇总及解答
一.ERNIE安装配置类问题 Q1:最适合ERNIE2.0的PaddlePaddle版本是?A1:PaddlePaddle版本建议升级到1.5.0及以上版本. Q2:ERNIE可以在哪些系统上使用?A ...
- 只需十四步:从零开始掌握Python机器学习(附资源)
转载:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源.你现在也在考虑从 Python 入门机器学习吗?本教程或许 ...
- go语言教程之浅谈数组和切片的异同
Hello ,各位小伙伴大家好,我是小栈君,上次分享我们讲到了Go语言关于项目工程结构的管理,本期的分享我们来讲解一下关于go语言的数组和切片的概念.用法和区别. 在go语言的程序开发过程中,我们避免 ...
- 深入理解计算机系统 第二章 信息的表示和处理 Part2 第二遍
<深入理解计算机系统> 第三版 第二遍读这本书,每周花两到三小时时间,能读多少读多少(这次看了 29 ~ 34 页) 第一遍对应笔记链接 https://www.cnblogs.com/s ...
- 014.Kubernetes二进制部署docker
一 部署docker 1.1 部署docker组件 docker 运行和管理容器,kubelet 通过 Container Runtime Interface (CRI) 与它进行交互. 1.2 下载 ...
- FreeSql v0.11 几个实用功能说明
FreeSql 开源发布快一年了,立志成为 .Net 平台方便好用的 ORM,仓库地址:https://github.com/2881099/FreeSql 随着不断的迭代更新,越来越稳定,也越来越强 ...
- nyoj 845-无主之地1 (struct)
845-无主之地1 内存限制:64MB 时间限制:1000ms 特判: No 通过数:8 提交数:16 难度:0 题目描述: 子晓最近在玩无主之地1,他对这个游戏的评价不错,结合了FPS与RPG元素, ...
- nyoj 779-兰州烧饼 (ceil)
779-兰州烧饼 内存限制:64MB 时间限制:1000ms 特判: No 通过数:6 提交数:8 难度:1 题目描述: 烧饼有两面,要做好一个兰州烧饼,要两面都弄热.当然,一次只能弄一个的话,效率就 ...
- SpringSecurity退出功能实现的正确方式
本文将介绍在Spring Security框架下如何实现用户的"退出"logout的功能.其实这是一个非常简单的功能,我见过很多的程序员在使用了Spring Security之后, ...