Я создаю свою первую игру на Java. Игра Монополия. Я борюсь с тем, как мне спроектировать игру, чтобы смоделировать ее пошаговую структуру (управление ходами игроков). Я хочу, чтобы в игру могли играть как один игрок, управляемый человеком, так и один или несколько игроков, управляемых ИИ.
Моя конкретная проблема заключается в том, что я не знаю, следует ли реализовать игровой цикл или нет, то есть цикл, который может управлять игроками и переменными, непосредственно связанными с игрой в «Монополию» (подумайте о таких вещах, как подсказка каждому игроку о своем ходу, увеличение хода для следующего игрока или получение бросков кубиков от каждого игрока по очереди). Я не имею в виду более низкоуровневое значение термина «игровой цикл», которое больше относится к рисованию кадров на экране, обновлению физики или обновлению ИИ с определенной скоростью.
Насколько я понимаю, мои варианты попытки реализовать то, что мне нужно, заключаются в следующем:
- Реализовать полностью управляемую событиями программу, в которой нет такого игрового цикла, или
- Реализуйте игровой цикл — что-то, что долго работает в фоновом режиме и, по сути, никогда не заканчивается, пока игра запущена. Это будет более процедурный подход.
Когда я впервые начал пытаться решить эту проблему, я столкнулся с проблемой зависания моего пользовательского интерфейса, потому что мой игровой цикл был бесконечным и полностью потреблял поток, в котором он выполнялся (я только что сделал очень простой цикл while, чтобы проиллюстрировать это). . Поэтому я приложил усилия к созданию SwingWorker
для инкапсуляции моего игрового цикла. Это решило проблему зависаний пользовательского интерфейса, но все же заставило меня задуматься, не иду ли я по неверному пути.
Как правило, я обнаружил, что большинство советов в Интернете обычно поддерживают любой подход, основанный на событиях, и поэтому моя текущая реализация с использованием SwingWorker
может быть шагом в неправильном направлении. Но я не могу полностью понять, как реализовать полностью управляемую событиями систему для этой конкретной задачи (имеется в виду отсутствие игрового цикла). Мне кажется, что где-то должна существовать петля для управления ходами игрока.
Вот мои конкретные вопросы:
- Подходят ли игровые циклы (как я их описываю) для пошаговых игр, таких как «Монополия», особенно для постановки в очередь ходов игрока и приглашения соответствующего игрока на его ход, по одному игроку за раз (и постановки в очередь всей процедуры/последовательности ходов? шаги, составляющие поворот)?
- Если бы для управления ходами игроков была создана система, основанная исключительно на событиях, как бы вы перебирали каждого игрока, чтобы подсказать им свой ход, и продолжали бы повторяться до конца игры?
- Если для решения конкретной проблемы, описанной выше, нужно использовать игровой цикл, должен ли он запускаться в отдельном потоке (возможно, с использованием
SwingWorker
), чтобы избежать зависания пользовательского интерфейса? Моя ситуация связана с 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();