Контакт с задержкой в XNA + lidgren

Я экспериментирую с lidgren в XNA, и у меня есть некоторые проблемы с 'задержкой'.

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

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

10
задан Jonas 6 February 2012 в 04:16
поделиться

1 ответ

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

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

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: Игнорировать обновления сети - Малый: очень быстро сходится (возможно, выглядит лагированным) - Большой: Медленно скользит на место, выглядит гладко, но может казаться невосприимчивым

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

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

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

31
ответ дан 3 December 2019 в 14:43
поделиться
Другие вопросы по тегам:

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