最近实习做了【鼠标碰撞圆圈】的游戏。
一开始游戏的执行逻辑全部是依靠 if - else嵌套,但是随着添加的功能越来越复杂,几十个if- else嵌套在一起,不仅降低了代码的可读性,而且无法实现功能和逻辑分离,最关键是逻辑有bug肉眼无法检查。因此,简单的学习并使用了有限状态机(Finite State Machine, FSM)。
先看看FSM定义:
具有有限数量的状态,它可以在任何给定的时间根据输入进行操作,从一个状态变换到另一个状态,或者促使一个输出或者一种行为的发生。一个有限状态机在任何瞬间只能处在一种状态
概括一下:
1. 有限个状态,且状态间存在转移关系。
2. 某个时间点,有且仅有一个状态存在。
废话不多少,先展示一下功能:
![d7f911ecd666d3d4ff4151c56970173a.gif](https://i-blog.csdnimg.cn/blog_migrate/6855e9d834088c74def621009f269ebc.gif)
状态转移图如下:
![87bc9f1f09f2468201aedc1bd949b85e.png](https://i-blog.csdnimg.cn/blog_migrate/44c9e2514477827e61b384c2739bdc1d.png)
为了实现FSM,最关键是要定义清楚“状态-行为-转换”,按照三步走来实现:
第一步:定义有限状态列表(状态)
第二步:定义状态-函数耦合逻辑(状态函数)
第三步:写函数内容,添加状态转换(行为)
【第一步】定义状态列表
存在六个状态:【圆圈出现,鼠标进入圆圈、鼠标移出圆圈、任务成功、任务失败、休息 】
public enum GameState_Enum // 枚举 状态列表
{
STATE_CIRCLESHOWING, // 圆圈出现
STATE_INCIRCLE, // cursor进入圆圈
STATE_OUTCIRCLE, // cursor移出圆圈
STATE_TRIALSUCCEED, // 任务成功
STATE_TRIALFAIL, // 任务失败
STATE_BREAK // 休息
};
【第二步】定义状态函数
有了状态列表,switch 语句实现 【状态】和【行为函数】对应。
while(1)
{
switch (currState)
{
case GameState_Enum.STATE_CIRCLESHOWING:
CircleShowing(); // 圆圈出现 行为函数
break;
case GameState_Enum.STATE_INCIRCLE:
InCircle(); // cursor进入圆圈 行为函数
break;
case GameState_Enum.STATE_OUTCIRCLE:
OutCircle(); // cursor移出圆圈 行为函数
break;
case GameState_Enum.STATE_TRIALSUCCEED:
TaskSucceed(); // 任务成功 行为函数
break;
case GameState_Enum.STATE_TRIALFAIL:
TaskFail(); // 任务失败 行为函数
break;
case GameState_Enum.STATE_BREAK:
Break(); // 休息 行为函数
break;
}
}
【第三步】行为函数内容,状态转移
接下来,定义每个【行为函数】的功能。以 TaskSucceed() 为例:
private void TaskSucceed()
{
// 功能
timeLine += Time.deltaTime; // 时间轴
///
你还可以写其他功能
///
// 状态转移
currState = GameState_Enum.STATE_BREAK;
}
完成了FSM搭建,给全局变量currState一个初始状态值,FSM就执行起来了。
接下来就可以愉快的玩耍啦!