Con las crecientes oportunidades para crear juegos multijugador en línea para diferentes plataformas, y muchas herramientas de código abierto accesibles y fáciles de usar, se ha vuelto mucho más conveniente para los desarrolladores crear emocionantes juegos multijugador. En esta charla, Sahar creará un juego multijugador simple para demostrarlo y hablará sobre los problemas que enfrentó al crear sus propios juegos.
Juegos web multijugador utilizando JavaScript
Video Summary and Transcription
La charla de hoy trata sobre la creación de un juego web multijugador utilizando Phaser y Socket.io. El orador demuestra cómo crear un juego de tres en raya, incluyendo la creación de la tabla, asignación de jugadores, realizar movimientos y determinar el próximo turno. Se discute la importancia de elegir el protocolo adecuado para juegos multijugador, como WebSocket o UDP. La charla también destaca las ventajas de utilizar JavaScript para juegos web y móviles, así como consideraciones para el código de red y disponibilidad del código.
1. Introducción a los juegos web multijugador
Hola a todos. Soy Sahar Poundasseh, un desarrollador de juegos independiente de Irán. Hoy les mostraré cómo crear un juego web multijugador utilizando Phaser y Socket.io. Construyamos juntos un juego de tic-tac-toe. He preparado previamente algo de código y lógica. En mi servidor Node.js, he instalado Express y Socket.io e implementado un archivo index.html. Genero un token para la sala utilizando un número aleatorio de cuatro dígitos. En el archivo index.html, importo la plataforma Phaser y utilizo socket.io. El código incluye un archivo de configuración de Phaser con cuatro funciones principales.
Hola a todos. Mi nombre es Sahar Poundasseh, como ya me conocieron antes. Soy un desarrollador de juegos independiente con sede en Irán, Teherán, y trabajo en un estudio de juegos llamado GearBag. Estoy aquí para hablar sobre juegos web multijugador. No soy muy buen orador, así que quiero mostrarles en acción cómo pueden crear un juego web multijugador desde cero y lo fácil que es, para que no se confundan con las complejidades. Voy a utilizar Phaser como mi motor y Socket.io Node.js como mi servidor, pero pueden usar cualquier cosa. Lo básico es que vamos a utilizar WebSocket y eso es todo. Espero que lo disfruten. Así que construyamos nuestro juego. Vamos a crear un juego de tic-tac-toe, uno simple, pero como no tengo mucho tiempo y no soy muy rápido escribiendo, he preparado algo de código, algo de lógica de antemano, el juego y cosas así. Vamos a completar el código de nuestra red juntos. Aquí en mi servidor Node.js, solo he instalado Express y Socket.io e implementado e importado un archivo index.html. Y estoy sirviéndolo aquí. Y solo tengo una función que genera un token para la sala. Es un número aleatorio de cuatro dígitos. Voy a usarlo con cuatro dígitos. Y por qué uso esto es porque me gustan los códigos de sala y me hace sentir especial como un VIP. Me gusta implementarlo en mis juegos. Y en mi archivo index.html, tengo estos dos archivos. He importado la plataforma Phaser y también he implementado, déjenme ir aquí abajo. También he implementado socket.io. Está construido sobre WebSocket, por lo que básicamente es WebSocket, pero estoy usando socket.io en este momento. En el código que está aquí, lo explicaré muy rápido. Es mi archivo de configuración de Phaser. Solo tiene el ancho y alto y tiene cuatro funciones principales, create init, preload y update para la escena. Solo tengo una escena. Estoy usando la función init y create. En mi init tengo algunas variables como el personaje del jugador y el registro de juego.
2. Creando la Tabla y la Interfaz de Usuario del Juego
Voy a mantener mis caracteres en la información de la tabla. El índice de la tabla, las métricas de la tabla, contiene unos y menos unos para las entradas de los jugadores. La tabla tiene un contenedor, un personaje y una zona para hacer clic. Estoy comprobando si es el turno del jugador y si el personaje de esa zona está vacío. Hay dos cuadros para la interfaz de usuario del juego, un cuadro de bienvenida y un cuadro para los botones de crear/unirse a la sala. Conectaré nuestro cliente al servidor de sockets.
Y en mis creaciones, he creado la tabla. Así que es un contenedor y phaser. Y tiene un personaje, que está vacío en este momento. Y contendrá X y O, y una zona para hacer clic. Y estoy guardando este personaje en la información de la tabla aquí mismo. Con un ID de lugar. Entonces, en lugar de usar I y J por separado, estoy usando un lugar del cero al ocho para gestionar mis lugares al hacer movimientos dentro del juego. Y esto es un evento de clic para la zona. Entonces, en este evento de clic, antes de emitir el movimiento al servidor y a los otros jugadores, estoy comprobando si es el turno del jugador y si el personaje de esa zona está vacío. Entonces, si ya hay algo allí, no lo estoy emitiendo. Y esta es la tabla. Y tengo dos cuadros. Es solo la interfaz de usuario del juego. Es un cuadro de bienvenida. Que escribirá bienvenida y mostrará el token de la sala al creador. Y hay un cuadro para contener dos botones para crear sala y unirse a sala. Y hay dos funciones para el escucha de clics. Entonces, cuando hacemos clic en crear una sala, debemos emitir a nuestro servidor que debe crear una sala para nosotros. Y para unirse, voy a tomar el token de la entrada del usuario y voy a emitir esto al servidor después para unirme a la sala. Y aquí hay un texto simple para mostrar un inicio y si es tu turno o no o si estás jugando con X o O. Y eso es todo, muy simple. Así que comencemos con nuestro lado del cliente. Lo primero que debemos hacer es conectarnos.
3. Creando una Sala y Asignando Jugadores
Cuando el jugador abre el juego, se conecta al socket. El primer paso es crear una sala emitiendo 'crear sala' al servidor. El servidor genera un token de cuatro dígitos y une al usuario a la sala. Se notifica al usuario que se ha creado la sala con el token. El servidor mantiene una lista de jugadores y sus salas, asignándoles personajes.
4. Asignación de Personajes y Compartir Token de Sala
Les asignaré el personaje x porque se unieron primero. La sala ha sido creada y emitirá un token de vuelta. Ocultaremos la caja de selección y mostraremos la caja de bienvenida con el token de sala para compartir.
5. Unirse a la Sala y Verificar Disponibilidad
El siguiente paso es que el otro usuario emita un token para unirse a la sala. Escuchamos el evento 'joinRoom' en el servidor y verificamos si la sala existe. También verificamos el número de jugadores en la sala.
6. Joining the Room and Starting the Game
Voy a verificar si ya hay dos jugadores en la sala. Si es así, la sala no está disponible. Luego, uniré al usuario a la sala y los agregaré a la lista de jugadores. La sala está llena, así que notificaré a ambos jugadores que el juego está comenzando. Emitiré el evento 'start game' a los oponentes del jugador que solicitó unirse, pasando información sobre la sala, los personajes y el turno. Al jugador que se unió, les notificaré que el juego está comenzando y les proporcionaré información sobre la sala. Si la sala no está disponible, emitiré un error. En el lado del cliente, escucharé el evento 'start game' y asignaré el token de la sala, el personaje del jugador y el bloqueo de juego basado en la información recibida.
7. Haciendo Movimientos y Determinando el Siguiente Turno
Si es tu turno de jugar, el bloqueo sería falso. Muestra tu pieza y el texto de inicio. Después de eso, muestra la tabla. Los jugadores se han unido a la sala y han recibido un mensaje de inicio de juego. Para hacer un movimiento, emite el movimiento al servidor con la información de la sala y la posición. Escucha el movimiento en el servidor. Encuentra el personaje del jugador que hizo el movimiento para determinar el siguiente turno.
Y ahora esto emitirá y moverá al servidor. Así que tenemos que volver aquí y escuchar eso. Entonces obtengo eso en. Mover, estamos obteniendo información sobre el movimiento, ¿verdad? Y lo primero que voy a hacer es encontrar el personaje del jugador que acaba de hacer el movimiento, para determinar quién será el siguiente turno. Así que voy a manejar eso en mi servidor porque es más seguro de esa manera. Para hacer eso, voy a encontrar el jugador con este ID. Entonces el índice es igual a jugadores.map con una función que obtiene un jugador y devuelve ese ID. Y luego voy a encontrar el índice hacia arriba, segundo, ese ID. Así que voy a encontrar al jugador con su segundo ID, su ID de conexión. Y
8. Determinando el Siguiente Turno
Entonces, el jugador actual será el jugador del índice y luego emitiré el movimiento, no, voy a encontrar el turno. Tenemos el nuevo turno, ahora vamos a decirles a los jugadores dentro de la sala que les toca jugar. Vamos a decir IO.to info.room.emit move. Y voy a pasar la información autorizada a esto. Veamos si... Bien, todo parece bien.
9. Escuchando las Reglas y Manejando los Movimientos
Ahora, volvamos a nuestro cliente. Tenemos que escuchar las reglas y manejar los movimientos. Después de cada movimiento, verificamos si hay una victoria. Finalmente, manejamos las desconexiones de los jugadores expulsándolos de la sala y eliminándolos del array de jugadores.
Ahora, volvamos a nuestro cliente. Ahora, tenemos que escuchar las reglas. Verás, no hice nada para eso dentro del cliente. Así que, vamos a escuchar. Justo aquí, this.socket.on y remove. Estamos recibiendo alguna información. Y qué voy a hacer con esa información, tengo un método handle move que es solo una parte de la interfaz de usuario. Establece el contenido del texto en las celdas como el carácter del movimiento, y actualiza la matriz de la tabla con unos y menos unos. Y determina el turno. Entonces, si es tu turno de jugar, el registro de juego será falso y dirá que es tu turno de jugar, y después de cada movimiento, estoy verificando la victoria justo aquí para detener el juego. Entonces, en el movimiento voy a llamar a mi función handle move y necesitará un contexto debido a mi contexto, sí. Entonces, las celdas van a ser esto y voy a decir this y la información que obtuve del movimiento, del servidor y lo manejará aquí mismo. Ahora, básicamente todo está hecho, pero voy a hacer una última cosa para atar todos los cabos sueltos porque siempre tienes que escuchar eso o estarás en problemas Tal vez eso no sea correcto decirlo. Sí. No soy hablante nativo de inglés, así que perdona mi francés. Entonces, estoy atascado en el on disconnect. Vamos a verificar si el jugador se ha desconectado de la red. Entonces, primero vamos a encontrar a los jugadores. Tengo el código justo aquí. Después de encontrar al jugador, lo voy a expulsar de la sala. Entonces, vamos a decir, players index.room. Así que, expulsémoslos de esta sala. Y también, los voy a eliminar del array de jugadores, porque si el array de jugadores se vuelve demasiado grande, consumirá mucha memoria y eso realmente no es lo que quieres. Entonces, players.splice, desde este índice y uno por uno. Bien, todo está hecho. Y realmente espero no tener ningún error ni nada. Así que, vamos a verificar.
10. Conclusión del Juego y Consejos
Tengo dos clientes, uno creando una sala con el token 7983, y el otro uniéndose. Juego el juego y gano y pierdo al mismo tiempo. WebSocket es confiable para la transmisión de datos de extremo a extremo, pero UDP es más rápido y mejor para juegos PVP. Considera el mejor protocolo para tu juego. Además del método cliente-servidor, puedes usar una red peer-to-peer para una transmisión de datos más rápida y una codificación más sencilla.
Muy bien. Es mi turno de jugar. El lado izquierdo es para jugar. Voy a poner una X allí y una O aquí. Y luego voy a X allí, O aquí. Correcto. Y gano y pierdo al mismo tiempo. Así que, el juego ha terminado. Y fue muy fácil. Sé que el juego es fácil, pero el concepto es realmente fácil. Piénsalo. Pero antes de terminar, volvamos a nuestras diapositivas. Tengo una cosa más que decir. Y terminaré después de eso. Así que, hay algunos tips. En primer lugar, WebSocket se basa en el protocolo TCP, que es una comunicación de 3 vías, y es muy confiable, y asegura la transmisión de datos de extremo a extremo y su seguridad. Pero también existe el protocolo UDP, que es en realidad más común y más adecuado para juegos PVP. Y es más rápido. Y si hay algunos paquetes de datos que se pierden en el camino, no le importa. Así que tal vez necesites usar eso. Así que piénsalo. ¿Cuál es lo mejor, el mejor protocolo para usar en un juego? Y también, utilicé el método cliente-servidor, aquí en el juego de Tic Tac Toe, pero no es el único método. Puedes usar el método de red peer-to-peer, donde los nodos están conectados entre sí directamente, y no hay un nodo de servidor, por lo que la transmisión de datos es más rápida entre ellos.
11. Fiabilidad y Consideraciones de Red
WebSocket es confiable para la transmisión de datos de extremo a extremo, pero UDP es más rápido y mejor para juegos PVP. Considera el mejor protocolo para tu juego. Además del método cliente-servidor, puedes usar una red peer-to-peer para una transmisión de datos más rápida y una codificación más sencilla.
12. Consideraciones de Código de Red y Disponibilidad de Código
Comienza temprano con tu código de red y piensa en ello desde el principio en tu código. Ten en cuenta la cantidad de información que estás transmitiendo entre tus pares. Gracias por escuchar. Websockets son la mejor opción para juegos multijugador. Es útil tener una opción no obligatoria para comprender el uso de las API de red en tiempo real. El código está disponible en GitHub.
Lo siguiente es comenzar temprano con tu código de red. Así que no digas que voy a terminar mi juego por completo y luego voy a agregar mi lógica de red para hacerlo multijugador. Será mucho más difícil y mucho más complejo. Así que piensa en ello desde el principio en tu código y hazlo simultáneamente. Y también, ten en cuenta la cantidad de información que estás transmitiendo entre tus pares, porque si la cantidad de información es muy grande, ralentizará tu servidor y no ralentizará, pero el mensaje llegará más lento y no creará una buena experiencia para los jugadores. Ahora, espero que hayas disfrutado esta charla y gracias por escuchar. Nos vemos el resto de la tarde. Hasta luego por ahora. ¿Quieres ver los resultados de esta encuesta? Parece que... Sí, claro. Me encantaría hacerlo. Websockets son la mejor opción aquí. Eso es realmente bueno porque si ya conoces Websockets, ya has recorrido más de la mitad del camino. Comienza a desarrollar juegos multijugador. Creo que fue útil tener una opción no obligatoria aquí porque eso fue algo... Tuvimos una encuesta similar ayer. No pudimos decir. Creo que había otra opción y no pudimos decir si la gente estaba usando otras tecnologías o si no estaban haciendo juegos multijugador. Siento que esto ayuda. Quería saber si la gente no ha estado trabajando con ninguna de estas API de red en tiempo real o tal vez sí lo han hecho. Es bueno saberlo. Ya has recorrido la mitad del camino. Sí. Genial. Creo que podemos echar un vistazo a algunas de las preguntas que han enviado. La primera también es una pregunta que tengo. ¿Está disponible en algún lugar el código que mostraste en la disponible en algún lugar como GitHub o algo así si quisiera probarlo y jugar con él? Sí, absolutamente. Publicaré el enlace a GitHub en el canal. Genial. Tal vez también puedas tuitearlo.
QnA
Ventajas de los juegos web y JavaScript
¿Podemos usar UDP en juegos web? No, no es seguro debido a problemas de red. WebRTC es una alternativa, pero se recomienda TCP con WebSocket. WebRTC podría funcionar para juegos pequeños, pero las salas más grandes y los juegos móviles presentan desafíos. Para juegos uno a uno, WebRTC puede ser una buena opción. Sin embargo, aún se necesita un servidor para la conexión inicial entre pares. El uso de JavaScript en la web tiene ventajas debido a la facilidad de implementación, compilación rápida, fácil visibilidad del código y compatibilidad entre dispositivos.
Por supuesto que sí. También para aquellos que no estén en Discord y quieran verlo. Genial. Excelente. Y luego otra pregunta. No sé mucho al respecto, pero la haré. ¿Podemos, es posible usar UDP en juegos web hoy en día? ¿Es algo que podemos hacer?
En realidad, no, porque hay algunos problemas de red, como ataques VDOS que hacen que no sea seguro usar el protocolo UDP en la web, pero lo más cercano que tenemos a eso es usar WebRTC, que en realidad no es mi preferencia porque es realmente... en primer lugar, es un P2P por sí mismo y es más difícil de implementar. Así que creo que usar TCP con WebSocket es el camino a seguir.
Tiene sentido. Pero, ¿eso significa que WebRTC sería mejor en términos de... No necesariamente tendría costos de servidor. Entonces, si estás haciendo un juego pequeño o algo así, porque es P2P, no... Sí, un juego pequeño, como una sala pequeña como el juego de tres en raya, podría hacerse con WebRTC, pero a medida que las salas se vuelven más grandes, especialmente, hay más problemas para P2P y WebRTC. Por ejemplo, en juegos móviles, cada cliente tiene que enviar sus mensajes a cien personas y eso usaría mucha data de conexión y no sería una buena práctica. Tiene sentido. Pero parece que si es un juego uno a uno como el ajedrez o algo similar donde solo hay dos jugadores, entonces tal vez WebRTC sería una buena opción. Eso sería bueno. Genial. Oh, hice una pregunta de seguimiento para eso. Pero aunque sea P2P, ¿aún necesitas un servidor para hacer la conexión inicial entre los pares?
Exactamente. Puedes usar ICE en tu servidor para hacer eso. Como dije, es más difícil de implementar. Entonces, tal vez para un juego más pequeño, es mejor usar los web sockets, porque es más fácil de implementar. Tiene sentido. Genial. ¿Y qué hay de, tenemos una pregunta de Tanta. Dicen gracias por la charla. Y mi pregunta es, ¿cuál es la ventaja de usar JavaScript en la web en comparación con los juegos de escritorio, por ejemplo?
Bueno, JavaScript en la web, en realidad es mucho más fácil de implementar, porque la mayoría de los desarrolladores ya han trabajado con JavaScript y la compilación es realmente rápida, así que no necesitas nada, lo mejor de todo es que solo tienes que actualizar la página del navegador y puedes ver tu trabajo, sí, está ahí, y supongo que eso es lo mejor para mí, porque puedo compilar fácilmente mi código, ver fácilmente los resultados y cosas así, y es mucho más fácil de publicar debido a la forma en que está en la web y puedes hacerlo,
Usando JavaScript para juegos web y móviles
JavaScript se puede utilizar para juegos web y también para crear juegos para Android e iOS. Los desarrolladores de Android pueden publicar juegos web en la tienda de aplicaciones de Android utilizando TWAs, que son similares a las PWAs. Proporciona más accesibilidad. iOS puede tener una opción similar. Esto es similar a lo que Will mencionó sobre publicar juegos de Play Games con Cordova o frameworks similares.