我正在写一个回合制策略游戏。游戏中的每个玩家都有一组可以单独控制的单位。在用户的回合中,游戏目前遵循一系列相当不变的事件:
选择一个单位 - >移动所选单位 - >发出命令 - >确认
我可以通过创建一个游戏类来实现这一点,该游戏类可以跟踪玩家所处的这些阶段,并提供从一个阶段移动到下一个阶段的方法,如下所示:
interface TeamCommander {
public void select(Coordinate where);
public void move(Coordinate to);
public void sendCommand(String command);
public void execute();
}
然而,这将允许在错误的时间调用方法的可能性(例如,在调用move()
之前调用select()
),我想避免这种情况。所以我目前实现了无状态,如下所示:
interface UnitSelector {
public UnitMover select(Coordinate where);
}
interface UnitMover {
public UnitCommander move(Coordinate to);
}
interface UnitCommander {
public CommandExecutor sendCommand(String command);
}
interface CommandExecutor {
public void execute();
}
但是,我很难向用户提供此信息。由于这是无状态的,因此游戏模型不存储关于用户当前正在做什么的任何信息,因此视图不能查询关于它的模型。我可以在GUI中存储一些状态,但那将是糟糕的形式。所以,我的问题是:有没有人知道如何解决这个问题?
答案 0 :(得分:0)
首先,我没有得到这样的东西:你必须在某个地方存储持久状态,即使它只存在于View / GUI中。没有持久状态,你就无法拥有游戏。我猜你正在使用ASP或PHP;如果是这样,请使用会话来跟踪状态。
其次,将状态逻辑构建到其中,以便知道输入序列中每个玩家/该玩家团队中每个单位的位置。不要试图用它来表达。 B需要A,C需要B等。当你正在编写它时,如果调用顺序不正确(你应该检查每个用户输入,因为我认为这是一个事件驱动而不是循环驱动的游戏),只需通过抛出异常给自己一个脚手架,并调试从那里开始。
顺便说一句:当我看到上面第二个例子中的单个方法的接口时,我会产生怀疑。一个接口通常会告知有一个独特的 SET 功能,每个不同的类都可以实现 - 除非您尝试构建多个不同的类,这些类使用稍微不同的单个方法集签名,不要做你在那里做的事情。说“接口而不是实现的代码”一切都很好,但你需要首先采用自上而下的方法,说:“我的最终客户端代码(在你的根游戏逻辑类或方法中)如何需要?要求发生这样的事情?“并继续向调用堆栈询问该问题(即在每个后续的子调用代码点)。如果你试图从下到上构建它,你将最终得到我在那里看到的令人困惑和不必要的复杂代码。我经常看到的另一个例外是命令模式,通常看起来像
void execute();
或
void execute(Object data);
...但通常不一大堆略有不同的方法签名(再次可能,但不太可能)。我的直觉来自于我对这些结构的体验,因为它们通常没有意义,你最终会完全重构使用它们的代码。