2013-07-25 110 views
8

我正在用Java创建我的第一款游戏。游戏是垄断。我正在努力设计游戏来模拟其基于回合的结构(管理玩家轮流)。我想让一个人控制的和一个或多个AI控制的玩家玩这个游戏。回合制游戏设计:事件驱动vs.游戏循环

我的具体问题是我不知道是否实施游戏循环,意味着可以管理玩家和直接与大富翁游戏相关的变量的循环(想到诸如提示每个玩家轮到他们,增加轮到下一个玩家,或从每个玩家获得骰子 - 反过来)。我并不是指“游戏循环”这个术语的更底层含义,它更多地涉及屏幕上的绘制帧,更新物理或在特定时间更新AI。

我的理解是,我的努力来实现我所需要的选项要么:

  1. 实现一个完全由事件驱动的程序,有没有这样的游戏循环,或
  2. 实现游戏环 - 一些在后台长时间运行并且只要游戏运行就基本上不会结束的东西。这将是更程序化的方法。

当我第一次尝试解决这个问题时,遇到了我的UI冻结问题,因为我的游戏循环没有结束,并且完全消耗了它正在运行的线程(我只是做了一个非常简单的while循环来说明这一点)。所以我去努力创建一个SwingWorker来封装我的游戏循环。这解决了UI冻结的问题,但仍然让我想知道我是否走错了路。

作为一般规则,我发现网上的大多数建议似乎都倾向于任何事件驱动的方法,因此我目前使用SwingWorker的实现可能是朝着错误方向迈出的一步。但是我不能完全理解我将如何为这个特定任务实现一个完全由事件驱动的系统(意味着没有游戏循环)。在我看来,循环必须存在于管理玩家轮流的地方。

这里是我的具体问题:

  1. 是游戏圈(如我描述他们)适合的回合制游戏,如垄断,专为排队播放器将和提示轮到自己相应的播放器,一次一个玩家(排队组成一个回合的整个步骤/序列)?
  2. 如果要创建一个纯粹的事件驱动系统来管理玩家轮流,你如何迭代每个玩家以提示他们轮到他们并继续迭代直到游戏结束?
  3. 如果要使用游戏循环解决上述特定问题,是否必须在其自己的线程内运行(可能使用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(); 
+0

垄断是不是从棋太大的不同,对我来说更有意义,让它事件驱动,因为它可以让规则的实现要容易得多,就像国际象棋,因为每个事件试图影响一些国家。 – arynaq

+0

不管你如何实现它,你可能不希望在UI线程上正在做您的游戏CPU周期。 – Tim

+1

如何使用有限状态机来表示游戏状态更改?我曾经用过一个粗糙的游戏来开发一个跳棋游戏,并使用基于事件的UI代码。 – SirDarius

回答

9

从SirDarius注释是即期。

虽然,对,作为推进播放器将简单的东西,你真的不需要费心实现完全成熟的有限状态机。

在MVC而言,这是你应该为玩家做什么:

  • 的型号:为推进现役球员到下一个球员,通过运行方法“转动过程“(即掷骰子,移动主动玩家的令牌等)。由于大部分转向过程是事件驱动的,因此这些方法调用将由控制器中的事件监听器完成。

  • 查看:当活动玩家完成他们的回合时提出一个事件,并在其他各种输入中引发事件。

  • 控制器:每当玩家完成他们的转弯,告诉模型前进到下一个玩家,并再次开始“转弯过程”。每当玩家提供输入时,就会触发一个事件,告诉模型前进到回合的下一个阶段。

对于AI球员,大部分相同的代码可以使用,但它没有意义有进展转由视图驱动。相反,该模型需要有另一种专门用于AI玩家的“转向过程”方法。唯一的区别是代码会连续执行而不等待视图的输入,而不是一系列事件监听器。

+0

我不关注您对该视图的评论。点击按钮时,我可以理解视图触发事件,但只要在“大富翁”中开始和结束,可能没有专用按钮用于开始或结束一个转弯。除此之外,AI机器人开始和结束轮到他们呢?很明显,他们不会与管理轮流的观点互动,是吗? – nairware

+0

@nairware垄断的玩家会自然而然地发展。只有很多任务需要执行,其中之一是任何回合的最后一项任务。在一般情况下,玩家将掷骰子,移动他们的一块,执行动作(购买房产,缴纳罚款,抓一张牌等),购买房屋,和(可选)进行交易。如果玩家入狱,转场过程会发生变化,但玩家仍有最后的行动要执行。当玩家完成他们的最终动作(或者点击上下文的“结束转动”按钮)时,转弯可能结束。 –

+0

我遵循。当然,结束这一转折的事件是有道理的。我只是不清楚这个观点与这个事件有什么关系。我认为你假设有一个“结束转弯”按钮,在这种情况下,你对视图的描述是合理的。AI控制的玩家不会点击这样的按钮,所以你也只能假设人为控制的玩家。同样的结局转向事件会为AI控制的球员射击,但不会从按钮点击或任何相关的视图(在我的估计中)。 – nairware