什么是有限状态机?

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

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

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. P2483 [SDOI2010]魔法猪学院

    P2483 [SDOI2010]魔法猪学院 摘要 --> 题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世 ...

  2. a标签点击后,给a标签添加样式

    window.onload=function(){ var a = document.getElementById("cate").getElementsByTagName(&qu ...

  3. 剑指 offer set 18 数组中只出现一次的数字

    题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字 思路 1. 思路是先将数组分成两个部分, 两个单个数字分别分到两部分中, 并且数组中其他数字都成 ...

  4. sessionStorage存储json对象

    应用场景: 账单列表中A页面:点击其中的一列,ajax返回的数据在这一页 点击进入账单详情B页面: 因为在A页面已经做过ajax的请求了,所以希望把当前其中的一个数组对象传到B页面中,所以,就考虑到暂 ...

  5. javascript 禁止页面选取-兼容IE、Chrome和firefox浏览器

    在做到一个页面需要禁止网页内容被选取的时候,碰到浏览器兼容的问题,解决方法如下 1.单独使用适用于IE.Chrome浏览器,主要是在head的<script>标签里面加上如下代码 docu ...

  6. 160606、springmvc中使用Spring Mobile

    springmobile特点: 1.客户端设备识别:识别结果只有3种类型:NORMAL(非手机设备).MOBILE(手机设备).TABLET(平板电脑). 2.网站偏好设置:Spring 通过设备识别 ...

  7. CodeForces 732B Cormen — The Best Friend Of a Man

    B. Cormen - The Best Friend Of a Man time limit per test 1 second memory limit per test 256 megabyte ...

  8. because of an existing model object of the same name

    背景: 视图解析器(我们用的是velocity) 报错: because of an existing model object of the same name 按照网上给的原因 : 设置了属性ex ...

  9. Ajax 常用资源

    regular online:http://regex.larsolavtorvik.com/ json online:http://json.cn/ Prototype:http://prototy ...

  10. #include <sys/epoll.h> epoll - I/O event notification facility 服务器端 epoll(7) - Linux manual page http://www.man7.org/linux/man-pages/man7/epoll.7.html

    epoll使用详解(精髓) - Boblim - 博客园 https://www.cnblogs.com/fnlingnzb-learner/p/5835573.html epoll使用详解(精髓) ...