"); //-->
/********************有限状态机自动机***********************/
状态图--一个图的数据结构!
1.while + switch;
2.状态机:就是指定系统的所有可能的状态及状态间跳转的条件,然后设一个初始状态输入给这台机器,机器就会自动运转,或最后处于终止状态,或在某一个状态不断循环。
游戏中状态切换是很频繁的。 可能以前要切换状态就是if~else,或者设标志,但这些都不太结构化, 如果把它严格的设为一种标准的状态机,会清楚的多。
比如控制一扇门的运动, 初始时门是关的, 当有力作用在门上时, 门开始慢慢打开,力的作用完后,门渐渐停止不动, 当有反向的力时,门又渐渐关上, 知道回到初始关的状态。 这个你会怎么来编程实现呢。 似乎很麻烦, 的确,没有状态机的思想时会很烦,设很多标志,一堆if条件。
用状态机的话,不只是代码更清晰, 关键是更符合逻辑和自然规律, 不同状态不同处理, 满足条件则跳转到相关状态。
伪码如下:
enum
{
CLOSED, // 关上状态
CLOSING, // 正在关状态
OPENED, // 打开状态
OPENING, // 正在开的状态
}doorState = CLOSED; // 初始为关
Update()
{
switch(doorState)
case CLOSED:
if (有人推门)
doorState = OPENING; // 跳转到正在开状态
break;
case OPENING:
door.Rotation += DeltaAngle; // 门的旋转量递增
if (门的速度为零) / / 力的作用已去
doorState = OPENED; // 跳转到开状态
break;
case OPENED:
if (有人关门)
doorState = CLOSING;
break;
case CLOSING:
door.Rotation -= DeltaAngle; // 门的旋转量递减
if (门的旋转角度减为零)
doorState = CLOSED; // 门已关上
break;
}
// 而绘制代码几乎不用怎么变, 门就是会严格按照状态机的指示去运动, 该停就会停
Render()
{
RotateView(door.Rotation);
DrawDoor(door.Position);
}
这是一个简单但很典型的例子, 状态机的应用太多了。
就说一个基本游戏的运转: (用到了一个状态然后还有子状态)
UpdateGame()
BEGIN;
switch(gameState)
case 等待选择菜单: //它有三个子状态。
if (选择菜单项 == 开始)
{
游戏初始;
gameState = 开始游戏
}
if (选择菜单项 == 选项)
gameState = 设置
if (选择菜单项 == 退出)
gameState = 退出
case 开始:
游戏运行;
if (用户按退出键)
gameState = 等待选择菜单 ;
...其他的状态跳转处理;
case 退出:
释放资源;
退出;
case 设置:
分别处理不同的选项, 跳转不同的子状态;
case .... // 其他状态的处理
END;
某一个状态可以包含更多的子状态, 这样最好是同一层次的状态设为一个枚举, 并分到另一个switch处理
如 enum STATES{state1, state2, state3}; state2又包含若干状态
则再定义enum SUB_STATE2{sub_state2_1, sub_state2_2, sub_state2_3,};
想很多基本的渲染效果, 如淡入淡出, 闪烁等等, 用状态的思想会事半功倍, 思路也更清晰。
其实像Opengl, Direct3D这样的渲染引擎本身就是状态机, 当你设置渲染的状态, 这台机器就保持这个状态进行渲染工作,如保持光照位置,保持片元颜色, 直到你再次改变它的状态。
状态机的应用实在太广, 相关理论也很多, 最近上课学的随机过程里也讲到一些, 数字电路里的时序逻辑器件也是用状态机来描述。 这些不必多说了。
总之, 用状态机的角度去看待问题, 往往能把比较复杂的系统分解为能单独处理的众多子状态, 处理也会得心应手。希望大家多用它, 很好的东西。
二、
推荐这个:[程序员杂志2004.8月刊_state模式和composite模式实现的状态机引擎]
http://www.contextfree.net/wangyw/source/oofsm.html
个人感觉状态机的几个不同实现阶段:
1、switch/case 最原始的实现方式,是很多的c程序员习惯采用的方式。
2、查找表[状态、事件、动作],稍微做了一点改进。有点类似MFC的雏形。
3、在以上基础上做的一些改进或者变体。
[比如用一个栈结构,激活的状态位于栈顶,自动的映射事件和动作的对应,再或者通过一些巧妙的宏等手段进行包装。但是线性结构在实际中使用比较受限、过于技巧性的宏比较难于理解...]
4、面向对象的设计下、灵活运用模式。如上面给出的链接。重用性和灵活性方面都有不错的表现。沿袭类似的设计思路、根据实际开发内容进行改造后利用。
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
基于AD芯片AD1674设计的数据采集电路
10大职业恐因AI在2030年消失!
“shangziyun”STM32F103ZET6读写24C02超级终端显示视频
光耦应用全面介绍
“奋斗STM32”的超声波测距串口显示视频
稳压逆变电源12V-220V 200W
英飞凌发布PSOC™ 4 Multi-Sense,通过电感感应和液体感应解决方案扩展电容感应技术
“zangchao”STM32与51单片机串口通信演示视频
MC3406A升降压DC―DC集成变换器
DeepSeek的一次小更新 堪比发布新模型
[求助] vxworks 硬盘启动资料
同级唯一激光雷达+8650芯片智驾方案!零跑B10有望4月上市:预售10.98万起
ARM - The Architecture for The Digital World
如何一步步建交叉编译环境!!!
[求助]关于VxWorks串行通信的几篇论文?
MAX731开关控制型DC-DC升压变换器
求救:如何解决串口采数丢点问题!
MAX743升压开关型DC-DC变换器的典型应用电路
湿度模块原理图(湿敏电阻protel99se格式).
聚焦Edge Computing&Edge AI,共绘技术创新生态蓝图
资腾科技Semicon China 2025,半导体客制化解方、ESG创未来
急求助:2410的确开发板怎样接VGA显示器
Dsp基础(讲义,实验指导,实验用参考程序。是dsp入门的经典)
比GPU快几百倍!曦智科技首发新一代光电混合计算卡:128×128光子矩阵
低功耗定时器专用电路
ROHM开发出实现业界超高光辐射强度的小型表贴型近红外LED
3纳米可期?国内半导体技术重大突破
走近 MIPS
MAX752升压开关型DC-DC变换器的典型应用电路
英特尔:开源开放,全栈赋能,拥抱AIGC时代