2011-01-07 12 views
7

La situación:Mutli jugador del juego de la sincronización

me gustaría preguntar cuál es la mejor lógica para la sincronización de objetos en un multijugador 1: 1 juego usando BT o un servidor web. El juego tiene dos jugadores, cada uno de ellos tiene múltiples balas & balas, las balas se crean dinámicamente y desaparecen después de un tiempo, los jugadores mi movimiento objetos alrededor simultáneamente.

El problema:

tengo un verdadero problema con la sincronización, ya que las balas en un solo dispositivo puede ser más rápido que otros, también pueden haber ido ya o golpear un objeto en un solo dispositivo, mientras que en el otro su todavía en el aire.

¿Posibilidades?

¿Cuál es la mejor forma de manejar la sincronización en este caso? Deberían todos los objetos ser controlados por un dispositivo que actúa como el servidor, mientras que el otro simplemente obtiene los valores, las posiciones y hace muy poco pensar. O debería distribuirse el control donde cada dispositivo crea, destruye y mueve sus propios objetos y luego a través de la sincronización le dice al otro dispositivo.

¿Cuál es la mejor manera de manejar la demora de transmisión en esto, ya que BT podría ser más rápido que jugar en la web? Lo mejor sería una muestra de trabajo, ¡muchas gracias!

Respuesta

10

Pareces haber comenzado con algunas buenas ideas sobre la sincronización, pero es posible que haya dos problemas que te encuentres superpuestos: la sincronización de los relojes de juego y la sincronización de gamestate.

(1) la sincronización de los relojes de juego necesita alguna representación del 'tiempo de juego' para su juego. para un juego de 2 jugadores es muy razonable simplemente declarar una autoridad.

así en el cliente de autoridad:

OnUpdate() 
    gameTime = GetClockTime(); 
    msg.gameTime = gameTime 
    SendGameTimeMessage(msg); 

por otro cliente podría ser algo como:

OnReceivGameTimeeMessage(msg) 
lastGameTimeFromNetwork = msg.gameTime; 
lastClockTimeOfGameTimeMessage = GetClockTime(); 

OnUpdate() 
gameTime = lastGameTimeFromNetwork + GetClockTime() - lastClockTimeOfGameTimeMessage; 

hay complicaciones como saltar/deslizamiento (es decir, conseguir tiempos desde la red que van hacia adelante/hacia atrás demasiado) que requieren más trabajo, pero espero que entiendas la idea. Haga un seguimiento con otra pregunta si lo necesita.

Nota: este ejemplo no diferencia 'ticks' contra 'segundos' ni está vinculado a su protocolo de red ni al tipo de dispositivo en el que se ejecuta su juego (guarde el requisito 'el dispositivo tiene un reloj local')

(2) sincronizando el juego de estado después de tener un reloj de juego constante, todavía necesita averiguar cómo simular y propagar consistentemente su estado de juego. para sincronizar gamestate usted tiene un par de opciones:

asíncronos

  • cada unidad de gamestate es 'propiedad' de un proceso. solo ese proceso está permitido para cambiar ese estado del juego. esos cambios se propagan a todos los demás procesos.
  • si todo es propiedad de un solo proceso, esto a menudo se denomina juego 'cliente/servidor'.
  • Nota: con este modelo, cada cliente tiene una visión diferente del mundo del juego en cualquier momento.
  • ejemplo, juegos: Quake, World of Warcraft

para optimizar el ancho de banda y latencia piel, a menudo se puede hacer algo de simulación local para campos con una alta frecuencia de actualización. ejemplo:

drawPosition = lastSyncPostion + (currentTime - lastSyncTime) * lastSyncVelocity 

por supuesto que tiene que reconciliar nueva información con su versión simulada en este caso.

síncrono

  • cada unidad de gamestate es idéntico en todos los procesos.
  • Los comandos de cada proceso se propagan entre sí con su tiempo de inicio deseado (en algún momento en el futuro).
  • en su forma más simple, un proceso (a menudo llamado el host) envía mensajes especiales que indican cuándo adelantar el tiempo del juego. cuando todos reciben ese mensaje, pueden simular el juego hasta ese momento.
  • el requisito "en el futuro" conduce a una alta latencia entre el comando de entrada y el cambio del estado del juego.
  • en juegos en tiempo no real como la civilización, esto está bien. en un juego como Starcraft, normalmente el sonido que reconoce la entrada viene inmediatamente, pero la acción que afecta el estado del juego realmente se retrasa. este estilo no es apropiado para juegos como shooters que requieren acciones sensibles al tiempo (en la escala de ~ 100 ms).

síncrono con resimulation

  • cada unidad de gamestate es idéntico en todos los procesos.
  • cada proceso envía a todos los otros procesos su entrada con su marca de tiempo actual. además, periódicamente se envía un mensaje de 'nada sucedió'.
  • cada proceso tiene 2 copias del sistema de juego.
  • copia 1 del estado del juego se propaga al 'último mensaje más antiguo' que ha recibido de todos los demás clientes. esto es equivalente al modelo síncrono, pero tiene la debilidad de que representa un estado de juego de 'hace un momento'
  • copia 2 del estado del juego es copia 1 más todos los mensajes restantes.es una predicción de lo que es el estado del juego en el momento actual en el cliente, suponiendo que nada nuevo sucede.
  • el jugador interactúa con alguna combinación de los dos gamestate (idealmente 100% copia 2, pero algunos se debe tener cuidado para evitar estallidos como los nuevos mensajes lleguen)
  • Juegos Ejemplo: Street Fighter 4 (reproducción a Internet)

Según su descripción, las opciones (1) y (3) parecen corresponder a su problema. nuevamente si tiene más preguntas o requiere más detalles, solicite un seguimiento.

+0

¡Muchas gracias por la explicación! – user387184

+0

La explicación del reloj del juego me parece clara. Si entiendo correctamente, básicamente le envía tiempo a los servidores para que el cliente adapte su tiempo de juego en consecuencia. Si esto sucede a través de BT o la red local, se puede ignorar el tiempo que requieren los mensajes de sincronización del servidor. Por ejemplo, si el servidor está en el momento 123 -> lo envía al cliente -> el cliente también puede establecer su propio tiempo en 123 (el retraso entre recibir el tiempo del servidor y actualizar el propio tiempo puede ignorarse si todo sucede en el mismo método) ¿Es esto correcto? – user387184

+0

Mi pregunta restante es, ¿funcionará esto a través del GameCenter de Apple? Desde la introducción de Apple GameCenter entiendo que tienen una versión de GKtank worling sobre GameCenter. Pero, ¿cómo se sincronizan si los mensajes entre los dos jugadores toman más tiempo? ¿Pausa el juego? Gracias de nuevo – user387184

1

ya que las balas en un solo dispositivo puede ser más rápido que otros

Esto no debería ocurrir si el juego ha sido architected correctamente.

La mayoría de los juegos en estos días (en particular los de varios jugadores) funcionan en ticks - pequeños timeslices. Cada sistema debe obtener el exactamente el mismo resultado cuando calcula lo que sucedió durante un tic: no "balas que se mueven más rápido en una máquina que en otra".

Luego es mucho más sencillo asegurarse de que cada sistema tenga las mismas entradas para cada jugador (deberá transmitir la entrada de cada jugador a cada otro jugador, junto con el tick donde se registró la entrada), y Asegúrese de que cada sistema calcule los tics a la misma velocidad.

+0

... por desgracia, el uso de las garrapatas no le quita el requisito para sincronizar. Incluso los dos ejemplos, GKTank y punchball sincronizan sus 2 objetos: sin la llamada de sincronización, están fácilmente fuera de sincronización. Pero escalar el enfoque utilizado no funciona en mi caso ya que tengo demasiados objetos ... – user387184

Cuestiones relacionadas