本节书摘来异步社区《游戏编程模式》一书中的第7章,第7.2节,作者: 【美】Robert Nystrom (尼斯卓姆) 译者: 赵卫兵 , 许新星 , 姜召阳 , 陈侃 , 屈光辉 , 郑炯彬 责编: 陈冀康,更多章节内容可以访问云栖社区“异步社区”公众号查看。
7.2 救星:有限状态机
为了消除你心中的疑惑,你可以准备一张纸和一支笔,让我们一起来画一张流程图。对于女主角能够进行的动作画一个“矩形”:站立、跳跃、躲避和俯冲。当你可以按下一个键让主角从一个状态切换到另一个状态的时候,我们画一个箭头,让它从一个矩形指向另一个矩形。同时在箭头上面添加文本,表示我们按下的按钮。
恭喜,你刚刚已经成功创建了一个有限状态机。有限状态机借鉴了计算机科学里的自动机理论(automata theory)中的一种数据结构(图灵机)思想。有限状态机(FSMs)可以看作是最简单的图灵机(如图7-1所示)。
其表达的是:
关于有限状态机我最喜欢的比喻就是它是像Zork一样的古老的文字冒险游戏。游戏中有着由出口连接着的一些房间。你可以通过输入像“往北前进”这样的命令来进行探索。
这其实就是一个状态机:每一个房间是一个状态。你所在的房间就是当前的状态。每个房间的出口就是它的转换,导航命令就是输入。
- 你拥有一组状态,并且可以在这组状态之间进行切换。比如:站立、跳跃、躲避和俯冲。
- 状态机同一时刻只能处于一种状态。女主角无法同时跳跃和站立。事实上,防止同时存在两个状态是我们使用有限状态机的原因。
- 状态机会接收一组输入或者事件。在我们这个例子中,它们就是按钮的按下和释放。
- 每一个状态有一组转换,每一个转换都关联着一个输入并指向另一个状态。当有一个输入进来的时候,如果输入与当前状态的其中一个转换匹配上,则状态机便会转换状态到输入事件所指的状态。
在我们的例子中,在站立状态的时候如果按下向下方向键,则状态转换到躲避状态。如果在跳跃状态的时候按下向下方向键,则会转换到俯冲攻击状态。如果对于每一个输入事件没有对应的转换,则这个输入就会被忽略。
简而言之,整个状态机可以分为:状态、输入和转换。你可以通过画状态流程图来表示它们。不幸的是,编译器并不认识状态图,所以,我们接下来要介绍如何实现。GoF的状态模式是一种实现方法,但是让我们先从更简单的方法开始。