Как делают протоколы оперативных стратегических игр, такие как взгляд Age of Empires и Starcraft? [закрытый]

tl; доктор: Выполнимые реализации лучше. Однако протест важен

В целом, я рекомендовал бы использовать что-то как Runnable, а не Thread, потому что он позволяет, Вы для хранения работы только слабо связали с выбором параллелизма. Например, если Вы используете Runnable и решаете позже, что это на самом деле не требует свой собственный Thread, можно просто назвать threadA.run ().

Протест: Здесь, я сильно препятствую использованию необработанных Потоков. Я очень предпочитаю использование [1 110] Callables и FutureTasks (От javadoc: "Отменимое асинхронное вычисление"). Интеграция тайм-аутов, надлежащей отмены и объединения потока современной поддержки параллелизма все намного более полезна для меня, чем груды необработанных Потоков.

Продолжение: существует FutureTask конструктор , который позволяет Вам использовать Runnables (если это - то, что Вы являетесь самыми довольными), и все еще извлеките пользу из современных инструментов параллелизма. Для заключения в кавычки javadoc:

, Если Вам не нужен конкретный результат, рассмотрите использование конструкций формы:

Future f = new FutureTask(runnable, null)

Так, если мы заменяем их runnable Вашим threadA, мы получаем следующее:

new FutureTask(threadA, null)

Другая опция, которая позволяет Вам оставаться ближе к Runnables, ThreadPoolExecutor. Можно использовать эти , выполняются метод для передачи в Выполнимом для выполнения "данной задачи когда-то в будущем".

, Если бы требуется попытаться использовать пул потоков, фрагмент кода выше стал бы чем-то как следующее (использующий Executors.newCachedThreadPool () метод фабрики):

ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());

43
задан JOrik 25 August 2009 в 21:19
поделиться

3 ответа

Я могу подробно рассказать об этом, но сначала прочтите "1500 лучников" http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_. php , и это ответит на многие ваши вопросы. Вот краткое изложение: Во-первых, большинство игр используют UDP из-за характера игры в реальном времени. Цикл игры выглядит примерно так:

  1. чтение сетевых данных
  2. выполнение прогнозов на стороне клиента и сравнение с тем, что сообщает сеть ваши объекты должны на самом деле
  3. запутаться в физике, чтобы обмануть то, что сообщает сеть, с тем, что ваши локальное состояние игры
  4. отправляет данные обратно в сеть в зависимости от того, что вы сделали это frame (если есть)
  5. render

Это значительно упрощено, и «возня с физикой» может легко составить книгу на 200 страниц, но она включает в себя предсказание на стороне клиента, где что-то может быть, получение данных с сервера это старое, но точно указывает, где объект был / должен быть, а затем как-то интерполирует эти значения, чтобы объект выглядел «достаточно близко» к тому месту, где он на самом деле должен быть, что никто не замечает. Это очень важно в шутерах от первого лица, но не в такой степени для стратегии в реальном времени.

В стратегии в реальном времени обычно происходит пошаговая система, в которой время делится на дискретные части, называемые «ходами». это происходит последовательно, и каждый ход имеет номер, сгенерированный монотонной функцией, которая гарантирует постоянно увеличивающиеся значения в определенном порядке без дублирования. На любом заданном ходу n каждый клиент отправляет сообщение всем другим клиентам с их предполагаемым действием на ходу n + m, где m - произвольное число, которое обычно довольно мало и может быть лучше всего определено методом проб и ошибок, а также игровым тестированием. Как только все клиенты отправили намеченное действие, каждый клиент выполняет все действия, которые были отправлены на ходу n + m. Это приводит к небольшой задержке, когда действие заказывается пользователем и когда оно выполняется, однако обычно это незаметно.

Есть несколько приемов, которые также можно использовать, чтобы обмануть время. Например, если вы выделите отряд, а затем прикажете ему двигаться, он издает звук и воспроизводит анимацию, когда начинает движение, но на самом деле не сразу двигается. Однако сетевое сообщение о намерении переместить эту единицу отправляется немедленно, поэтому к тому времени, когда экран отвечает на ввод игрока, сетевые сообщения уже были отправлены и подтверждены. Вы можете изменить его дальше, введя небольшую задержку (около 100 мс) между щелчком мыши и ответом игрового объекта. Обычно это незаметно для игрока, но 100 мс - это вечность в игре по локальной сети, и даже при широкополосном соединении на домашнем компьютере средний пинг, вероятно, составляет около 15-60 мс или около того, что дает вам достаточно времени для отправки пакета до Движение.

Что касается данных для отправки, в играх есть два типа данных: детерминированные и недетерминированные. Детерминированные действия основаны на игровой физике, поэтому, когда действие начинается, есть 100% гарантия, что я могу предсказать результат этого действия. Эти данные никогда не нужно отправлять по сети, поскольку я могу определить, что они будут на клиенте, исходя из начального состояния. Обратите внимание, что использование генератора случайных чисел с одним и тем же начальным значением на каждом клиенте превращает «случайные» события в детерминированное поведение. Недетерминированные данные обычно вводятся пользователем, но во многих случаях можно предсказать, какими будут вводимые пользователем данные. Суть этой пары в стратегической игре в реальном времени состоит в том, что недетерминированное событие является своего рода порядком для одного из моих игровых объектов. После того, как игровому объекту было приказано двигаться, способ его движения становится на 100% детерминированным. Поэтому все, что вам нужно отправить в сеть, это идентификатор объекта, заданная команда (сделайте это перечислением для экономии полосы пропускания) и цель команды (если есть, так что заклинание может не иметь цели, если это область действия, но команда перемещения имеет конечный пункт назначения). Если пользователь щелкает примерно 100 раз, чтобы переместить отряд, нет необходимости отправлять отдельную команду перемещения для каждого щелчка, поскольку все они находятся в одной и той же общей области, поэтому обязательно отфильтруйте и это, так как это убьет ваш пропускная способность.

Последний прием для обработки возможной задержки между командой и ее выполнением - это так называемый локальный фильтр восприятия. Если я получаю приказ о перемещении через некоторое время t после того, как был отдан приказ, я знаю, когда отряд должен был начать движение, и я знаю его конечный пункт назначения. Вместо того, чтобы телепортировать отряд, чтобы доставить его туда, где он должен быть, Я могу начать его движение поздно, а затем возиться с физикой, чтобы немного ускорить его, чтобы он мог догнать то место, где он должен быть, а затем замедлить его, чтобы поставить в нужное место. Точное значение, необходимое для его ускорения, также является относительным, и тестирование игры - единственный способ определить правильное значение, потому что оно просто должно «чувствовать себя правильно», чтобы оно было правильным. Вы можете сделать то же самое с стрельбой пулями и ракетами, и это очень эффективно для этого. Причина, по которой это работает, заключается в том, что люди не очень хорошо видят тонкие изменения в движении, особенно если объект движется прямо к ним или от них, поэтому они просто не замечают.

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

90
ответ дан 26 November 2019 в 22:44
поделиться

Check out Battle for Wesnoth.

http://www.wesnoth.org/

It's free, open source, and totally awesome. You can learn a lot from digging into its source.

3
ответ дан 26 November 2019 в 22:44
поделиться

Обсуждение Сетевая архитектура Age of Empires здесь

ИМХО, этот стиль одноранговой архитектуры, основанной на дублировании и воспроизведении, впечатляет, но является своего рода тупиком для игроков с более чем 8 или около того.

3
ответ дан 26 November 2019 в 22:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: