我正在使用Java创建我的第一个游戏,它是大富翁。我正在考虑如何设计游戏以建模其回合制结构(管理玩家回合)。我想允许单个人类控制和一个或多个AI控制的玩家参与游戏。
我遇到的具体问题是,我不知道是否要实现游戏循环,也就是可以直接管理与Monopoly游戏相关的变量和玩家的循环(例如提示每个玩家进行回合、将回合递增至下一位玩家或获取每个玩家的骰子点数——依次进行)。我不是指更低级别意义上的“游戏循环”,它更涉及在屏幕上绘制帧、更新物理或以特定时间率更新AI。
我理解我尝试实现所需内容的选项为:
- 实现完全事件驱动程序,没有这样的游戏循环
- 实现游戏循环——作为后台长期运行并基本上永远不会停止,只要游戏在运行。这将是更过程化的方法。
当我开始尝试解决这个问题时,我遇到了UI冻结的问题,因为我的游戏循环是无休止的,并且完全占用了它运行的线程(我只是创建一个非常简单的while循环来说明这一点)。因此,我努力创建了一个SwingWorker
来封装我的游戏循环。这解决了UI冻结问题,但仍让我想知道我是否走错了方向。
通常,我发现网上的大多数建议似乎青睐于任何事件驱动的方法,因此我目前的实现使用SwingWorker
可能是朝错误的方向迈出的一步。但是,我无法完全理解如何为此特定任务实现完全事件驱动的系统(没有游戏循环)。在某个地方必须存在一个循环以管理玩家回合。
以下是我的具体问题:
- 像大富翁这样的回合制游戏是否适合使用游戏循环(我所描述的)——特别是用于排队玩家回合并提示适当的玩家进行回合,每次一个玩家(和排队整个回合的过程/步骤序列)?
- 如果要创建纯事件驱动系统来管理玩家回合,如何迭代每个玩家以提示他们进行回合,并保持迭代直到游戏结束?
- 如果要使用游戏循环来解决上述特定问题,是否必须在自己的线程中运行它(可能使用
SwingWorker
)以避免UI冻结?我的情况是Java特定的,但我想我也会对非Java特定情况的答案感兴趣。
目前,我正在使用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();