Multijugador
Deja que varias personas compartan la misma escena a la vez. Envía mensajes, comparte valores, crea objetos para todos y muestra a los demás jugadores moviéndose con suavidad.
Estas llamadas solo funcionan cuando el multijugador está activado en tu proyecto y hay una sala abierta. El resto del tiempo no hacen nada. Así, el mismo script también funciona en una vista previa para un solo jugador, y no necesitas dos versiones.
Quién está en la sala
ctx.net.id; // el id de este participante
ctx.net.peers(); // todos los que están ahora en la sala
ctx.net.onJoin((peer) => {});
ctx.net.onLeave((peer) => {});
Qué se sincroniza solo
Solo las posiciones de los cuerpos físicos marcados como shared. Todo lo demás lo envías tú.
Es a propósito. Una caja, una puerta o una pelota deben ser un único objeto que todos ven en el mismo sitio. Un personaje del jugador no debe ser compartido: si lo es, cuando una persona camina, se mueven los avatares de todos. → propiedad
Mensajes
Usa mensajes para las cosas que ocurren: alguien ha marcado un punto, ha empezado una ronda, se ha abierto una puerta.
ctx.net.send('score', { points: 10 });
ctx.net.on('score', ({ from, data }) => {
/* … */
});
Un mensaje llega a todos menos a ti. No recibes ninguna confirmación.
Estado compartido
Usa el estado compartido para los valores en los que todos tienen que coincidir. Es un mapa sencillo, y cada uno recibe una copia. Si dos personas escriben la misma clave, gana la última escritura.
ctx.net.state.set(ctx.net.id, { name, colour, ready: true });
ctx.net.state.get(somePeerId);
ctx.net.state.all();
ctx.net.state.on(ctx.net.id, (value) => {});
Para guardar valores de cada jugador, usa ctx.net.id como clave. Cada persona escribe su propia
entrada y lee las de los demás.
Crea objetos para todos
const id = ctx.net.spawn(props.bullet, { position, rotation });
ctx.net.despawn(id);
Recibes el id al momento, pero el objeto aparece un instante después. El id es el mismo para todos.
Solo la persona que ha creado un objeto puede eliminarlo. Cuando alguien sale de la sala, los objetos que ha creado también se eliminan.
Mueve a los demás jugadores con suavidad
Aquí es donde más a menudo fallan las cosas, así que hay una llamada especial para ello.
ctx.net.follow(otherPlayerObject, { position, rotation });
ctx.net.unfollow(otherPlayerObject);
Llama a follow con cada posición que recibas. Entre diez y veinte veces por segundo es lo
normal. Después, el objeto se mueve con suavidad, un poco por detrás de la última posición.
Volver a llamar a follow con la misma posición no cuesta nada. Así que puedes llamarlo en cada
fotograma con la última posición que tengas.
Las actualizaciones llegan con mucha menos frecuencia que los fotogramas, así que el objeto se queda quieto y luego salta: parece que los demás jugadores avanzan a saltos en lugar de caminar. Acercarse poco a poco a la última posición tampoco lo arregla. Entre una actualización y otra no hay nada nuevo hacia donde moverse, así que el objeto se para y luego da un tirón.
Una configuración que funciona
Si empiezas desde cero, esta configuración te servirá para mucho:
- Cada jugador controla su propio personaje: un cuerpo local que se mueve con su entrada.
- Su posición se envía a los demás con
net.stateo con mensajes, entre diez y veinte veces por segundo. - Los personajes de los demás se mueven con
follow. - Los objetos del mundo son cuerpos compartidos, así que la física los mantiene sincronizados por ti.
- La puntuación y el estado de la ronda están en
net.state, y los escribe quien esté a cargo de ese evento.
Siguiente: Solución de problemas: qué hacer cuando algo no funciona.