2011-05-09 12 views
10

Hola, he escrito un juego multijugador en Java y me preguntaba qué necesito aprender y/o qué debo usar para hacer juego que se puede jugar a través de una red o en Internet por varias computadoras. Realmente no tengo ni idea de por dónde empezar, así que cualquier consejo sería útil, gracias.Hacer un juego multijugador jugable a través de una red o en Internet

+0

¿Cómo es el juego compatible con la funcionalidad multijugador en su estado actual? ¿Está usando sockets para comunicarse con múltiples instancias en la misma máquina? –

+0

No, solo se basa en tomar turnos, pero supongo que es algo que tendria que hacer antes de que pueda ponerlo en una red. –

+0

Multijugador significa que varios usuarios están jugando el mismo juego y que hay cierta interacción entre los jugadores en el juego. Dijiste que tu juego está "basado en tomar turnos". ¿Es multijugador en absoluto? –

Respuesta

1

Si desea agregar la función multijugador a través de la red, puede ser útil para que eche un vistazo a la Netty project para construir la infraestructura de comunicación.

Pero antes de que puedas hacer eso, debes asegurarte de que tu juego tenga la "arquitectura" correcta. Necesita tener grandes módulos: el Cliente y el Servidor.

El servidor es responsable de toda la lógica del juego. En cierto sentido, es el motor del juego. El Cliente es responsable de consultar el estado del juego en el Servidor, mostrarlo al jugador, obtener la entrada del jugador y enviar comandos al servidor.

Una forma de desacoplar nuestro código de Cliente y Servidor sin la molestia de aprender programación de red es tener dos programas diferentes que se ejecutan desde la CLI. La secuencia de ejecución puede ser así:

  1. El servidor se ejecuta para inicializar el estado del juego, el estado del juego se guarda en un archivo.
  2. El cliente se ejecuta, lee el estado del juego, lo muestra de alguna manera y recibe cierta información del jugador. Guarda esa entrada en un archivo.
  3. El servidor se ejecuta, lee los comandos del cliente, cambia el estado del juego y actualiza el archivo de estado.

Enjuague y repita. Esto es básicamente lo que hacen los servidores PBEM.

Para ayudar a desacoplar el Cliente y el Servidor, tiene sentido definir un "idioma" para representar los cambios en el estado del juego y los comandos que debe ejecutar el servidor. Ayuda si el cliente almacena en caché el estado y aplica los cambios tal como se envía desde el servidor.

Una vez que su código de Cliente y Servidor está completamente desacoplado, y el "idioma" está completamente definido, está listo para cambiar el mecanismo de comunicación de basado en archivos a basado en sockets.

1

Un posible enfoque arquitectónico sería tener una instancia del juego que actúe como anfitrión (por ejemplo, la primera en iniciarse). Coordinaría el juego y enviaría información del estado del juego y se dirigiría a cada uno de los otros jugadores.

Cuando un jugador hace un movimiento, envía la información del movimiento al host, lo que actualiza el estado del juego (y verifica la validez del movimiento, etc.). Luego enviará el nuevo estado del juego a cada uno de los jugadores y también enviará (probablemente como una comunicación por separado) la notificación del próximo turno al cliente apropiado y esperará su respuesta.

En cierto sentido, el host actúa como el servidor del juego en este escenario, pero puede ser más fácil de usar/jugar en que no hay un proceso separado que deba ejecutarse para poder jugar.

40

Esas otras respuestas son bastante de alto nivel, lo cual está bien, pero no desea un alto nivel, quiere un nivel bajo, como en "¿cómo puedo hacer que realmente envíe datos y qué significa eso? y qué envío, etc. " Esto es lo que debe hacer:

Primero, ¿TCP o UDP?Si usted no sabe lo que cualquiera de esas cosas son, leer sobre ellos, ya que no tengo espacio para dar un buen resumen de los dos aquí, pero para su elección saber lo siguiente:

  1. TCP es buena para juegos basados ​​en turnos o juegos en los que la alta latencia generalmente está bien, ya que TCP garantiza la entrega de paquetes, por lo que es posible que el paquete descartado tarde un poco en volver a entregarse. Esto es bueno para cosas como el ajedrez, o cualquier otra cosa que tome turnos.
  2. UDP es bueno para juegos en los que no necesariamente se preocupan por la confiabilidad en los mensajes y preferiría que los datos sigan enviándose y, si se pierde algo, bueno. Esto es bueno para juegos que son juegos basados ​​en acción en tiempo real, como HALO: Reach o Call of Duty. En esos casos, si envía la posición de un objeto y el objeto nunca llega allí, es mejor enviar una nueva posición que volver a enviar una posición anterior (que ahora es incluso más antigua), por lo que no es importante garantizar la fiabilidad todo el tiempo. Dicho esto, DEBES tener ciertas cosas que sean 100% confiables, por lo que aún necesitarás ciertas cosas para garantizar la entrega, como la creación de objetos y la destrucción de objetos. Esto significa que debe implementar su propio protocolo basado en prioridad semi-confiable sobre UDP. Esto es difícil.

Por lo tanto, pregúntese qué es importante, conozca cómo funcionan TCP y UDP, y luego haga una elección inteligente.

Dicho esto, ahora tiene que sincronizar el estado del objeto en la red. Esto significa que sus objetos necesitan serializar a algo que pueda representarse en una secuencia de bytes y escribir en un socket. Escribir en un socket es fácil; Si puede escribir en un archivo puede escribir en un socket, realmente no es difícil. Lo importante es asegurarse de que puede representar un objeto como un búfer, por lo que si su objeto tiene referencias/punteros a otros objetos, no podrá enviar esos punteros ya que son diferentes en los otros clientes. , por lo que debe convertirlos en algo que sea común a todos los hosts. Esto significa ID's, aunque el ID de un objeto debe ser único en todos los hosts, por lo que debe tener una forma de coordinarse entre hosts de modo que no haya dos hosts que creen objetos diferentes con el mismo ID. Hay formas de manejar hosts haciendo esto, pero no nos preocuparemos por eso aquí (sugerencia: use algún tipo de mapeo entre la identificación del host y la ID de la red. Sugerencia más grande: No haga esto si no necesita)

Así que ahora puede enviar datos, genial, ¿ahora qué? Cada vez que el estado del juego cambia, debe enviar una actualización a las otras máquinas de alguna manera. Aquí es donde entra la arquitectura cliente-servidor o peer-to-peer si lo desea. Cliente-Servidor es más fácil de implementar. Además, un host "actúa", ya que el servidor sigue siendo Cliente-Servidor y cualquiera que diga algo diferente está equivocado.

Por lo tanto, la responsabilidad del servidor es "poseer" todo el estado del juego. Solo el servidor puede decir en definitiva en qué estado se encuentra un objeto. Si desea mover un objeto, le dice al servidor que le gustaría mover, sin embargo, el servidor le dice que debe mover el objeto, no solo hazlo (aunque a veces es útil algún tipo de predicción del lado del cliente). THen el servidor envía el estado de objeto actualizado a todos los otros hosts.

Has mencionado un juego por turnos, ¿no? Muy simple:

  1. Vas a resolver una vuelta completa en el cliente, que es a su vez se encuentra actualmente. Una vez que el cliente hace lo que quiere hacer, envíe los resultados de ese turno al servidor. Luego, el servidor valida los movimientos del cliente (no solo confía en el cliente, las trampas suceden de esa manera) y los aplica a su estado de objeto.
  2. Una vez que el servidor está actualizado, envía mensajes a todos los demás clientes con el nuevo estado del mundo, y esos clientes aplican esas actualizaciones.Esto incluye al cliente que acaba de tomar su turno; ese cliente solo debe actualizar su estado mundial cuando el servidor se lo indique, ya que desea garantizar la coherencia con el resto de los hosts Y desea evitar que un host haga trampa.
  3. El servidor envía un mensaje que indica a quién le toca el turno. Puede enviar esto al mismo tiempo que la actualización del estado mundial en el paso anterior, eso estaría bien. Solo tenga en cuenta que los clientes intentan cumplir su turno. Es por eso que el servidor tiene autoridad sobre el mundo; si un cliente intenta hacer trampa, el servidor puede derribarlos.

Eso es todo lo que tendrá que hacer para un juego de turnos. Sugerencia: Use TCP Sugerencia más importante: TCP implementa algo llamado "Algoritmo de Nagle" que combinará sus mensajes en un solo paquete. Lo que esto significa es que si envía dos mensajes separados con dos llamadas separadas para "Enviar", es posible que los otros hosts reciban solo un paquete en una sola llamada para "Recibir", pero ese paquete contendrá el contenido de AMBOS de los paquetes que fueron enviados. Por lo tanto, si envía dos paquetes de 100 bytes con dos llamadas para enviar, puede recibir un paquete de 200 bytes en una sola llamada para recibir. Esto es normal, por lo que debe ser capaz de lidiar con esto de alguna manera. Un truco consiste en hacer que cada paquete sea del mismo tamaño y luego leer tantos bytes del socket cada vez que se comprueba la entrada. Tenga en cuenta también que también puede obtener mensajes parciales. Por ejemplo, si envía dos mensajes de 100 bytes, se pueden combinar en un solo mensaje de 200 bytes. A continuación, si lee desde el socket en el otro extremo, pero lee con un tamaño de búfer de 150 bytes, tendrá 150 bytes, que contiene el primer paquete y parte del segundo. Tendrá que hacer una segunda llamada para recibir el resto del segundo mensaje, así que MANTENGA PISTA DE CUÁNTOS DATOS HA RECIBIDO para que no se pierda parte de un paquete en alguna parte. Es por eso que mantener sus paquetes del mismo tamaño es útil.

Existen otros trucos útiles para reducir el tamaño y la frecuencia de tus mensajes y para realizar un seguimiento de los juegos que no están basados ​​en turnos y actuar en tiempo real, pero si tienes un juego por turnos, entonces lo correcto es usar TCP y no preocuparse por nada de eso. Aquí hay algunos enlaces a sitios web y artículos útiles que le dará más información sobre cómo se realiza la programación de la red del juego:

  • Glenn Fiedler's site, una gran información aquí.
  • 1500 archers, un excelente documento sobre cómo implementar una técnica llamada deterministic lockstep, que es útil para muchos tipos de juegos.

Deseo saber si desea obtener más información sobre estas cuestiones o si tiene más preguntas específicas.

Cuestiones relacionadas