Работа с отставанием в XNA + лидгрен - PullRequest
10 голосов
/ 18 июля 2010

Я экспериментирую с lidgren в XNA, и у меня возникают некоторые проблемы с "лагом".

Я скачал их образец XNA и заметилчто даже их образец отстает.Дело в том, что движение не является плавным с другой стороны, и я пытаюсь сделать это в локальной сети (на самом деле на том же компьютере), а не через Интернет.

У кого-то были те же проблемы, что и с гладкойдвижение из-за запаздывающей связи с лидгреном и XNA?

Ответы [ 2 ]

31 голосов
/ 18 июля 2010

Образец, который вы связали, напрямую устанавливает позицию для того, что он получает из сети, это плохая идея для многопользовательской игры!

Что вы должны сделать в реальной игре, это интерполировать между локальной позицией иудаленная позиция.Итак, ваш метод приема будет выглядеть примерно так:

void Receive(packet)
{
    unit.RemoteX = packet.Read_X_Position();
    unit.RemoteY = packet.Read_Y_Position();
}

Это не влияет на локальную позицию на устройстве, вместо этого в вашем методе обновления (каждый кадр) вы перемещаете локальную позицию в направлениидистанционное положение:

void Interpolate(deltaTime)
{
    difference = unit.RemoteX - unit.LocalX
    if (difference < threshold)
        unit.LocalX = unit.RemoteX
    else
        unit.LocalX += difference * deltaTime * interpolation_constant
}

Затем вы отображаете «локальное» положение устройства, это обеспечивает движение без задержек следующим образом:

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

Поскольку устройство плавно движется туда, где и должно быть, похоже, что никакой задержки нет вообще!

Константа интерполяции контролирует, как быстро локальные и удаленные позициибудет сходиться: - 0: игнорировать обновления сети - малый: очень быстро защелкнуться на месте (возможно, он выглядит запаздывающим) - большой: медленно сдвинуться на место, выглядит гладким, но может не отвечать на запросыnsive

Вам нужно выбрать компромисс где-то между этими опциями.

Есть некоторые другие вещи, которые следует учитывать при реализации такого рода системы, например, вам часто требуется верхний предел того, как далекоОтдельно стоящие устройства могут находиться в удаленном положении, в противном случае местное и удаленное состояние в некоторых ситуациях может «отклеиться».Если они находятся слишком далеко друг от друга (что никогда не должно происходить, за исключением случаев крайней задержки), вы можете либо остановить игру и сказать пользователю, что она слишком запаздывает, либо перепрыгнуть юнит прямо в положение, которое будет выглядеть запаздывающим, но по крайней мере игра будетпродолжить.

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

1 голос
/ 11 февраля 2011

Я пытался написать многопользовательскую fps-игру, начиная с демонстрации простого перемещения нескольких кубиков и повторения положения / вращения на другой машине, которая находится в режиме зрителя.

I 'используя приведенный выше пример кода, и он работает хорошо (мне пришлось настроить константу интерполяции выше 1, чтобы она выглядела плавно).

Я видел несколько примеров интерполяции, учитывающих времяразница между текущим временем и отметкой времени в полученном сообщении.

Я вижу, что этот код не использует разницу во времени, поэтому интерполяция займет столько времени, сколько необходимо, чтобы добраться до целевого значения (илипо крайней мере, в пределах порогового значения, чтобы затем зафиксировать положение).У меня вопрос, есть ли в этом какое-то преимущество?

Большое спасибо.

...