2010-07-18 2 views
9

Я экспериментирую с lidgren в XNA, и у меня возникают проблемы с «лаг».Работа с задержкой в ​​XNA + lidgren

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

Были ли какие-либо проблемы с негладким движением из-за задержки соединения с lidgren и XNA?

+4

Этот вопрос не соответствует теме и должен быть перенесен на Gamedev.SE – Kromster

+1

Был ли gamedevSE активным в 2010 году, когда это было опубликовано? –

ответ

30

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

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

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. Если разница слишком велика для прыжка, затем медленно двигайтесь к позиции, в которой вы должны находиться. Константа интерполяции контролирует, как быстро сближаются локальные и удаленные позиции. При постоянной интерполяции нуле, то блок будет игнорировать обновления сети, с константой 1 он будет телепортироваться прямо к позиции сети (и смотреть лаг) - так что вы должны выбрать компромисс где-то между

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

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

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

+0

+1: Спасибо за ваш ответ; это уже дало мне некоторую проницательность –

+0

Полезно знать: D – Martin

+0

Было бы хорошо, если бы вы приняли этот ответ;) – Martin

1

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

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

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

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

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

Смежные вопросы