我经常对状态或阶段采取的一种方法是创建一个管理器类。本质上,您需要一个GamePhase
具有Initialise()
、和方法的对象,并且Update()
可能还有。通常也值得拥有某种处理移交的方法。稍后再谈。一旦你有了这个类,从它继承来为每个阶段创建一个类;, ,等Draw()
Dispose()
Pause()
Resume()
SoldierPlacementPhase
MovementPhase
AttackPhase
然后你有一个GamePhaseManager
类,它有Initialise()
、和方法Update()
,可能还有某种方法。您还需要一种将状态添加到管理器的方法——它需要一种存储它们的方法。我建议使用 an或作为键。您的方法将把该键作为参数。Draw()
Dispose()
SetCurrentPhase()
Add()
Dictionary<>
int/enum
string
SetCurrentPhase()
基本上,您要做的就是在游戏中设置一个实例GamePhaseManager
,然后创建并初始化每个阶段对象并将其添加到管理器中。然后你的游戏的更新循环将调用GamePhaseManager.Update()
,它只是调用当前状态的 Update 方法,并传递参数。
您的阶段将需要某种方式来告诉它们何时该结束,以及某种处理方式。我发现最简单的方法是设置你的GamePhase
对象,然后有一个方法,就像GamePhase.SetNextPhase(GamePhase next)
它为每个阶段提供一个对下一个阶段的引用。然后他们所需要的只是一个Exiting
带有受保护设置器和公共获取器的布尔值,这样当他们的内部逻辑决定该阶段结束时,他们可以设置Exiting = true
它们Update()
,然后GamePhaseManager.Update()
你可以这样做:
public void Update(TimeSpan elapsed)
{
if (CurrentPhase.Exiting)
{
CurrentPhase.HandOver();
CurrentPhase = CurrentPhase.NextPhase;
}
CurrentPhase.Update(elapsed);
}
你会注意到我在更新前改变了阶段。这样退出阶段就可以完成它的循环;否则你会得到奇怪的行为。该CurrentPhase.HandOver()
方法基本上让当前阶段传递下一阶段需要知道的任何内容,以便从正确的点继续。这可能是通过让它在NextPhase.Resume()
内部调用,将它需要的任何信息作为参数传递给它来完成的。记得也设置Exiting = false
在这里,否则只更新一个循环后它会继续移交。
这些Draw()
方法以相同的方式处理 - 你的游戏循环调用GamePhaseManager.Draw()
,它只是调用CurrentPhase.Draw()
,传递参数。
如果你有任何不依赖于阶段的东西——例如地图——你可以将它存储在 中GamePhaseManager
并在 的方法中调用它GamePhaseManager
的方法,你可以让阶段传递它并让它们调用它的方法,或者您可以将其保持在顶层并在GamePhaseManager
's. 旁边调用它的方法。这取决于阶段需要对其进行多少访问。
编辑
您的编辑表明您知道上面的大部分内容,但我将其留在那里以帮助将来遇到此问题的任何人。
如果你已经有一个经理来处理游戏的各个阶段,我的直觉是嵌套它。你看到你的游戏有阶段,并建立了一个类来处理它们。您有一个拥有自己的阶段的阶段,那么为什么不使用您已经编写的阶段处理代码呢?Screen
从你的对象继承来拥有一个SubdividedScreen
类,或者任何你想调用它的东西。这个新类与父类基本相同,但它也包含自己的ScreenManager
类实例。用这些对象之一替换Screen
您正在调用的对象,并用实例填充它以表示各个阶段(、等)。您可能需要对map
SubdividedScreen
ScreenManager
Screen
PlacementPhase
PlayerPhase
ScreenManager
代码以确保正确的信息可以到达需要它的方法,但它比使用Update()
switch case 细分的杂乱方法要整洁得多。