游戏编程模式:状态模式

“允许一个对象在其内部状态改变时改变自身的行为。对象看起来好像是修改自身类。”

模式动机:

在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。

模式结构:

  • 环境类
  • 抽象状态类
  • 具体状态类

自动机:

并发自动机:

当存在两种不同类型的状态(n个,m个),它们种间会产生交叉,此时如果使用普通的有限状态机需要定义n*m个具体状态。如果使用两个并行的状态机,那么仅需n+m个具体状态。

此时环境类需要持有两个状态索引,用于处理两个状态的行为。

1
2
3
4
5
6
7
8
9
10
11
class Content
{
private State state1;
private State state2;

void getBehavior(Input input)
{
state1.Update(input);
state2.Update(input);
}
}

这样每一个状态机都可以响应输入事件并以此切换状态,而不用考虑其他状态机的实现细节。(当两个状态没什么关系的时候,这种方法可以很好的实现。

层次自动机:

当主角的不同行为对相同的输入可能会执行相同的行为时,我们可以将这些具体的状态类进行提取,生成一个父类。

一个状态有一个父状态,当有一个事件进入时,如果子状态不处理它,那么沿着继承链传给它的父状态来处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Content
{
private FatherState state;
void getBehavior(Input input)
{
state.Update(Input);
}
}

class FatherState
{
public void Update(Input input)
{
if(check Child)
{
child.Update(input);
// 也可以this = new Child();?
}
else
{
//do something;
}
}
}

class ChildState : FatherState
{
public override void Update(Input input)
{
//do something;
}
}

下推自动机:

如果需要恢复到上一个状态,则使用一个栈来保存当前状态,当前的状态总在栈顶,执行之后恢复,弹出栈顶状态。