状态模式(状态机)

Unity中的有限状态机和状态模式设计       游戏开发过程中,各种游戏状态的切换无处不在。但很多时候,简单粗暴的if else加标志位的方式并不能很地道地解决状态复杂变换的问题,这时,就可以运用到状态模式以及状态机来高效地完成任务。状态模式与状态机,因为他们关联紧密,常常放在一起讨论和运用。而本文将对他们在游戏开发中的使用,进行一些探讨。      当然,要我一下讲的很明白,估计也不太可能,还是老样子,我们进行文章和代码分析,最后... 阅读详情

以前写状态机,比较常用的方式是用 if-else 或 switch-case,高级的一点是函数指针列表。最近,看了一文章《c语言设计模式–状态模式(状态机)》(来源:embed linux share,作者:亚索老哥)),原来状态机还可以这么简单地玩~~

亚索老哥提出的状态机六步法

(1)、定义状态接口
(2)、定义系统当前状态指针
(3)、定义具体状态,根据状态迁移图来实现具体功能和状态切换
(4)、定义主程序上下文操作接口
(6)、主程序通过上下文操作接口来控制系统当前状态的变化

亚索老哥的状态机例程

场景:

  • 设计一个简单的MP3播放器,要求两个按键(播放/暂停、停止)分别控制MP3的播放/停止功能

按键功能:

  • [play/pause] 播放/暂停
  • [stop] 停止

状态迁移图:
在这里插入图片描述

#include <stdio.h>

/***********************************************
1、定义状态接口,以MP3的状态接口为例,每种状态下都可能发生
两种按键动作。
************************************************/

typedef struct State{
    void (* stop)();
    void (* palyOrPause)();
}State;


/***********************************************
2、定义系统当前状态指针,保存系统的当前状态
************************************************/

State * pCurrentState;


/***********************************************
3、定义具体状态,根据状态迁移图来实现具体功能和状态切换。
************************************************/

void ignore();
void startPlay();
void stopPlay();
void pausePlay();
void resumePlay();

//空闲状态时,stop键操作无效,play/pause会开始播放音乐
State IDLE = {
        ignore,
        startPlay
};

//播放状态时,stop键会停止播放音乐,play/pause会暂停播放音乐
State PLAY = {
        stopPlay,
        pausePlay
};

//暂停状态时,stop键会停止播放音乐,play/pause会恢复播放音乐
State PAUSE = {
        stopPlay,
        resumePlay
};

void ignore()
{
    //空函数,不进行操作
}

void startPlay()
{
    //实现具体功能
    printf("开始播放音乐\n");
    //进入播放状态
    pCurrentState = &PLAY;
}
void stopPlay()
{
    //实现具体功能
    printf("停止播放音乐\n");
    //进入空闲状态
    pCurrentState = &IDLE;
}

void pausePlay()
{
    //实现具体功能
    printf("暂停播放音乐\n");
    //进入暂停状态
    pCurrentState = &PAUSE;
}

void resumePlay()
{
    //实现具体功能
    printf("恢复播放音乐\n");
    //进入播放状态
    pCurrentState = &PLAY;
}


/***********************************************
4、定义主程序上下文操作接口,主程序只关心当前状态,不关心状态之间
是怎么变化的。
************************************************/

void onStop();
void onPlayOrPause();

State context = {
        onStop,
        onPlayOrPause
};

void onStop(State *pThis)
{
    pCurrentState->stop(pThis);
}

void onPlayOrPause(State *pThis)
{
    pCurrentState->palyOrPause(pThis);
}


/***********************************************
5、初始化系统当前状态指针,其实就是指定系统的起始状态
************************************************/

void init()
{
    pCurrentState = &IDLE;
}

/***********************************************
6、主程序通过上下文操作接口来控制系统当前状态的变化
************************************************/
void main()
{
    init();
    context.palyOrPause();//播放
    context.palyOrPause();//暂停
    context.palyOrPause();//播放
    context.stop();//停止
}

模拟一个状态机

TODO

小结

亚索老哥的状态机六步法,有许多优点,还是借用原话:

  • 代码结构要更加清晰,避免了过多的switch…case或者if…else语句 的使用。
  • 很好地体现了开闭原则和单一职责原则,每个状态都是一个子结构体,你要增加状态就要增加子结构体,你要修改状态,你只修改一个子结构体就可以了。
  • 封装性非常好,状态变换放置到子结构体的内部来实现,外部的调用不用知道子结构体的内部如何实现状态和行为的变换。
状态模式与订单状态机的实现 定义一个状态接口或抽象类,声明所有具体状态类需要实现的方法。上下文类持有一个当前状态的引用,并允许状态对象修改它的状态。// 默认初始状态状态模式通过将状态行为分离到不同的状态类中,允许对象在其状态改变时改变其行为。这种模式提供了一种优雅的方式来处理状态变化,避免了在上下文类中使用大量的条件判断,提高了代码的可维护性和扩展性。在实际应用中,可以使用状态设计模式来管理各种状态驱动的行为,比如订单状态、工作流状态等。PENDING_PAYMENT, // 待支付PAID, // 已支付。 阅读详情

相关推荐

C语言实现状态机:详解与示例代码

在上面的示例代码中,我们定义了三个状态:IDLE(空闲状态)、RUNNING(运行状态)和FINISH(完成状态)。通过定义状态和状态之间的转换条件,并使用条件语句进行状态切换,我们可以有效地处理复杂的逻辑流程。通常,我们会使用枚举类型来定义状态,并使用条件语句(如switch语句)来处理状态之间的转换。每个状态代表系统或程序在某一时刻的行为或状态,而状态之间的转换代表了不同条件下状态的变化。我们可以根据具体的需求定义更多的状态和状态之间的转换条件,以实现更加复杂的程序逻辑。

PixelLoom的博客 1528

设计模式之状态模式

状态模式,又称状态机模式,属于行为型设计模式的一种,定义:允许一个对象在内部状态发生改变时改变其行为,就好像是改变了自身的类一样。如果状态简单,这种if else语句看上去是没有问题的,但是如果状态变得复杂起来,多种状态之间互相作用,关联,这种代码就会变得非常复杂,比如使用大量的flag去维护状态和状态之间的转换,使得这部分代码变得难以维护,最重要的是这部分代码将在客户端进行维护,客户端不得不关心各个状态之间的转换和具体的行为。

weixin_39765162的博客 748

C语言实现状态机的三种方法(附完整源码)

本文介绍了C语言实现状态机的三种方法:1)switch-case方法,通过分支语句实现状态转换,适合简单场景;2)状态转移表法,使用二维数组定义状态转换规则,便于维护复杂状态机;3)函数指针映射法,将状态封装为独立函数,实现面向对象风格。每种方法都提供了完整代码示例,展示了从状态定义到转换处理的具体实现。根据状态机复杂度可选择不同方案,switch-case适合简单逻辑,转移表适合中等复杂度,函数指针法则适用于需要封装状态行为的场景。

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1035

C语言实现状态机(二)

前言 对于之前的一篇博客《C语言实现状态机》(链接:https://blog.youkuaiyun.com/qq_36969264/article/details/105865099?spm=1001.2014.3001.5501),看网友的留言,似乎对pFsm->stNextState 和 EVENT_MAP_END的比较有一些误解。 这里需要解释一下,当时这么写是为了省事,但后面看这么写确实很容易让人误解,所以这篇文章的目的是为了修改掉这个容易让人误解的地方,同时对该状态机做了一些优化。 一、实现状态机的基本

qq_36969264的博客 8733

状态机设计实例:单片机上的有限状态机实现

状态机由一组状态和状态之间的转换组成。状态之间的转换由事件触发,根据当前状态和事件,系统会根据预定义的转换规则切换到下一个状态。状态机的设计可以帮助我们清晰地描述系统的行为和状态转换规则,从而提高系统的可维护性和可扩展性。在嵌入式系统的开发中,状态机是一种常用的设计模式,用于描述系统的行为和状态转换。本文将介绍如何在单片机上实现一个简单的有限状态机,并提供相应的源代码。下面我们以一个简单的LED控制器为例,说明状态机的设计和实现过程。当然,实际的状态机设计可能更加复杂,并涉及更多的状态和事件。

UoEmacs_Lisp的博客 669

使用MLP解决OCR问题(OpenCV)(下)

分类模型:        分类模型涉及的一个比较关键的问题就是输出的10维向量是如何与具体的类别挂钩的。实际上:10维向量的每一位都代表一类,在对于训练集的表达中,如果输入数据是0,则10维向量的第一位赋值为1,其余均为0。即0对应[1,0,0,0,0,0,0,0,0,0]。MLP模型训练完成后,就需要对用户输入的数据所属类别进行判定。这时得到的输出数据基本不可能是正好的所属类为1,其他位置为0

qq_18515405的专栏 1907

详解状态模式以及Spring状态机

详解状态模式以及Spring状态机 前言 讲设计模式之前我们先来了解下设计模式的SOLID原则: S(Single Responsibility Principle):单一职责原则,接口职责应该单一,不要承担过多的职责。 O(Open Closed Principle):开闭原则,即对扩展开放,对修改关闭。简单来说就是代码的设计要达到:当别人要修改扩展功能的时候,最好能不要修改我们原有代码,而是新增代码来实现空能的扩展。这也是我们设计时要达到的目标。 L(Liskov Substitution Princ

贾廷帅的博客 5734

跨时钟域传输数据——单bit和多bit信号(总结)

总结单bit和多bit信号的跨时钟域传输

qq_42135020的博客 1万+

在游戏中看状态机与状态模式

状态机与状态模式 状态机 最早接触状态机这个词来自编译原理的学习,在词法分析中,通过有限状态机来进行单词识别。状态机在里面被定义为一个数学模型,一个五元组。 截图来自维基百科 对于Android开发者,可能最为熟知的就是MediaPlayer的状态机图了 状态机一般有四个要素 现态:状态机当前所处的状态 条件:触发动作或者状态迁移的条件(在按键系统中,就是指按键的值) 动作:条件满足后执行的动作(也就是响应各个任务,在代码中往往一个动作对应一个方法) 次态:动作完成后要迁移的下个状态 上图中蓝色圆圈

skateboard1的专栏 560

SimNow模拟环境实战:用vnpy_ctp连接期货市场的5个关键配置步骤

本文提供了一份详细的量化交易实战指南,重点讲解如何使用vnpy_ctp插件连接SimNow期货模拟环境的5个关键配置步骤。内容涵盖SimNow环境选择、vnpy_ctp核心参数解析、实战连接脚本编写、深度排错技巧以及向实盘迁移的准备,旨在帮助量化交易开发者快速搭建可靠的测试环境,避免常见陷阱。

weixin_29063035的博客 1273

Truncated SVD for faster dection

Truncated SVD方法最先被提出在《Fast R-CNN》论文中,用于降低全连接层的运算量,提升模型的速度。在卷积神经网络的分类任务中,FC层的运算速度远远大于CONV层,而在Fast R-CNN的目标检测任务中,大多数的运算时间发生在FC 的运算中,是因为针对每张输入图片,只进行一次卷积操作,而要对生成的Region Proposal,大致两千个,进行全连接操作进行分类与Bounding...

weixin_35747666的博客 1535

【设计模式】状态模式和状态机的区别和联系

大多数资料、文章,都没有解释状态模式和状态机的关系,而是将这两个词混淆着使用。如果你有这方面的疑惑,希望本文能给你带来帮助。如果有描述不当的地方,也请帮忙指正 以下并不涉及状态模式/状态机的基础内容,且均为个人理解 比较好的,对该问题进行的讨论 stackoverflow-What is the difference between a state machine and the implementation of the state pattern? The Super State Design .

无数_Mirage的博客 3103

Unity开发HoloLens应用:从打包到部署的完整指南

本文为Unity开发者提供了将应用部署到HoloLens设备的完整实战指南。详细讲解了从环境准备、Unity项目配置、生成Visual Studio工程,到最终构建APPX安装包并通过设备门户或Visual Studio进行部署的全流程,帮助开发者高效完成混合现实应用的打包与安装。

red88的博客 1019

状态机、状态模式

一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类状态类

Cookie__C的博客 1476

S7-1200中时钟功能设定和读写调用的具体方法

S7-1200中时钟功能设定和读写调用的具体方法

Robot_PLC_HMI_Automation 1万+

couldn‘t upgrade db schema: insert into ACT_GE_PROPERTY values (‘common.sche[已解决]

启动整合了flowable的项目,初始化时报错。flowable没有自动建表, 原因 测试数据库版本是MySQL5.7。经过查询和尝试,原因是:在这个数据库里面,已经有一个数据库里面有activiti的这些表了,它检索的时候全库检索查到它了,所以flowable不去建表了,但是我们指定的这个schema里卖弄还是空的,所以它报了找不到表。解决方法:mysql的链接上加上参数如下,让本schema成为默认的schema。...

JavaPub 6014

状态模式与android状态机

最近项目中需要上传文件,各种上传异常、重传、断点续传状态很多很复杂,决定使用状态模式,所以研究一下状态模式。 一、状态模式介绍 1. 一般性UML图   2. 简单例子 以上传文件为例学习一下状态模式 给IState设置3个接口,分别是请求上传、上传、上传完成;定义三个状态实现IState接口,每个状态都需要实现这三个接口,如下:   定义Uploader类作为Contex

三轮车的博客 3546

Apollo 9.0 速度非线性规划算法 – piecewise jerk speed nonlinear optimizer Ⅰ

二次规划的速度规划算法(PiecewiseJerkSpeedOptimizer)的存在两个问题: 这里以一张图来说明上面的问题,假设存在一个实际限速区间(或曲率很大需要降速的区间)[S1, S2],PiecewiseJerkSpeedOptimizer的做法是根据动态规划的st曲线(黑色),找到具体的时间区间[T1, T2],然后对区间[T1, T2]内所有的点施加约束或惩罚。但是二次规划平滑后的曲线(黄色)发生了变化,那么限速区间[S1, S2]对应的时间区间[T1, T2]也发生了变化,所以实际应该是对

WaiNgai 334

科普文:软件架构Spring系列之【Spring状态机的设计模式:状态模式(State Pattern)】

摘要:本文深入解析Spring Statemachine状态机中运用的设计模式,重点阐述状态模式(State Pattern)的实现原理。通过对比传统分支逻辑方案,说明状态模式在管理复杂状态流转时的优势:代码更清晰、维护性更高。文章详细介绍了Spring Statemachine中状态模式的三个核心角色(Context、State、ConcreteState)及其协作方式,并以红绿灯状态变更案例进行演示。同时指出状态模式与策略模式的区别在于前者关注状态流转,后者关注策略选择。此外,还提及了观察者、策略、模板

为无为,事无事,味无味。 1587

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

嵌入式状态机(三)状态模式状态机

嵌入式状态机的进阶用法——状态模式

weixin_71547062的博客 913

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

状态机和状态模式

原文超链接 又是很长时间没有写博客了(一个月)…最近在做一个SpringBoot+Vue的项目,所以一直在看spring相关的东西。今天要学习的跟spring 没有关系,是我在之前维护的一个测试工具是遇到的一个知识点–状态机 这个测试的一个功能就是解析自己定义的一套脚本语法规则,涉及到对输入的语句进行解析,然后下发到对应的执行器去执行。 之前的解析逻辑是用一个while循环,对每一个字符判断,然后...

KerwinTwinkle的博客 3015

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

设计模式:状态模式与状态机

文章目录前言 前言 在工作时遇到了这样一个需求: 控制消毒柜: 1. 当柜门打开时,关闭消毒,并重置已消毒时间; 2. 当柜门关闭时,打开消毒,并在指定时间(如30分钟)后关闭消毒; 在接到这个需求后,我第一反应就是有很多的状态流转,可以试一试状态模式。本文通过这样一个真实的公司需求,讲解设计模式中的状态模式,以及他的应用----状态机。 ...

gxhuhuhu的博客 2080

有限状态机与状态模式

先来看看我们编程时常见的一个例子 enum Network_State { Net_Close, Net_Open, Net_Connect, }; void operation(int state) { if (state == Net_Close) { // 。。。。 } else if (state == Net_Open) { // 。。。。 } else if (state == Net_Connect) {

weixin_43796767的博客 979

JavaScript状态模式及状态机模型

这是一篇,我自己都看不完的文章...文章大体就两部分:状态模式的介绍状态机模型的函数库javascript-state-machine的用法和源码解析场景及问题背景:我们...

大转转FE 994

状态机 和 状态模式

状态机简写为FSM(Finite State Machine),主要分为2大类:有限状态机,(英语:Finite-state > machine, FSM),又称有限状态自动机 。 第一类,若输出只和状态有关而与输入无关,则称为Moore状态机 第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机 1 . 介绍状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳

孙青云的博客 6171
上一篇: 学习KEA之FTM
下一篇: 学习KEA之ADC之一:基本介绍
大橙员
博客等级 码龄14年 185粉丝 52原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值