组合FSM的状态是否“正确”?
假设你有一个
的对象enum State
{
State1 = 1 << 0,
State2 = 1 << 1,
State3 = 1 << 2
} ;
恰好,组合状态是有意义的,如
State myState = State1 | State2 ;
然而,在FSM理论中这是非法的吗?
这是一条捷径:
假设你有3种状态:跑步,走路和跳跃。然后你有第四个状态射击。
你需要能够跑步和射击,步行和射击,以及跳跃和射击。而不是制作6种状态RunningFiring,WalkingFiring,JumpingFiring,我想组合射击状态(无论走路跑步跳跃状态)
我知道我可以使用BOOL作为“第四状态”,但这看起来不是甚至是wronger吗?有一个“状态......”
答案 0 :(得分:1)
在我看来,当你开始需要组合这样的状态时,你的状态机开始做太多了。您可能需要考虑将一些功能/逻辑移动到一个单独的状态机,该状态机专注于在“父”状态机处于另一个状态时可能会或可能不会改变状态的一个任务。
答案 1 :(得分:1)
我记得在13岁左右的时候读过一本关于游戏编程的书,看到一个用于建模属性的位掩码的例子。像
这样的东西const int HAS_WEAPON = 0x1;
const int WEARING_ARMOR = 0x2;
const int IS_ALIENT = 0x4;
等等。然后你可以将NPC的属性表示为int,并且可以使用属性作为掩码来设置/清除各个位。
现在,当然,当内存变得更便宜时,bitpacking就不常见了,因此我们可以使用布尔值来表示属性。无论如何,这似乎与您想要做的类似。
但是,属性与状态机中的状态不同。在状态机中,处于一种状态意味着您不一定处于任何其他状态。因此,如果你有一堆不相互排斥的东西,状态机可能不是你要走的路。请考虑您添加的每个二进制值属性将使整个机器的大小加倍。
当你说
时我知道我可以使用BOOL来实现 “第四国”,但似乎没有 甚至是wronger?拥有“状态” 侧..“
它向我表示,您正在考虑您所代表的信息的方式可能存在问题。当然,“射击”听起来像一个状态的好候选人,如果你总是要么开火或做其他事情,那么它就像一个状态机。但是,如果“Firing”可以与现有系统中的所有状态结合使用,那么将它作为属性进行建模会不会有任何损害?
答案 2 :(得分:1)
在我看来,这是状态的AND分解(以及正常的异或分解)的一个例子。 UML使用正交区域模拟这种情况。因此,在这种情况下,您有两个正交区域。第一个包含正常的OR状态Running,Walking和Jumping。另一个正交区域包含状态点火。此状态机允许以下组合:运行|射击,步行|射击和跳跃|射击。
您可以使用两个状态机来近似这两个正交区域(您需要两个状态变量)。目前,Firing的状态机只有一个状态,但我相信你最终会得到补充状态“not-Firing”,所以它将成为一个合适的状态机。
Miro Samek,state-machine.com