回合制游戏设计:事件驱动与游戏循环
我正在用Java创建我的第一个游戏。游戏是大富翁。我正在努力设计游戏以对其回合制结构进行建模(管理玩家回合)。我想允许一个人类控制的玩家和一个或多个AI控制的玩家玩游戏。
我的具体问题是,我不知道是否要实现游戏循环,这意味着一个循环可以管理玩家和与大富翁游戏直接相关的变量,(想想诸如提示每个玩家轮到他们的回合,增加对下一个玩家的回合,或者依次从每个玩家那里获得掷骰子的事情)。我指的不是“游戏循环”这个术语的低级含义,它更多地涉及在屏幕上绘制帧,更新物理或以特定时间速率更新AI。
我的理解是,我试图实现我需要的东西的选择是:
- 实现一个完全没有这种游戏循环的完全事件驱动的程序,或者
- 实现一个游戏循环 - 只要游戏正在运行,它就在后台长时间运行,基本上永无止境。这将是更程序性的办法。
当我第一次开始尝试解决这个问题时,我遇到了UI冻结的问题,因为我的游戏循环永无止境,并且完全消耗了它正在运行的线程(我只是做了一个非常简单的 while 循环来说明这一点)。因此,我努力创建一个来封装我的游戏循环。这解决了UI冻结的问题,但仍然让我怀疑我是否走错了路。SwingWorker
作为一般规则,我发现网络上的大多数建议通常似乎都倾向于任何事件驱动的方法,因此我目前使用a的实现可能是朝着错误方向迈出的一步。但是我无法完全理解如何为这个特定任务实现一个完全事件驱动的系统(意味着不存在游戏循环)。在我看来,在某个地方必须存在一个循环来管理玩家回合。SwingWorker
以下是我的具体问题:
- 游戏循环(正如我所描述的那样)是否适合于基于回合的游戏,例如Monopoly,专门用于对玩家回合进行排队并提示适当的玩家进行回合,一次一个玩家(并对构成回合的整个步骤/步骤序列进行排队)?
- 如果要创建一个纯粹的事件驱动系统来管理玩家回合,你如何迭代每个玩家以提示他们轮到他们,并不断迭代,直到游戏结束?
- 如果要使用游戏循环来解决上述特定问题,它是否必须在自己的线程中运行(可能使用)以避免冻结UI?我的情况是特定于Java的,但我想我也会对非Java特定情况的答案感兴趣。
SwingWorker
目前,我使用MVC模式组织代码。我的控制器是我的游戏循环(实际线程)所在的位置。它远未完成,但它有助于说明我如何在我称之为“游戏循环”的玩家回合中管理玩家回合。SwingWorker
来自控制器的 SwingWorker
代码:
swingWorker = new SwingWorker<Void, Model>() {
@Override
protected Void doInBackground() throws InterruptedException {
gameLoopRunning = true;
while (gameLoopRunning) {
//to do: use a timer instead of thread.sleep
Thread.sleep(1000);
//user turn prompt
if (model.getActivePlayer().isUserControlled()) {
boolean userRolled = false;
while(!userRolled) {
System.out.println("Roll the dice please...");
Thread.sleep(3000);
}
}
//bot turn prompt
else {
//insert code for bot rolling dice here
model.rollDice();
}
publish(model);
Thread.sleep(1000);
model.incrementPlayerTurn();
publish(model);
}
return null;
}
@Override
protected void process(List<Model> chunks) {
Model gameModel = chunks.get(chunks.size() - 1);
//hard-coded for 6 players
for (int i = 0; i < 6; i++) {
view.getPlayerPanel(i).setTurn(gameModel.getPlayers().get(i).isTurn());
}
view.getGamePanel().getDice().setDie1(model.getDie1());
view.getGamePanel().getDice().setDie2(model.getDie2());
}
};
swingWorker.execute();