《游戏编程模式》一7.2 救星:有限状态机

7.2 救星:有限状态机

为了消除你心中的疑惑,你可以准备一张纸和一支笔,让我们一起来画一张流程图。对于女主角能够进行的动作画一个“矩形”:站立、跳跃、躲避和俯冲。当你可以按下一个键让主角从一个状态切换到另一个状态的时候,我们画一个箭头,让它从一个矩形指向另一个矩形。同时在箭头上面添加文本,表示我们按下的按钮。

恭喜,你刚刚已经成功创建了一个有限状态机。有限状态机借鉴了计算机科学里的自动机理论(automata theory)中的一种数据结构(图灵机)思想。有限状态机(FSMs)可以看作是最简单的图灵机(如图7-1所示)。

其表达的是:

关于有限状态机我最喜欢的比喻就是它是像Zork一样的古老的文字冒险游戏。游戏中有着由出口连接着的一些房间。你可以通过输入像“往北前进”这样的命令来进行探索。

这其实就是一个状态机:每一个房间是一个状态。你所在的房间就是当前的状态。每个房间的出口就是它的转换,导航命令就是输入。

  • 你拥有一组状态,并且可以在这组状态之间进行切换。比如:站立、跳跃、躲避和俯冲。
  • 状态机同一时刻只能处于一种状态。女主角无法同时跳跃和站立。事实上,防止同时存在两个状态是我们使用有限状态机的原因。
  • 状态机会接收一组输入或者事件。在我们这个例子中,它们就是按钮的按下和释放。
  • 每一个状态有一组转换,每一个转换都关联着一个输入并指向另一个状态。当有一个输入进来的时候,如果输入与当前状态的其中一个转换匹配上,则状态机便会转换状态到输入事件所指的状态。

在我们的例子中,在站立状态的时候如果按下向下方向键,则状态转换到躲避状态。如果在跳跃状态的时候按下向下方向键,则会转换到俯冲攻击状态。如果对于每一个输入事件没有对应的转换,则这个输入就会被忽略。

简而言之,整个状态机可以分为:状态、输入和转换。你可以通过画状态流程图来表示它们。不幸的是,编译器并不认识状态图,所以,我们接下来要介绍如何实现。GoF的状态模式是一种实现方法,但是让我们先从更简单的方法开始。

时间: 2024-08-29 07:50:42

《游戏编程模式》一7.2 救星:有限状态机的相关文章

《游戏编程模式》一导读

前 言 游戏编程模式在五年级的时候,我和我的小伙伴们获准使用一个放置着几台非常破旧的TRS-80s[1]的闲置教室.为了激励我们,一位老师找到了一份印有一些简单BASIC程序的打印文档给我们. 当时,计算机上的音频磁带驱动器是坏掉的,所以每次我们想要运行一些代码的时候,都不得不仔细地从头开始键入代码.这使得我们更喜欢那些只有几行代码的程序: 如果计算机打印足够多的次数,或许它会神奇的变成现实哦[2]. 10 PRINT "BOBBY IS RADICAL!!!" 20 GOTO 10

《游戏编程模式》一第1章 架构,性能和游戏

第1章 架构,性能和游戏 游戏编程模式在我们一头扎进一堆模式之前,我想为你介绍一些关于我如何看待软件架构以及它是如何应用到游戏的一些背景,这可能会帮助你更好地理解这本书的其余部分.至少,当你陷入关于设计模式和软件架构是多么糟糕(或者很棒)的一场争论中时,它会给你一些论据来使用. 请注意,我没有假设你站在争论中的哪一方.就像任何军火商一样,我为所有战斗方提供武器.

《游戏编程模式》一第7章 状态模式

第7章 状态模式 "允许一个对象在其内部状态改变时改变自身的行为.对象看起来好像是在修改自身类." 交代一下:我写的有些过头了,我在本章里面添加了太多东西.表面上这一章是介绍状态模式[1]的,但是我不能抛开游戏里面的有限状态机(finite state machines,FSM)而单独只谈"状态模式".不过,当我讲到FSM的时候,我发觉我还有必要再介绍一下层次状态机(hierarchical state machine)和下推自动机(pushdown automat

《游戏编程模式》一7.5 状态对象应该放在哪里呢

7.5 状态对象应该放在哪里呢 我这里忽略了一些细节.为了修改一个状态,我们需要给state_指针赋值为一个新的状态,但是这个新的状态对象要从哪里来呢?我们之前的枚举方法是定义一些数字.但是,现在我们的状态是类,我们需要获取这些类的实例.通常来说,有两种实现方法. 7.5.1 静态状态 如果一个状态对象没有任何数据成员,那么它的唯一数据成员便是虚表指针了.那样的话,我们就没有必要创建此状态的多个实例了,因为它们的每一个实例都是相同的. 在那种情况下,我们可以定义一个静态实例.即使你有一系列的FS

《游戏编程模式》一1.1 什么是软件架构

1.1 什么是软件架构 如果你从头到尾阅读了这本书,那么你并不会了解到3D图形背后的线性代数或者游戏物理背后的演算.这本书也不会告诉你如何一步步改进你的AI搜索树或者模拟音频播放中的房间混响. 哇,此段简直为这本书打了一个糟糕的广告. 相反,这本书是关于上面这一切要使用的代码的组织方式.这里少谈代码,多谈代码组织.每个程序都具有一定的组织性,即使它只是"把所有东西扔到main()函数里然后看看会发生什么",所以我认为讨论如何形成好的组织性会更有趣些.我们如何分辨一个架构的好坏呢? 我大

《游戏编程模式》一1.3 性能和速度

1.3 性能和速度 你有时候会听到关于软件架构和相关概念的批评声,尤其在游戏开发中:它会影响到游戏的性能.许多模式让你的代码更加灵活,但是它依赖于虚函数派发.接口.指针.消息以及其他至少有一些运行成本的机制. 一个有趣的范例是C++模板.模板元编程有时可以让你获得抽象接口而没有任何运行时开销. 对灵活的定义,不同人有不同的看法,当你在某些类中调用一个具体方法时,你相当于将这个类固定(很难做出改变).当你使用一个虚方法或者接口时,被调用的类将直到真正运行起来才能被追踪到,这样的程序更具灵活性但是会

《游戏编程模式》一7.3 枚举和分支

7.3 枚举和分支 一个问题是,Heroine类有一些布尔类型的成员变量:isJumping_和isDucking_,但是这两个变量不应该同时为true.当你有一系列的标记成员变量,而它们只能有且仅有一个为true时,这表明我们需要把它们定义成枚举(enum). 在这个例子当中,我们的有限状态机的每一个状态可以用一个枚举来表示,所以,让我们定义以下枚举: enum State { STATE_STANDING, STATE_JUMPING, STATE_DUCKING, STATE_DIVING

《游戏编程模式》一7.8 并发状态机

7.8 并发状态机 我们决定给我们的主角添加持枪功能.当她持枪的时候,她仍然可以:跑.跳和躲避等.但是,她也需要能够在这些状态过程中开火. 如果你执着于传统的有限状态机,那我们可能需要把之前的状态加倍.对于每一个已经存在的状态,我们需要定义另一个状态,它做的事情也差不多,不过就是多了持枪的操作.比如站立状态和站立开火状态,跳跃状态和跳跃开火状态等. 如果我们添加更多的武器种类,那么这个状态数量将会急剧增加.而且不仅仅是增加了大量的状态类实例,它还会增加大量的冗余,实际上带不带枪的状态仅有是否包含

《游戏编程模式》一7.7 有什么收获吗

一个有限状态机甚至都不是图灵完备的.自动机理论使用一系列抽象的模型来描述计算,并且每一个模型都比先前的模型更复杂.而图灵机只是这里面最具有表达力的模型之一. "图灵完备"意味着一个系统(通常指的是一门编程语言)是足够强大的,强大到它可以实现一个图灵机.这也意味着,所有图灵完备的编程语言,在某些程度上其表达力是相同的.但有限状态机由于其不够灵活,并不在其中. 我已经花了大量的时间来介绍有限状态机.现在我们一起来捋一捋.到目前为止,我跟你讲的所有事情都是对的,有限状态机对于某些应用来讲是非