什么是有限状态机?

通俗点讲,有限状态机是:将对象的状态(攻击、闲置、晕眩)的实现代码,提取出来,封装成状态。由状态机负责在各个状态之间调度。

对象持有状态管理类(状态机)的引用,与具体的状态解耦。

OK,那接下来开始设计一个塔的状态,我们有一个父类FiniteState,状态机只和父类交互,屏蔽了状态具体实现

塔与状态是一对一的关系,也就是说,在塔创建的时候,全部状态已经生成好了(GenerateStateList方法), 我们根据状态的枚举类进行切换。

using System.Collections.Generic;

/// <summary>
/// 塔的状态机工具类
/// </summary>
public class TowerStateHelper
{
/// <summary>
/// 状态个数
/// </summary>
private const int STATE_COUNT = ; /// <summary>
/// 创建状态集合
/// </summary>
/// <param name="tower">作用对象</param>
/// <returns></returns>
public static Dictionary<StateType, FiniteState> GenerateStateList(TowerBase tower)
{
Dictionary<StateType, FiniteState> stateList = new Dictionary<StateType, FiniteState>(STATE_COUNT); stateList.Add(StateType.Idle, new StateIdle() { TargetTower = tower, StateTypeId = StateType.Idle });
stateList.Add(StateType.Guard, new StateGuard() { TargetTower = tower, StateTypeId = StateType.Guard });
stateList.Add(StateType.Attack, new StateAttack() { TargetTower = tower, StateTypeId = StateType.Attack });
stateList.Add(StateType.Spell, new StateSpell() { TargetTower = tower, StateTypeId = StateType.Spell }); return stateList;
}
} /// <summary>
/// 状态类型
/// </summary>
public enum StateType
{
/// <summary>
/// 不可用
/// </summary>
Innit, /// <summary>
/// 闲置
/// </summary>
Idle, /// <summary>
/// 攻击
/// </summary>
Attack, /// <summary>
/// 警惕
/// </summary>
Guard, /// <summary>
/// 吟唱
/// </summary>
Spell
}

状态机,它的职责是负责在各个状态之间进行调度

using System.Collections.Generic;

/// <summary>
/// 状态机
/// </summary>
public class TowerStateMachine
{
#region 公共属性 /// <summary>
/// 追溯前面的状态
/// </summary>
public StateType PreviousStateType
{
get; set;
} #endregion #region 私有属性
/// <summary>
/// 全局状态
/// </summary>
private FiniteState _globalState; /// <summary>
/// 当前状态
/// </summary>
private FiniteState _currentState; /// <summary>
/// 状态列表
/// </summary>
private Dictionary<StateType, FiniteState> _stateList; #endregion #region 重写事件 /// <summary>
/// 初始化方法
/// </summary>
/// <param name="globalState">全局状态</param>
/// <param name="newStateType">当前状态</param>
public TowerStateMachine(TowerBase tower, FiniteState globalState, StateType newStateType)
{
PreviousStateType= StateType.Innit;
_stateList = TowerStateHelper.GenerateStateList(tower); if (null != globalState)
{
globalState.OnEnter();
_globalState = globalState;
} _stateList[newStateType].OnEnter();
_currentState = _stateList[newStateType];
} #endregion #region 公共方法 /// <summary>
/// 执行
/// </summary>
public void Excute()
{
if (null != _globalState)
_globalState.OnExcute(); if (null != _currentState)
_currentState.OnExcute();
} /// <summary>
/// 改变状态
/// </summary>
/// <param name="newStateType"></param>
public void ChangeStatus(StateType newStateType)
{
if (newStateType == _currentState.StateTypeId)
return; PreviousStateType = _currentState.StateTypeId;
_currentState.OnExit(); _stateList[newStateType].OnEnter();
_currentState = _stateList[newStateType];
} #endregion
}

状态基类,我们定义了进入、OnExcute(每次update被调用)、退出方法

/// <summary>
/// 状态基类
/// </summary>
public abstract class FiniteState
{
/// <summary>
/// 状态机类型
/// </summary>
public StateType StateTypeId { get; set; } /// <summary>
/// 塔对象
/// </summary>
public TowerBase TargetTower { get; set; } /// <summary>
/// 进入
/// </summary>
public abstract void OnEnter(); /// <summary>
/// 执行
/// </summary>
public abstract void OnExcute(); /// <summary>
/// 退出
/// </summary>
public abstract void OnExit();
}

调用对象

 //声明
private TowerStateMachine _stateMachine; //初始化
_stateMachine = new TowerStateMachine(this, null, StateType.Idle); //在Update方法里调用
_stateMachine.Excute();

状态的切换由具体状态类满足条件自动触发、或者手动触发都可以。

Unity状态机的实现,以《塔防》为例的更多相关文章

  1. 使用Unity创建塔防游戏(Part2)

    How to Create a Tower Defense Game in Unity – Part 2 原文地址:https://www.raywenderlich.com/107529/unity ...

  2. 使用Unity创建塔防游戏(Part1)

    How to Create a Tower Defense Game in Unity - Part1 原文作者:Barbara Reichart 文章原译:http://www.cnblogs.co ...

  3. 使用unity创建塔防游戏(原译)(part1)

    塔防游戏非常地受欢迎,木有什么能比看着自己的防御毁灭邪恶的入侵者更爽的事了. 在这个包含两部分的教程中,你将使用Unity创建一个塔防游戏. 你将会学到如何: 创建一波一波的敌人 使敌人随着路标移动 ...

  4. Unity塔防游戏开发

    Unity3D塔防开发流程 配置环境及场景搭建编程语言:C#,略懂些许设计模式,如果不了解设计模式,BUG More开发工具:Unity3D编辑器.Visual Studio编译器开发建议:了解Uni ...

  5. 使用Unity创建塔防游戏(Part3)—— 项目总结

    之前我们完成了使用Unity创建塔防游戏这个小项目,在这篇文章里,我们对项目中学习到的知识进行一次总结. Part1的地址:http://www.cnblogs.com/lcxBlog/p/60759 ...

  6. Unity《ATD》塔防RPG类3D游戏架构设计(二)

    目录 <ATD> 游戏模型 <ATD> 游戏逻辑 <ATD> UI/HUD/特效/音乐 结语 前篇:Unity<ATD>塔防RPG类3D游戏架构设计(一 ...

  7. Unity《ATD》塔防RPG类3D游戏架构设计(一)

    目录 <ATD> 游戏简介 <ATD> 整体结构 <ATD> 游戏机制 Buff机制 Skill机制(技能机制) 仇恨机制 <ATD> 游戏模型 策划案 ...

  8. Unity塔防游戏的创建

    看了下塔防游戏的教程,比我想像的还简单一些,有些收获: (1)敌人的移动路径,其时比较简单,用了N个Empty GameObject作为路径点,然后做一个总的Empty GameObject 作为父级 ...

  9. Unity3D学习笔记(十七):IK动画、粒子系统和塔防

    新动画系统: 反向动力学动画(IK功能): 魔兽世界(头部动画),神秘海域(手部动画),人类一败涂地(手部动画) 如何启用(调整) 1.必须是新动画系统Animator 设置头.手.肘的目标点 2.动 ...

  10. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(三)

    一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇 二.本篇目标: l  说说游戏中各种角色的动作.属性以及重构思路 l  进行代码重构让色狼大叔和 ...

随机推荐

  1. STL 源代码剖析 算法 stl_algo.h -- inplace_merge

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) ----------------------- ...

  2. js(jQuery)相关随笔

    //获取所有name='id'.被选择的的多选框var idArr = $("input[type='checkbox'][name='id']:checked");//将这些多选 ...

  3. Django学习笔记第十一篇--关于session

    一.session和sessionid: sessionid是cookie的一个字段,sessionid一般如下: """请求报文""" & ...

  4. ios 将图片做成圆形

    UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"oiuyfdsa.png ...

  5. 谨防in、or 公用性能问题

    今天遇到一个奇葩的问题:在where条件中用了 m in(×××) or m>=10,查询直接超时,我看了一下,数据库中就2万条数据 我将查询改为了union all 结果就不超时了

  6. android sdk 中跨平台部分

    跨平台部分: platforms samples sources system-images 这几个可以直接拷贝即可

  7. SNORT--install ---dependency-resolve

    # ./configure 遇到ERROR: checking for pfring_open in -lpcap... no ERROR!  Libpcap library/headers (lib ...

  8. json和jsonp解决跨域传输数据等

    https://kb.cnblogs.com/page/139725/ https://blog.csdn.net/lambert310/article/details/51683775

  9. 【题解】P5151 HKE与他的小朋友

    [题解]P5151 HKE与他的小朋友 实际上,位置的关系可以看做一组递推式,\(f(a_i)=f(a_j),f(a_j)=f(a_t),etc...\)那么我们可以压进一个矩阵里面. 考虑到这个矩阵 ...

  10. python中读取json文件报错,TypeError:the Json object must be str, bytes or bytearray,not ‘TextIOWrapper’

    利用python中的json读取json文件时,因为错误使用了相应的方法导致报错:TypeError:the Json object must be str, bytes or bytearray,n ...