什么是有限状态机?

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

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

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. CStringArray序列化处理

    开发中需要对CStringArray进行保存操作,涉及到序列化,特总结一下: //写 CStringArray saTmp1; CStringArray saTmp2 saTmp1.AddString ...

  2. 利用hugo生成静态站点

    动机 使用Markdown撰写博客,并以静态页面形式发布. 选择hugo 现在jekyll似乎更加流行,但是jekyll是基于Ruby的,在windows下安装很繁琐. 而hugo是用go写的,win ...

  3. python练习题-3

    author:headsen chen date: 2018-06-01  15:51:05 习题 31:  作出决定(if + raw_input) [root@localhost py]# cat ...

  4. ios UITableView中Cell重用机制导致内容重复解决方法

    UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...

  5. SpringMVC笔记——Spring+MyBatis组合开发简单实例

    简介 SSH框架很强大,适合大型项目开发.但学无止境,多学会一门框架组合开发会让自己增值许多. SSM框架小巧精致,适合中小型项目快速开发,对于新手来说也是简单上手的.在SSM框架搭建之前,我们先学习 ...

  6. 搜索R包和查看包的技巧

    1.R怎么搜包 # 安装sos包 install.packages("sos") # 导入sos包 library(sos) # 使用函数findFn() 函数里面传入关键字来搜索 ...

  7. .Net Ajax跨域请求总结

    导语 之前写过一篇文章Ajax跨域请求COOKIE无法带上的解决办法,这两天正好好好的查了一下相关知识,做来总结一下 一.传统 ajax跨域访问是一个老问题了,解决方法很多,比较常用的是JSONP方法 ...

  8. netstat -tulpn

    [root@d java]# netstat -tulpnActive Internet connections (only servers)Proto Recv-Q Send-Q Local Add ...

  9. scrapy - grab english name

    wxpath定位-采集验证-入库-使用. from scrapy.spider import Spider from scrapy.crawler import CrawlerProcess clas ...

  10. LeetCode_Search in Rotated Sorted Array

    题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 ...