Java 实现大型状态机的最佳方法?
基本上,我有一个控制游戏角色攻击的状态机,根据动画长度计时 例如: 我从默认状态开始,如果玩家点击攻击按钮,它就会开始攻击,切换状态并根据攻击长度设置计时器。状态机变得更加复杂,但是当我考虑可以被取消的攻击攻击时,可以根据它们所击中的目标移动到不同的状态,并且每个州都有独特的方式来处理被攻击的角色。 目前我有大量的switch语句。我考虑过多态性,但这需要为每个状态创建一个新的类,其中有很多状态(例如,开始攻击、攻击和结束攻击都需要单独的状态) switch语句可以工作,但是它相当大,并且不像基于继承的系统那样容易修改 对美观的实现有什么建议吗 编辑:Java 实现大型状态机的最佳方法?,java,switch-statement,state-machine,Java,Switch Statement,State Machine,基本上,我有一个控制游戏角色攻击的状态机,根据动画长度计时 例如: 我从默认状态开始,如果玩家点击攻击按钮,它就会开始攻击,切换状态并根据攻击长度设置计时器。状态机变得更加复杂,但是当我考虑可以被取消的攻击攻击时,可以根据它们所击中的目标移动到不同的状态,并且每个州都有独特的方式来处理被攻击的角色。 目前我有大量的switch语句。我考虑过多态性,但这需要为每个状态创建一个新的类,其中有很多状态(例如,开始攻击、攻击和结束攻击都需要单独的状态) switch语句可以工作,但是它相当大,并且不像基
这是在使用java。Boost有一个完美的状态机,唯一的缺点是习惯于模板/类型编程
考虑构建一个表驱动的状态机。如果你想一想状态机的定义,你基本上有一组状态,有一个可分辨的初始状态,一个转换函数,以及(在本例中)一个输入和输出字母表 您可以构造一个按当前状态和输入索引的表,并使用指向函数的指针或函子类来表示所发生的情况。该函数应返回下一个状态。然后可以将状态机构建为(伪代码): 其中
lookupTransition(inputs)
只查找下一个状态。我在这里假设转换函数是无参数返回状态的函数,因此lookupTransition(inputs)
必须是有多少输入的函数,返回指向返回状态的无效参数函数的指针
正确地设置它,您可以将所有状态机和行为放在一个表中,该表可以轻松地修改和重新编译
(为了获得额外的积分,请找出如何从文件加载该表,这样就根本不需要重新编译。)
更新
在Java中,使用类似于函子类的东西来代替函数指针
另一次更新
当然,另一种选择是使用状态机编译器,比如。我不能说我曾经使用过它,但确实有。使用其他人建议的基于表格的方法,手工书写也不难 对于较大的状态机,您必须注意“过渡爆炸”现象。事实证明,传统的有限状态机不提供跨多个状态重用公共转换的机制,因此您最终会重复太多,并且您的状态机“爆炸”(这也违反了请勿重复自己(DRY)原则)
出于这个原因,我建议使用分层状态机和实现技术,允许轻松地将这些状态机映射到代码。有关分层状态机的更多信息,请参阅Wikipedia文章 在我这边,我正在使用stateforge和HFSM()。
并行状态、分层方法和观察者可以解决相当多的复杂情况。我习惯于模板编程,但我目前使用java,我可能应该提到这一点。这才是真正的问题,不是吗。只要您需要为每个状态/事件组合创建一个新类,代码就会变得非常冗长。我们将不得不等待结束,以最终能够做这样的事情简洁。目前,反射或代码生成可以用来减少代码混乱,但也有其自身的缺点。每个转换只有一行或两行闭包有帮助;使用函子使代码有点像饼干刀,但复杂性并没有那么大的不同。使用动态语言,如Ruby、Python或Groovy,可能会有所帮助,但主要是因为它会使表加载部分更容易。但最终,如果你有一个复杂的状态机,你将不得不编写代码。
state := initial state
while(state != STOP)
state := (lookupTransition(inputs))()