2011-01-17 6 views
5

Estoy escribiendo un simple juego de pong en línea para dos jugadores que juegan en la red. Es una aplicación cliente-servidor, con una lógica de juego en el lado del servidor. Tengo algunos problemas con la sincronización del juego en el lado del cliente, y el resultado es bastante insatisfactorio. Esta es la forma en que funciona actualmente:Sincronización simple en línea de la red de juegos de pong

  1. En el lado del servidor Tengo un objeto de juego que almacena la posición de los jugadores y la pelota, cada objeto tiene su posición x, x y y, y la velocidad. En función de esa posición de los objetos, se actualiza en el ciclo. En el lado del cliente hay el mismo objeto local con los mismos datos, y también se actualiza en el ciclo.
  2. Cuando el jugador presiona/libera hacia arriba o hacia abajo, el cliente envía un paquete de red con un entero, de forma que el objeto jugador se inicia/detiene para moverse en el objeto del juego en el servidor.
  3. El servidor envía un paquete de sincronización cada 50 milisegundos con la posición y la velocidad de los tres objetos. Cuando el cliente recibe este paquete, cambia las posiciones de los objetos del juego en consecuencia.

Este método no funciona muy bien ya que mueve los objetos del juego hacia adelante y hacia atrás en el lado del cliente. ¿Alguna idea de cómo mejorarla?

+0

¿Qué quiere decir con "resultados insatisfactorios" y "mover los objetos hacia adelante y hacia atrás"? – BlueCookie

+0

Este artículo apareció después de esta pregunta: http://drewblaisdell.com/writing/game-networking-techniques-explained-with-pong/ – opyate

Respuesta

17

Admita que tiene una latencia de 30 ms entre el cliente y el servidor. El cliente envía "Quiero mover la raqueta hacia abajo" y su raqueta es en y = 100px con una velocidad de 0.1px/ms

30ms segundos más tarde:

  • raqueta cliente es en y = 100 + 30 * 0,1 = 103px servidor
  • recibe el encargo del cliente y empezar a mover la raqueta (que se encuentra todavía en y = 100px en el lado del servidor)

20ms segundos más tarde:

  • raqueta cliente está en y = 103 + 20 * 0,1 = 105px
  • del lado del servidor raqueta cliente está en y = 100 + 20 * 0,1 = 102px
  • servidor envía al cliente la nueva posición (102px)

30 ms segundos más tarde:

  • rarcket cliente está en y = 105 + 30 * 0,1 = 108px
  • cliente recibe desde el servidor de la nueva positon de la raqueta : 102px

En este punto, la raqueta cliente "saltos" hacia atrás desde 108 a 102px ...

cómo hacer frente a la latencia de la red? Dos complementarias maneras:

  • esperan Acuse de recibo del servidor antes de hacer una acción
  • predicen resultados de las acciones (en los lados de cliente y servidor)

El primer abordaje se utiliza cuando el efecto sobre el cliente apenas está vinculado con el resultado y no puede ser "revertido". Ejemplo: cuando un cliente dispara un misil, no es posible que el servidor suprima este misil en la próxima actualización porque el cliente ya no tenía más stock de misiles. Entonces, en este caso, la aplicación cliente lanzará el misil solo después de que el servidor haya enviado un acuse de recibo.

El segundo siempre se usa para evitar estos "saltos" cuando se sincroniza el servidor. Tienes que controlar la latencia de la red para predecir el movimiento de los elementos de tu juego. Aquí hay dos maneras: calcular el ping o sincronizar el servidor y la hora del cliente al inicio (la forma más fácil y más sólida). La idea general es:

  • cliente envía "Quiero mover la raqueta hacia abajo en el tiempo = 1265871" y empezar a mover

30 ms tarde: Raqueta

  • cliente en y = 100 + 30 * 0.1 = 103px
  • El servidor recibe el movimiento y calcula la latencia de 30 ms (por ping o diferencia de sincronización de tiempo) y establece la posición de la raqueta en y = 100 + latencia * 0.1 = 100 + 30 * 0.1 = 103px

¡Perfecto! Ellos están sincronizados.

20 ms después:

  • servidor y el cliente de raqueta tanto en y = 103 + 20 * 0,1 = 105px
  • servidor envía nueva posición y dirección

30 ms después:

  • raqueta cliente a y = 105 + 30 * 0.1 = 108px
  • cliente r eceives nueva posición y la dirección (105px movimiento hacia abajo), calcula la latencia 30 ms y ajustar la posición de la raqueta en y = 105 + latencia * 0,1 = 105 * 30 * 0,1 = 108px

Una vez más, están sincronizados cliente y el servidor!

La desincronización puede ocurrir en el otro cliente cuando el primer cliente deja de moverse. En este caso, la raqueta del jugador "saltará" un poco. Cuando esto no es crítico, es posible suavizar esta transición.

Espero que ayude.

Cuestiones relacionadas