Лучший способ реализовать воспроизведение игры? - PullRequest
11 голосов
/ 29 апреля 2009

Я создаю игру на основе сетки на Java и хочу реализовать запись и воспроизведение игр. Я не уверен, как это сделать, хотя я рассмотрел 2 идеи:

  1. Несколько раз в секунду я записывал бы полное состояние игры. Чтобы воспроизвести его, я пишу средство визуализации, чтобы прочитать состояния и пытаюсь создать визуальное представление. При этом, однако, у меня, вероятно, будет большой файл сохранения, и любые попытки воспроизведения будут, вероятно, иметь заметную задержку.

  2. Я также мог записывать каждое нажатие клавиши и щелчок мышью в файл сохранения. Это дало бы мне файл меньшего размера и могло бы воспроизводить с меньшей задержкой. Однако малейшая ошибка в начале игры (например, стрельба спустя 1 миллисекунду) может привести к совершенно другому игровому состоянию через несколько минут.

Каков наилучший способ воспроизведения игры?

Редактировать. Я не уверен, насколько детерминистична моя игра, поэтому я не уверен, что всю игру можно объединить, записав только нажатия клавиш и щелчки мыши.

Ответы [ 8 ]

14 голосов
/ 29 апреля 2009

Хороший механизм воспроизведения - это не то, что можно просто добавить в игру без особых трудностей. Лучше всего сделать дизайн игровой инфраструктуры с учетом этого. Командный шаблон может использоваться для создания такой игровой инфраструктуры.

Например:

public interface Command{
    void execute();
}
public class MoveRightCommand implements Command {
   private Grid theGrid;
   private Player thePlayer;

   public MoveRightCommand(Player player, Grid grid){
        this.theGrid = grid;
        this.thePlayer = player;
       }

   public void execute(){
     player.modifyPosition(0, 1, 0, 0);
   } 
}

И затем команда может быть помещена в очередь выполнения и , когда пользователь нажимает кнопку клавиатуры, перемещает мышь или без триггера с механизмом воспроизведения. Командный объект может иметь значение метки времени (относительно начала воспроизведения) для точного воспроизведения ...

8 голосов
/ 29 апреля 2009

Шон Харгривз недавно опубликовал в своем блоге сообщение о том, как они реализовали воспроизведение в MotoGP. Рассматривается несколько разных подходов, их плюсы и минусы.

http://blogs.msdn.com/shawnhar/archive/2009/03/20/motogp-replays.aspx

3 голосов
/ 29 апреля 2009

Предполагая, что ваша игра является детерминированной, может быть достаточно, если вы записали входные данные пользователей (вариант 2). Однако вам необходимо убедиться, что вы распознаете правильное и непротиворечивое время для этих событий, например, когда оно было распознано сервером. Я не уверен, как вы обрабатываете события в сетке.

Меня беспокоит то, что если у вас нет механизма, который мог бы равномерно ссылаться на синхронизированные события, возможно, проблема в том, как ваш код обрабатывает распределенных пользователей.

Рассмотрим игру наподобие Halo 3 на XBOX 360, например - каждый клиент записывает свой взгляд на игру, включая исправления на основе сервера.

2 голосов
/ 29 апреля 2009

Я бы просто сказал, что лучший способ записи повторов игры полностью зависит от характера игры. Быть основанным на сетке не проблема; вопрос заключается в том, как предсказуемое поведение следует за изменением состояния, как часто в систему поступают новые входные данные, вводятся ли случайные данные в какой-либо момент и т. д. но это не сработает для шутера от первого лица, где нет четких поворотов. Вы можете сохранить шутер от первого лица, отметив точное время каждого входа, но это не сработает для RPG, где результат ввода может быть изменен в результате случайного броска костей. Даже кажущаяся безошибочной идея сделать снимок как можно чаще недостаточно, если важная информация появляется мгновенно и не сохраняется ни в одной захватывающей форме.

Интересно, что это очень похоже на проблему, которую вы получаете с сетью. Как один компьютер гарантирует, что другой компьютер узнает о состоянии игры, не отправляя все это состояние игры с непрактично высокой частотой? Типичный подход в конечном итоге представляет собой смесь уведомлений о событиях и обновлений состояния, что, вероятно, вам и понадобится.

2 голосов
/ 29 апреля 2009

То, как вы подходите к этому, будет во многом зависеть от языка, который вы используете для своей игры, но в общих чертах существует множество подходов, в зависимости от того, хотите ли вы использовать много памяти или хотите немного задержаться. Было бы полезно, если бы вы могли подумать о том, на какие жертвы вы готовы пойти.

Но, казалось бы, наилучший подход может состоять в том, чтобы просто сохранить ввод от пользователя, как было упомянуто, и либо сохранить позиции всех актеров / спрайтов в игре одновременно, что так же просто, как просто сохраняя направление, скорость и плитку x, y или, если все может быть детерминированным, игнорируйте актеров / спрайтов, поскольку вы можете получить их информацию.

Насколько недетерминистична ваша игра, также было бы полезно дать лучшее предложение.

Если имеется большое динамическое движение, такое как аварийное дерби, вы можете сохранять информацию каждый кадр, так как вы должны обновлять игроков / актеров с определенной частотой кадров.

2 голосов
/ 29 апреля 2009

Нет необходимости сохранять все в сцене для каждого кадра. Сохраняйте изменения постепенно и используйте некоторые хорошие методы интерполяции. Я бы на самом деле не использовал подход, основанный на шаблонах команд, а скорее делал бы проверки с фиксированной скоростью для каждого игрового объекта и смотрел бы, изменился ли какой-либо атрибут. Если есть изменение, то это изменение записывается в некоторой хорошей кодировке, и воспроизведение даже не станет таким большим.

2 голосов
/ 29 апреля 2009

Почему бы не записать несколько раз в секунду, а затем сжать ваш вывод, или, возможно, сделать это:

recordInitialState();
...
runs 30 times a second:
recordChangeInState(previousState, currentState);
...

Если вы записываете изменение состояния только с отметкой времени (и каждое изменение невелико, а если изменений нет, то ничего не записываете), в итоге вы должны получить файл разумного размера.

1 голос
/ 12 июня 2009

Я сделал это однажды, позаимствовав идею сжатия видео: ключевые кадры и промежуточные кадры. По сути, каждые несколько секунд вы сохраняете полное состояние мира. Затем, один раз за обновление игры, вы сохраняете все изменения состояния мира, которые произошли с момента последнего обновления игры. Детали (как часто вы сохраняете ключевые кадры? Что именно считается «изменением состояния мира»?) Будут зависеть от того, какую игровую информацию вам нужно сохранить.

В нашем случае мир состоял из многих, многих игровых объектов, большинство из которых были неподвижны в любой момент времени, поэтому этот подход позволил нам сэкономить много времени и памяти при записи положений объектов, которые не двигались , У вас компромиссы могут быть другими.

...