Multijugador en Phaser con Firebase
🎯 Objetivo de esta lección
En esta lección aprenderás a crear un formulario HTML integrado dentro de un juego desarrollado con Phaser, que permitirá a los jugadores introducir un ID de sala para unirse a partidas multijugador. Además, conectarás este sistema con Firebase para validar las salas existentes.
Configuración del cliente
🧱 Paso 1: Habilitar DOM en Phaser
Antes de poder cargar elementos HTML en tu juego, debes habilitar el sistema DOM en el fichero package.json. Para ello, añadiremos el siguiente código para poder cargar nuestro formulario HTML:
/package.json
dom: {
createContainer: true,
},
Esto permite a Phaser crear un contenedor DOM que puede renderizar elementos HTML sobre el lienzo del juego (canvas
). Sin esta configuración, los formularios HTML no se mostrarán.
🧾 Paso 2: Crear el formulario HTML
Definimos el formulario HTML que vamos a cargar en nuestro juego:
<label for="roomId">Escribe el id de la sala</label
><input
type="text"
name="roomId"
placeholder="roomId"
id="roomId"
style="font-size: 32px"
/>
<button id="conectar" name="conectar">Conectar</button>
<p style="color: white">
O dale este ID a un amigo: <span id="currentRoomId"></span>
</p>
📥 Paso 3: Precargar el formulario en la escena
Debemos precargar el HTML anterior en nuestro juego:
preload() {
this.load.html("roomForm", "/assets/main.html");
}
🧠 Paso 4: Usar el formulario en la escena del juego
Cargaremos la escena anterior en nuestro juego mediante el siguiente código de la escena Game:
import { Scene } from "phaser";
import { createRoom, getRoomById } from "../services/room";
export class Game extends Scene {
constructor() {
super("Game");
}
create() {
const f = async () => {
const currentRoomId = await createRoom();
const form = this.add.dom(400, 100).createFromCache("roomForm");
const roomInput = form.getChildByID("roomId");
const playButton = form.getChildByID("conectar");
roomInput.textContent = currentRoomId;
playButton.onclick = async (event) => {
if (event.target.name === "conectar") {
const roomId = roomInput.value;
const room = await getRoomById(roomId);
if (!room) {
alert("No existe una room con este id");
} else {
this.scene.start("Karate");
}
}
};
};
f();
}
}
🔗 Paso 5: Conexión con Firebase
El código anterior está llamando a un documento que se conecta con firebase:
import { db, getDocs, collection, query, where } from "./firebase";
// CREATE
export const createRoom = async () => {
const colRef = collection(db, "rooms");
const ms = new Date().getTime();
console.log(ms);
const obj = {
date: ms,
id: 1234,
};
await addDoc(colRef, obj);
return obj.id;
};
export const getRoomById = async (roomId) => {
const colRef = collection(db, "rooms");
const result = await getDocs(
query(colRef, where("id", "==", Number(roomId)))
);
const doc = getArrayFromCollection(result);
return doc[0];
};
const getArrayFromCollection = (collection) => {
return collection.docs.map((doc) => {
return { ...doc.data(), id: doc.id };
});
};
Este sistema te permite:
- Generar un ID único de sala.
- Guardarlo en Firebase.
- Validar si una sala existe antes de conectar al jugador.