设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123425 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

64 | 状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

优缺点
代码示例
状态类的接口
优点
代码示例
二维表表示状态机
优缺点
代码示例
状态接口中定义所有事件函数的问题
三种状态机实现方式的总结
状态模式是状态机的一种实现方式
状态模式
查表法
分支逻辑法
状态转移图
不同形态的马里奥
动作(Action)
事件(Event)
状态(State)
课堂讨论
重点回顾
状态机的实现方式
例子:超级马里奥游戏
有限状态机
游戏中常用的状态机是如何实现的?

该思维导图由 AI 生成,仅供参考

从今天起,我们开始学习状态模式。在实际的软件开发中,状态模式并不是很常用,但是在能够用到的场景里,它可以发挥很大的作用。从这一点上来看,它有点像我们之前讲到的组合模式。
状态模式一般用来实现状态机,而状态机常用在游戏、工作流引擎等系统开发中。不过,状态机的实现方式有多种,除了状态模式,比较常用的还有分支逻辑法和查表法。今天,我们就详细讲讲这几种实现方式,并且对比一下它们的优劣和应用场景。
话不多说,让我们正式开始今天的学习吧!

什么是有限状态机?

有限状态机,英文翻译是 Finite State Machine,缩写为 FSM,简称为状态机。状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。
对于刚刚给出的状态机的定义,我结合一个具体的例子,来进一步解释一下。
“超级马里奥”游戏不知道你玩过没有?在游戏中,马里奥可以变身为多种形态,比如小马里奥(Small Mario)、超级马里奥(Super Mario)、火焰马里奥(Fire Mario)、斗篷马里奥(Cape Mario)等等。在不同的游戏情节下,各个形态会互相转化,并相应的增减积分。比如,初始形态是小马里奥,吃了蘑菇之后就会变成超级马里奥,并且增加 100 积分。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了游戏中常用的状态机的实现方式,以及状态机的基本概念。作者首先介绍了有限状态机的组成部分:状态、事件、动作,并通过“超级马里奥”游戏的例子解释了状态机的概念。接着,作者提出了三种状态机的实现方式:分支逻辑法、查表法和状态模式。在分支逻辑法中,作者通过代码示例展示了如何使用if-else或switch-case分支判断逻辑来实现状态机,但指出了其可读性和可维护性较差的问题。而在查表法中,作者介绍了利用二维表来表示状态机的实现方式,并展示了相应的代码示例,强调了其代码实现更加清晰、可读性和可维护性更好的优点。最后,作者提到了状态模式的实现方式,并对比了这三种实现方式的优劣和应用场景。通过本文,读者可以快速了解状态机的基本概念和不同的实现方式,以及它们的优缺点和适用场景。文章内容深入浅出,适合技术人员了解状态机的实现方式及其应用。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(95)

  • 最新
  • 精选
  • DFighting
    不太赞同老师的这种抽象方式,状态机中的每个状态应该具有事件、触发条件、转移(方法)列表,每一个应该都可以抽象为一个接口或者泛型类,状态机作为一个单例这个没问题,但是状态机应该只是作为一个状态的注册工厂,里面具有的应该是多种状态,状态间的流转才是状态机最重要的功能抽象。score放在状态和状态机中都不合适,这应该是状态机操纵的一个对象/资源,应该单独抽象出来,在状态间流转

    作者回复: 好吧

    2020-11-21
    4
    29
  • 进击的巨人
    感觉状态模式就是一个策略模式

    作者回复: 嗯嗯

    2020-11-27
    2
    2
  • 吃饭睡觉打酱油
    老师,在使用状态机的时候,初始状态应该是可以支持初始化的吧。

    作者回复: 嗯嗯

    2020-06-20
    1
  • Geek_78eadb
    课后题: 1. 使用抽象工厂模式实现 Action 类:即根据不同的状态实现 ObtainMushRoom 等动作类,比如 ObtainMushRoom 的初始化需要传入目前状态和目前分数, ObtainMushRoom 可以利用状态机的查表法进行状态转移和其它动作

    作者回复: 嗯嗯 ������

    2020-11-28
    2
  • 打工人233号
    如果一种状态转移对应多种状态如何处理呢?

    作者回复: 这个好像没有这种情况吧

    2020-11-13
  • 慕枫技术笔记
    查表法在状态新增的情况下怎么做到不修改代码的?

    作者回复: 没法做到一点都不修改代码的哦

    2020-07-29
    3
  • pippin
    查表法的这个数组有问题吧,transitionTable[0][0]应该是SMALL吧。这里应该是写错了吧。private static final State[][] transitionTable = { {SUPER, CAPE, FIRE, SMALL}, {SUPER, CAPE, FIRE, SMALL}, {CAPE, CAPE, CAPE, SMALL}, {FIRE, FIRE, FIRE, SMALL} };

    作者回复: 没有啊,你看看上面那个表格

    2020-04-13
    2
  • 张先生丶
    关于课堂讨论,可以在接口和实现类中间加一层抽象类解决此问题,抽象类实现状态接口,状态类继承抽象类,只需要重写需要的方法即可
    2020-03-30
    6
    153
  • Darren
    Java中Spring也有有限状态机的框架 :https://github.com/spring-projects/spring-statemachine
    2020-04-14
    57
  • 下雨天
    课后题 最小接口原则 具体做法:状态类只关心与自己相关的接口,将状态接口中定义的事件函数按事件分类,拆分到不同接口中,通过这些新接口的组合重新实现状态类即可!
    2020-03-30
    2
    34
收起评论
显示
设置
留言
95
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部