Я экспериментирую с lidgren в XNA, и у меня есть некоторые проблемы с 'задержкой'.
Я загрузил их образец XNA и заметил, что даже их образец отстает. Вещь, перемещение не является гладким с другой стороны, и я пробую это на LAN (на том же компьютере на самом деле) не по Интернету.
У кого-либо были те же проблемы в отношении негладкого перемещения из-за отстающего соединения с lidgren и XNA?
Пример, на который вы сослались, напрямую устанавливает позицию на то, что он получает из сети, это плохая идея для многопользовательской игры!
Что вы должны делать в реальной игре, так это интерполировать между локальной и удаленной позицией. Таким образом, ваш метод получения будет выглядеть примерно так:
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
}
Затем вы отображаете "локальную" позицию устройства, таким образом достигается движение без задержки следующим образом:
Поскольку устройство плавно движется к тому месту, где оно должно быть, кажется, что задержки нет вообще!
Константа интерполяции управляет скоростью сближения локальной и удаленной позиций: - 0: Игнорировать обновления сети - Малый: очень быстро сходится (возможно, выглядит лагированным) - Большой: Медленно скользит на место, выглядит гладко, но может казаться невосприимчивым
Вам нужно выбрать компромисс где-то между этими вариантами.
Есть и другие моменты, которые необходимо учитывать при реализации подобной системы, например, часто требуется верхний предел того, насколько далеко друг от друга могут находиться юниты от их удаленной позиции, иначе в некоторых ситуациях локальное и удаленное состояния могут "расшататься". Если они находятся слишком далеко друг от друга (чего никогда не должно происходить, кроме случаев крайнего отставания), вы можете либо остановить игру и сказать пользователю, что она слишком затянута, либо переместить юнит прямо на позицию, что будет выглядеть затянутым, но, по крайней мере, игра продолжится.
Дополнение: Перечитывая этот ответ, мне пришло в голову, что улучшением могло бы стать отслеживание разницы во времени. Если вы знаете (приблизительно), какова задержка в системе, тогда вы знаете, что когда вы получаете пакет с удаленной позицией, вы знаете, как далеко в прошлом находится этот пакет. Если вы также посылаете удаленную скорость, вы можете предсказать, где объект находится сейчас (предполагая постоянную скорость). Это может уменьшить разницу между оценкой локального состояния и истинным удаленным состоянием в некоторых играх, в других играх (где у вас много меняющихся скоростей) это может ухудшить ситуацию.