2010-07-18 10 views
9

Estoy experimentando con lidgren en XNA y estoy teniendo algunos problemas con el 'retraso'.Lidiando con lag en XNA + lidgren

He descargado sus XNA sample y noté que incluso sus retrasos de muestra. El caso es que el movimiento no es fluido en el otro lado, y estoy intentando esto en una LAN (en la misma computadora en realidad) no a través de Internet.

¿Alguno ha tenido los mismos problemas en cuanto a movimiento no suave debido a una conexión retrasada con lidgren y XNA?

+4

Esta pregunta parece no estar relacionada con el tema y debería trasladarse a Gamedev.SE – Kromster

+1

¿GamedevSE estaba activo en 2010, cuando se publicó? –

Respuesta

30

La muestra que vinculó establece directamente la posición a lo que recibe de la red, ¡esta es una mala idea para un juego multijugador!

Lo que debe hacer en un juego real es interpolar entre la posición local y la posición remota. Por lo tanto, el método de recibir vería un poco como esto:

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

Esto no tiene ningún efecto sobre la posición local de la unidad, en lugar de su método de actualización (cada cuadro), se mueve la posición local hacia la posición remota :

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

a continuación, mostrar la posición de "local" de la unidad, con ello se consigue el movimiento lagless así:

  1. Si la posición de la unidad está casi en la posición remota, saltará a la remota pag osition (sin embargo, saltará una distancia tan pequeña que no se verá laggy).
  2. Si la diferencia es demasiado grande para saltar, entonces avance lentamente hacia la posición en la que debería estar. La constante de interpolación controla qué tan rápido convergerán las posiciones local y remota. En la interpolación constante cero, la unidad ignorará actualizaciones de la red, la constante 1 se teletransportarse directamente a la posición de la red (y buscar lag) - por lo que necesita para elegir un compromiso en algún punto intermedio

Dado que la unidad se mueve sin problemas hacia donde debería estar, ¡parece que no hay desfase en absoluto!

Hay otras cosas que debe tener en cuenta al implementar este tipo de sistema, por ejemplo, a menudo desea un límite superior de cuán lejos pueden estar las unidades de su posición remota; de lo contrario, el estado local y remoto puede "despegarse" en algunas situaciones Si están demasiado separados (lo que nunca debería suceder, excepto en casos de retraso extremo), puede detener el juego y decirle al usuario que está demasiado relajado, o saltar la unidad directamente a su posición, que se verá lenta, pero al menos el juego continuar.

Adición: Al volver a leer esta respuesta, se me ocurre que una mejora sería realizar un seguimiento de las diferencias horarias. Si sabe (más o menos) cuál es el desfase en el sistema, entonces sabrá que cuando recibe un paquete con una posición remota sabe aproximadamente qué tan lejos en el pasado está el paquete. Si envía velocidad remota también, puede predecir dónde está el objeto ahora (suponiendo velocidad constante). Esto puede hacer que la diferencia entre el estado local estimado y el verdadero estado remoto sea más pequeña en algunos juegos, en otros juegos (donde hay muchas velocidades cambiantes) puede empeorar las cosas.

+0

+1: gracias por su respuesta; ya me ha dado alguna idea –

+0

es bueno saber: D – Martin

+0

Sería bueno que aceptaras esta respuesta;) – Martin

1

He estado pensando en escribir un juego de fps multijugador, comenzando con una demostración de simplemente mover algunos cubos y replicar la posición/rotaciones en otra máquina, que está en modo espectador.

Estoy usando la muestra de código anterior y está funcionando bien (he tenido que modificar la constante de interpolación más alta que 1 para que se vea suave).

He visto algunos ejemplos de interpolación que tienen en cuenta la diferencia de tiempo entre la hora actual y la marca de tiempo en el mensaje recibido.

Veo que este código no usa la diferencia de tiempo, por lo que la interpolación llevará el tiempo que sea necesario para llegar al valor objetivo (o al menos dentro del valor del umbral para ajustarlo a su posición). Mi pregunta es, ¿hay alguna ventaja en esto?

Muchas gracias.