回合制游戏设计:事件驱动与游戏循环 [英] Turn-based Game Design: Event-Driven vs. Game Loop

查看:118
本文介绍了回合制游戏设计:事件驱动与游戏循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java创建我的第一个游戏.游戏是大富翁.我正在为如何设计游戏以基于回合结构(管理玩家回合)建模而苦苦挣扎.我想允许一个人类控制的玩家和一个或多个AI控制的玩家一起玩游戏.

I am creating my first game in Java. The game is Monopoly. I am struggling with how I should design the game to model its turn-based structure (managing player turns). I want to allow for both a single human-controlled and one or multiple AI-controlled players to play the game.

我的具体问题是我不知道是否实施游戏循环,这意味着可以管理玩家和与大富翁游戏直接相关的变量的循环(例如,提示每个玩家选择他们的回合,将回合增加到下一个玩家,或依次从每个玩家那里掷骰子.我指的不是游戏循环"一词的低级含义,它更多地涉及在屏幕上绘制框架,更新物理特性或在特定时间更新AI.

My specific issue is that I do not know whether to implement a game loop or not, meaning a loop which can manage the players and the variables directly related to the game of Monopoly, (think of things such as prompting each player for their turn, incrementing the turn to the next player, or getting dice rolls from each player—in turn). I am not referring to the more low-level meaning of the term "game loop" which relates more to drawing frames on the screen, updating physics, or updating AI at a specific rate of time.

我的理解是,我尝试实现我所需要的方法的选择之一是:

My understanding is that my options for trying to implement what I need are either to:

  1. 实施一个完全由事件驱动的程序,而该程序没有这种游戏循环,或者
  2. 实施游戏循环-在后台长时间运行的东西,只要游戏正在运行,就基本上不会停止.这将是更具程序性的方法.

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

When I first started trying to solve this issue, I ran into problems of my UI freezing because my game loop was never-ending and was completely consuming the thread on which it was running (I just made a very simple while loop to illustrate this). So I went to the effort of creating a SwingWorker to encapsulate my game loop. That solved the issue of UI freezes, but still left me wondering if I was going down the wrong path.

作为一般规则,我发现大多数Web上的建议通常似乎都支持事件驱动的任何方法,因此,我当前使用 SwingWorker 的实现可能是错误的一步.方向.但是我无法完全掌握如何针对此特定任务实施完全由事件驱动的系统(这意味着不存在游戏循环).在我看来,必须存在一个循环来管理玩家的转弯.

As a general rule, I found that most advice on the web generally seems to favor any approach which is event-driven, and thus my current implementation utilizing a SwingWorker could be a step in the wrong direction. But I cannot fully grasp how I would implement a completely event-driven system for this specific task (meaning no game loop present). It seems to me that a loop has to exist somewhere for managing the player turns.

这是我的具体问题:

  1. 是否存在适用于回合制游戏(例如大富翁")的游戏循环(如我所描述的),专门用于排队玩家的回合并提示合适的玩家回合,一次一次(并排队整个过程)./包含转弯的步骤顺序)?
  2. 如果要创建一个纯粹的事件驱动系统来管理玩家的回合,那么您如何遍历每个玩家以提示他们的回合并保持迭代直到游戏结束?
  3. 如果要使用游戏循环来解决上述特定问题,是否必须在自己的线程中运行它(可能使用 SwingWorker )以避免冻结UI?我的情况是特定于Java的,但是我想我也会对非Java特定情况的答案感兴趣.
  1. Are game loops (as I am describing them) appropriate for turn-based games such as Monopoly—specifically for queuing the player turns and prompting the appropriate player for their turn, one player at a time (and queuing the entire procedure of/sequence of steps that comprise a turn)?
  2. If a purely event-driven system were to be created for managing player turns, how do you iterate through each player to prompt them for their turn and keep iterating until the game ends?
  3. If a game loop were to be used to solve the specific problem described above, does it have to be run within its own thread (possibly using SwingWorker) in order to avoid freezing the UI? My situation is Java-specific, but I suppose I would be interested in answers for non-Java-specific situations as well.

当前,我使用MVC模式组织代码.我的控制器是我的游戏循环(实际的 SwingWorker 线程)所在的位置.它远未完成,但可以帮助说明我如何管理所谓的游戏循环"中的玩家回合.

Currently, I have my code organized using the MVC pattern. My controller is where my game loop (the actual SwingWorker thread) resides. It is far from complete, but it helps illustrate how I am managing player turns in what I am calling a "game loop".

SwingWorker 代码:

SwingWorker code from controller:

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();

推荐答案

SirDarius的评论很明显.

The comment from SirDarius is spot on.

尽管如此,对于像进阶玩家这样简单的事情,您实际上并不需要费心实现完整的有限状态机.

Though, for something as simple as advancing player turns, you don't really need to bother implementing a full fledged finite state machine.

就MVC而言,这是您应该为人类玩家做的事情:

In terms of MVC, this is what you should do for human players:

  • 模型::提供一些方法,用于将活动玩家前进到下一个玩家,并执行转弯过程"(例如,掷骰子,移动活动玩家的代币等).).由于转弯过程的大部分是事件驱动的,因此这些方法调用将由控制器中的事件侦听器进行.

  • The Model: Provide methods for advancing the active player to the next player and for running through the "turn process" (i.e. rolling the dice, moving the active player's token, etc.). Because much of the turn process is event driven, these method calls will be made from event listeners in the controller.

视图::当活动玩家结束转牌时引发事件,并在其他各种输入上引发事件.

The View: Raise an event when the active player finishes their turn, as well as raising events on various other input.

控制者:每当玩家结束回合时,告诉模型前进到下一个玩家,然后再次开始回合过程".每当玩家提供输入时,都会触发一个事件,通知模型前进到回合的下一个阶段.

The Controller: Whenever a player finishes their turn, tell the model to advance to the next player, and start the "turn process" again. Whenever a player provides input, an event will be fired that tells the model to advance to the next stage of the turn.

对于 AI 玩家,可以使用大多数相同的代码,但是由视图驱动转弯进度是没有意义的.取而代之的是,该模型需要采用另一种专门针对AI玩家的转弯过程"方法.唯一的区别是代码将连续执行而无需等待视图中的输入,而不是一系列事件侦听器.

For AI players, the majority of the same code can be used, but it does not make sense to have the turn progression be driven by the view. Instead, the model would need to have another "turn process" method which would be specifically for AI players. The only difference being that the code would execute in succession without waiting for input from the view, instead of being a series of event listeners.

这篇关于回合制游戏设计:事件驱动与游戏循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆