Juegos multijugador con Makecode Arcade

Introducción

Qué es un juego multijugador

Un juego multijugador es aquel tipo de juego en el que pueden jugar 2 o más personas al mismo tiempo.

Estos juegos pueden ser de tipo cooperativos para poder luchar juntos por un objetivo común como por ejemplo derribar ambos todos los aviones que encuentren o pueden ser de tipo rival  como por ejemplo el típico juego de lucha de uno contra otro.

En Makecode Arcade también es posible programar este tipo de juegos,  y si ya es divertido poder jugar con tus amigos a un mismo juego más divertido  te resultará programarlos y verás lo sencillo que resulta .

La consola OK:D51

Desde Makecode Arcade se puede aprender a programar todo tipo de juegos sin tener consola física,  pero si te animas a tener la tuya y quieres programar juegos multijugador necesitas disponer de una consola que disponga de esta característica como por ejemplo la consola OK:D51 que permite unirlas mediante 2 cables dupont macho para realizar la comunicación entre ellas.

Opciones de Makecode Arcade

Simulados

Actualmente Makecode Arcade permite programar juegos multijugador por bloques pero éstos de momento sólo se pueden probar en el simulador con 2 jugadores usando el teclado como veremos en el siguiente ejemplo.  

En consolas físicas

Para hacer posible programar juegos multijugador y mediante bloques  existe una extensión no oficial que veremos en este tutorial y que te permitirá hacerlo, de lo contrario tendrías que programarlos mediante JavaScript o Python

Juego multijugador de lanzar penaltis

Objetivo

El objetivo de este juego será lanzar la pelota al otro jugador intentando que no la pare.  Para ello cada jugador podrá lanzar una pelota al contrario y éste deberá moverse de izquierda a derecha para intentar pararla,  y lo mismo tendremos que hacer nosotros cuando nos lancen la pelota.

Cada jugador que meta un gol al otro jugador, sumará un punto en su marcador. 

Ganará quien llegue antes a 10 puntos

Jugador 1

Estructurar el código inicial

Para que nuestro código resulte más sencillo de mantener, separaremos las partes diferenciadas del juego creando funciones que serán llamadas desde la entrada principal del programa on start 

  1. Desde la categoría Functions creamos un nuevo bloque que se llame initPlayer1 donde iremos arrastrando los bloques correspondientes para dar vida al jugador principal

Arrastramos el bloque creado al bloque principal on start

Dibujando al personaje

Como nos vamos a enfocar más en la metodología de programación, crearemos un personaje sencillo que constará de un rectángulo con una franja central azul.   Y como reto personal cada uno que lo mejore a su gusto.

Movilidad del jugador

  1. Queremos que se mueva sólo horizontalmente con una velocidad de 200 píxeles por segundo
  2. Que no se salga de los límites de la pantalla
  3. Lo emplazaremos en la mitad inferior de la pantalla  ( la pantalla mide 160x120 )

Resultado

Ya podemos ejecutar el juego y comprobar que cumple con los requisitos planteados

Jugador 2

Estructurar el código inicial

Al igual que hemos hecho con el Jugador 1,  vamos a crear otra función initPlayer2 para crear a nuestro segundo jugador y empezar a ver los bloques responsables de crear la modalidad multijugador

Bloques multijugador

Todos los bloques destinados para crear juegos de tipo multijugador están categorizados , y son muy similares a los usados para crear juegos sencillos de 1 jugador.

Movilidad del jugador

En nuestro caso tendremos que utilizar el siguiente bloque específico de multijugador donde indicaremos cómo se moverá nuestro jugador 2

El resto de código es similar al creado con el jugador 1, pero teniendo en cuenta que lo vamos a posicionar en la parte superior de la pantalla

  1. Creamos un sprite llamado jugador2 y lo representamos con un rectángulo rojo para diferenciarlo del jugador1
  2. Lo movemos de forma horizontal usando el bloque visto en el apartado anterior
  3. Lo posicionamos en la parte superior de la pantalla y en la mitad del eje x

Resultado

El resultado será el de 2 jugadores enfrentados que se pueden mover horizontalmente por la pantalla y lanzarse balones. 

Ejecutamos el código y movemos al jugador 1 pero ¿ cómo podemos probar el juego moviendo a los dos jugadores a la vez ? ( solución en la siguiente sección )

Controles Multijugador

Cuando probamos nuestro juego multijugador con el emulador tenemos que conocer cómo probar a ambos jugadores sin necesidad de descargar el juego en nuestras consolas.

El Jugador 1 lo puedes mover tanto con el gamepad del simulador como con el teclado, pero el Jugador 2 sólo se puede manejar con el teclado.

A continuación tienes el mapa de teclas para poder controlar ambos jugadores

Lanzamiento de balones

Desde el Jugador 1

El lanzamiento del balón lo trataremos como un proyectil que  sale desde el Jugador 1 con una velocidad en el eje y negativa ( para que suba desde abajo de la pantalla hacia arriba ),  para lanzarlo usamos el botón A


Problema:  Si probamos el juego vemos que se pueden lanzar muchos balones a la vez si pulsamos repetidas veces el botón A.  La solución en el siguiente apartado controlando los ciclos de vida de los proyectiles.

Ciclo de vida de los proyectiles

Existen 2 bloques con los que podemos controlar cuándo se ha creado un sprite ( un proyectil balón en nuestro caso) y cuando se destruyen,  por los que podemos crear una variable que controle cuando hay un balón en el juego en cuyo caso no permitiremos disparar otro balón.

  1. Sólo disparar el balón si NO hay otro en juego ( variable hayBalon = 0 )
  2. Cuando se crea el proyectil, indicar que hay un balón en juego ( con la variable creada hayBalon = 1 )
  3. Cuando desaparece o se destruye el proyectil podemos indicar que ya no hay balón )

Desde el Jugador 2

El código es muy similar,  incluso podemos duplicar todo el bloque if ...  al que cambiaremos algunos parámetros. 

  1. En este caso el bloque de pulsación del botón A es específico de  multijugador
  2. Indicamos que el balón es un proyectil que sale desde el sprite jugador2
  3. Con una velocidad positiva en el eje y ( de arriba a bajo )

Parar el balón

Cada jugador tiene que parar el balón del otro jugador ya que sino se contabilizará como un Gol, para ello detectamos cuando el sprite balón ha tocado a algún jugador para destruirlo.

¿ Por qué destruir el balón si de todas formas desaparecerá y el sprite se destruirá sólo ?

Porque si lo destruimos antes de que salga por la pantalla  podremos detectar cuando los balones no son parados por un jugador y salen de la pantalla marcando un Gol

Detectar goles y actualizar marcador

Como vimos en la sección anterior,  si el balón no era destruido antes de que salga por la pantalla es porque alguien ha metido Gol,  por lo que actualizaremos el contador correspondiente de cada jugador.

  1. Inicializamos los contadores de ambos jugadores al empezar la partida
  2. Modificamos el bloque existente que detecta cuando un proyectil ( el balón ) se destruye
  3. Si la coordenada "y" del balón es negativa es porque se ha salido por la parte superior de la pantalla, GOL!! punto para el jugador 1
  4. Si la coordenada "y" del balón es mayor que 120 ( el alto de la pantalla ) GOL!! y punto para el jugador 2

Fin del partido

El fin del partido se producirá cuando alguno de los 2 jugadores alcance 10 puntos en su marcador. 

Esta comprobación podemos realizarla dentro de un bloque que se ejecuta siempre que cambie algo en el juego "on game update", aprovechamos este momento para volver a modificar el bloque de inicio de partida "on start" para meter los bloques de inicialización de contadores dentro de una función initGame  ya que nos resultará útil a la hora de resetear el juego

Extensión Real Multiplayer

Introducción

Para hacer posible el programar juegos multijugador usando bloques, existe la extensión no oficial llamada Real Multiplayer,  que podemos cargar en makecode desde la opción  "Avanzado > Extensiones"  y posteriormente insertar el siguiente enlace:

https://github.com/distintiva/pxt-real-multiplayer

Juego de naves multijugador

Para ver el funcionamiento de esta extensión a lo visto,  usaremos el siguiente juego que hemos creado :

https://arcade.makecode.com/84138-42853-06448-38206

Pantalla de Espera

Cuando un juego multijugador se va a descargar en las consolas, siempre tendrá que ponerse en modo espera hasta detectar la conexión de otra consola.

Ésta pantalla la puedes diseñar como quieras pero hay ciertos elementos fijos como el título del juego y la barra de progreso de espera que las puedes personalizar con los siguientes bloques:


Siempre que queramos probar la pantalla de espera desde el simulador,  tendremos que activar el siguiente bloque:

Y si queremos probar el propio juego la pondremos en "Off" 

Iniciada la conexión con la otra consola

Una vez nuestra consola detecte la conexión con la otra consola,  se ejecutará el siguiente bloque donde podremos especificar los aspectos de inicio del juego, decorado o posición de los jugadores.

También le diremos a la extensión qué 2 sprites harán de jugadores y cómo se moverán

Sincronizando imágenes entre las consolas

Cuando un sprite se crea o se mueve, o cuando se dispara un proyectil, hay que sincronizar las posiciones de estos sprites y sus imágenes.  Ésto se consigue especificando qué imágenes del juego serán creadas y necesitamos sincronizar con las 2 consolas.  

El bucle Maestro

Siempre una de las 2 consolas será la encargada de generar acciones aleatorias , ya que si ambas lo hicieran entonces cada una generaría juegos diferentes.   Para ello tenemos el master loop que será ejecutado sólo por una de las 2 consolas, y posteriormente sincronizará los sprites que haya generado con la otra consola.

Control de botones

En este caso que el juego se ejecutará en el hardware en lugar del simulador,  necesitaremos definir el comportamiento de los botones desde el mismo bloque.  Sólo hay que tener en cuenta que esta extensión nos facilita otro bloque "is player 1" para detectar si el botón ha sido pulsado por el jugador 1 o por el jugador 2.

También podemos ver como podemos usar el bloque "sprite ... belongs to player1/player2"  para poder asignar un proyectil a un jugador concreto, y así sabremos posteriormente quién ha destruido el meteorito

Gestión de puntuación

Ésto lo haremos como de la forma habitual ayudándonos del bloque que nos dice quién disparó el proyectil que acaba de tocar un meteorito

Con todo esto ya podemos descargar el juego en cada consola,  unirlas por cable y divertirnos con nuestros amigos!