在游戏开发中,AI是个永恒不变的话题,如果你要的AI只是很简单的一个逻辑
那么有限状态机是一个很好的解决方案,尽管在实际开发中,AI的设计并不是一个简单的逻辑,
如果用有限状态机,维护起来会非常麻烦,但还是有必要记一笔。

为什么说维护起来很麻烦?
画一个图就知道了。
在状态不是很多的时候,要维护的状态就少,实现起来也很简单。

但是,一旦状态一多,要维护的状态就多了,
每增加一个状态,就要维护这个状态到其他各个状态之间的实现
当状态越来越多的时候,你就会觉得心有余而力不足了。

代码1:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. namespace ShiHuanJue.FSM
  6. {
  7. public abstract class FSMParent
  8. {
  9. #region 公共变量
  10.  
  11. public string m_currentState = string.Empty;
  12.  
  13. #endregion
  14.  
  15. #region 私有变量
  16.  
  17. protected Dictionary<string, IState> theFSM = new Dictionary<string, IState>();
  18.  
  19. #endregion
  20.  
  21. public FSMParent()
  22. {
  23. }
  24.  
  25. public virtual void ChangeStatus(string newState, params Object[] args)
  26. {
  27. if (this.m_currentState == newState)
  28. {
  29. UnityEngine.Debug.Log("oldState = newState");
  30. return;
  31. }
  32.  
  33. if (!this.theFSM.ContainsKey(newState))
  34. {
  35. UnityEngine.Debug.Log("newState is not in stateList");
  36. return;
  37. }
  38.  
  39. if(this.theFSM.ContainsKey(this.m_currentState))
  40. this.theFSM[this.m_currentState].Exit(args);
  41. this.theFSM[newState].Enter(args);
  42. this.m_currentState = newState;//更改当前状态
  43. this.theFSM[newState].Process(args);
  44. }
  45. }
  46. }

代码2:

  1. using System;
  2. namespace ShiHuanJue.FSM
  3. {
  4. public interface IState
  5. {
  6. // 进入该状态
  7. void Enter(params Object[] args);
  8.  
  9. // 离开状态
  10. void Exit(params Object[] args);
  11.  
  12. // 状态处理
  13. void Process(params Object[] args);
  14. }
  15. }

代码3:

  1. namespace ShiHuanJue.FSM
  2. {
  3. // 状态
  4. static public class MotionState
  5. {
  6. static readonly public string IDLE = "idle";
  7. static readonly public string WALKING = "walking";
  8. static readonly public string DEAD = "dead";
  9. static readonly public string ATTACKING = "attacking";
  10. }
  11. }

代码就上面3个,很简单吧。
怎么用呢?

  1. using System;
  2. using System.Collections;
  3.  
  4. namespace ShiHuanJue.FSM
  5. {
  6. static public class RoleStateSet
  7. {
  8. static public RoleIdle stateIdle = new RoleIdle();
  9. static public RoleWalking stateWalking = new RoleWalking();
  10. static public RoleDead stateDead = new RoleDead();
  11. static public RoleAttacking stateAttackint = new RoleAttacking();
  12. }
  13.  
  14. public class FSMRole : FSMParent
  15. {
  16. public FSMRole()
  17. {
  18. theFSM.Add(MotionState.IDLE, RoleStateSet.stateIdle);
  19. theFSM.Add(MotionState.WALKING, RoleStateSet.stateWalking);
  20. theFSM.Add(MotionState.DEAD, RoleStateSet.stateDead);
  21. theFSM.Add(MotionState.ATTACKING, RoleStateSet.stateAttackint);
  22. }
  23.  
  24. public override void ChangeStatus(string newState, params Object[] args)
  25. {
  26. base.ChangeStatus(newState,args);
  27. }
  28. }
  29. }

实现各个状态的逻辑。这里就贴一个Idle的。其它状态格式都一样,只是实现不一样。

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. namespace ShiHuanJue.FSM
  5. {
  6. public class RoleIdle : IState
  7. {
  8. public void Enter(params System.Object[] args)
  9. {
  10. Debug.Log("RoleIdle Enter");
  11. }
  12.  
  13. public void Exit(params System.Object[] args)
  14. {
  15. Debug.Log("RoleIdle Exit");
  16. }
  17.  
  18. public void Process(params System.Object[] args)
  19. {
  20. Debug.Log("RoleIdle Process");
  21. }
  22. }
  23. }

测试一下咯:

  1. using UnityEngine;
  2. using System.Collections;
  3. using ShiHuanJue.FSM;
  4.  
  5. public class Test : MonoBehaviour
  6. {
  7. void Start()
  8. {
  9. FSMRole roleAI = new FSMRole();
  10. Debug.Log(roleAI.m_currentState);
  11.  
  12. roleAI.ChangeStatus(MotionState.IDLE);
  13. Debug.Log(roleAI.m_currentState);
  14.  
  15. roleAI.ChangeStatus(MotionState.WALKING);
  16. Debug.Log(roleAI.m_currentState);
  17.  
  18. roleAI.ChangeStatus(MotionState.IDLE);
  19. Debug.Log(roleAI.m_currentState);
  20. }
  21. }

代码都在这了,实际用的也不多,工程就不上传了。用的不多,只是在这记一笔。
实际开发中,还是推荐用行为树。
行为树下次再说,我会先自己写一个行为树之后,分析下缺点,然后介绍一下腾讯开源的行为树框架。
我觉得学习,再理解了它的原理之后,就可以拿现有完善的框架来用,站在巨人的肩膀上,你才可以看的更远,知道自己是多么的渺小。
敬请期待~!

有限状态机(FSM)的更多相关文章

  1. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  2. cocos2d-x 游戏开发之有限状态机(FSM) (四)

    cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...

  3. cocos2d-x 游戏开发之有限状态机(FSM) (三)

    cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...

  4. cocos2d-x 游戏开发之有限状态机(FSM) (一)

    cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...

  5. cocos2d-x 游戏开发之有限状态机(FSM) (二)

    cocos2d-x 游戏开发之有限状态机(FSM)  (二) 1 状态模式

  6. 有限状态机FSM

    有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型.常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络 ...

  7. Atitit. 有限状态机 fsm 状态模式

    Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...

  8. [原创][FPGA]有限状态机FSM学习笔记(一)

    1. 概述--何为有限状态机FSM? 有限状态机-Finite State Machine,简写为FSM,是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.通常 ...

  9. Linux编程之有限状态机FSM的理解与实现

    有限状态机(finite state machine)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.FSM是一种逻辑单元内部的一种高效编程方法,在 ...

  10. 有限状态机(FSM)的Java 学习FSM

    本文从简单的例子入手,逐步演变成非常复杂的程序. 在简明 状态模式(5.8)中,状态之间的变换由外界控制,或者说,多种状态是分割的.无关的.状态模式最有趣的地方正是讨论其状态的变迁. 1.引子 空调( ...

随机推荐

  1. Backbone源码阅读手记

    Backbone.js是前端的MVC框架,它通过提供模型Models.集合Collection.视图Veiew赋予了Web应用程序分层结构.从源码中可以知道,Backbone主要分了以下几个模块: ( ...

  2. bzoj1045 糖果传递

    escription 老师准备了一堆糖果, 恰好n个小朋友可以分到数目一样多的糖果. 老师要n个小朋友去拿糖果, 然后围着圆桌坐好, 第1个小朋友的左边是第n个小朋友, 其他第i个小朋友左边是第i-1 ...

  3. oracle分区表知识

    在F5中查看执行计划的时候总是看到很多信息: range分区 执行计划中出现的: 分区表,按 n1 ,n2 分区 partition range single:访问单个分区 partition ran ...

  4. Linux设置Memcached开机启动

    Memcached开机启动方式 方法一: 在 /etc/rc.d/rc.local 文件中追加启动命令 /usr/local/memcached/bin/memcached  -u root -d - ...

  5. NSCache

    今天在优化的时候,用了NSCache,感觉没什么两样(视觉上).按理内存缓存,怎么也比从硬盘读取的要快.. dispatch_async(dispatch_get_global_queue(, ), ...

  6. angularjs表单验证checkbox

    angularjs中默认有表单验证的支持,见文末的refer 我想要验证至少要选择一个checkbox,否则就不能提交 但是checkbox貌似没有简单的方法,想来想去给出下面的解决方案 valida ...

  7. js中选定元素slice()

    选定元素slice() slice() 方法可从已有的数组中返回选定的元素. 语法 arrayObject.slice(start,end) 参数说明: 1.返回一个新的数组,包含从 start 到 ...

  8. css中选择器的使用技巧

    td:first-child{选择第一个} td:last-child{选择最后一个} td:nth-child(3){选择第3个} 一个简单的选择方法,很方便

  9. linux连接远程桌面

    #!/usr/bin/env python3 #-*-encoding:utf-8-*- import re import os import urllib.request, urllib.parse ...

  10. unrecognized selector sent to instance

    今天长一见识(特此感谢小星星老湿-坏笑),凡是遇到“unrecognized selector sent to instance *******”的都是******方法没有,比如这种的错误: 可以尝试 ...