Multijoueur
Permettez à plusieurs personnes de partager une même scène en même temps. Envoyez des messages, partagez des valeurs, faites apparaître des objets pour tout le monde et affichez les autres joueurs qui se déplacent en douceur.
Ces appels ne fonctionnent que si le multijoueur est activé pour votre projet et qu'une salle est ouverte. Le reste du temps, ils ne font rien. Le même script fonctionne donc aussi dans un aperçu à un seul joueur, et vous n'avez pas besoin de deux versions.
Qui est dans la salle
ctx.net.id; // l'id de ce participant
ctx.net.peers(); // tous ceux qui sont dans la salle en ce moment
ctx.net.onJoin((peer) => {});
ctx.net.onLeave((peer) => {});
Ce qui se synchronise tout seul
Uniquement les positions des corps physiques réglés sur shared. Tout le reste, c'est à vous de l'envoyer.
C'est voulu. Une caisse, une porte ou une balle doit être un seul objet, que tout le monde voit au même endroit. Un personnage joueur, lui, ne doit pas être partagé : sinon, quand une personne marche, l'avatar de tout le monde bouge. → propriété
Messages
Utilisez les messages pour ce qui se produit : quelqu'un a marqué un point, une manche a commencé, une porte s'est ouverte.
ctx.net.send('score', { points: 10 });
ctx.net.on('score', ({ from, data }) => {
/* … */
});
Un message part vers tout le monde sauf vous. Vous ne recevez pas de confirmation en retour.
État partagé
Utilisez l'état partagé pour les valeurs sur lesquelles tout le monde doit être d'accord. C'est une simple table de clés et de valeurs, dont chacun reçoit une copie. Si deux personnes écrivent la même clé, c'est la dernière écriture qui l'emporte.
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) => {});
Pour garder des valeurs propres à chaque joueur, utilisez ctx.net.id comme clé. Chaque personne
écrit sa propre entrée et lit celles des autres.
Faire apparaître pour tout le monde
const id = ctx.net.spawn(props.bullet, { position, rotation });
ctx.net.despawn(id);
Vous recevez l'id tout de suite, mais l'objet n'apparaît qu'un instant plus tard. L'id est le même pour tout le monde.
Seule la personne qui a fait apparaître un objet peut le retirer. Quand quelqu'un quitte la salle, les objets qu'il a fait apparaître sont retirés aussi.
Déplacer les autres joueurs en douceur
C'est là que les choses se passent le plus souvent mal : il existe donc un appel spécial pour cela.
ctx.net.follow(otherPlayerObject, { position, rotation });
ctx.net.unfollow(otherPlayerObject);
Appelez follow avec chaque position que vous recevez. Dix à vingt fois par seconde, c'est
normal. L'objet se déplace alors en douceur, un peu en retard sur la dernière position.
Rappeler follow avec la même position ne coûte rien. Vous pouvez donc l'appeler à chaque image
avec la dernière position dont vous disposez.
Les mises à jour arrivent bien moins souvent que les images : l'objet reste immobile, puis saute. Les autres joueurs semblent avancer par à-coups au lieu de marcher. Faire glisser l'objet vers la position la plus récente ne règle pas non plus le problème. Entre deux mises à jour, il n'y a aucune nouvelle position vers laquelle aller : l'objet s'arrête, puis repart d'un coup.
Une organisation qui marche
Si vous partez de zéro, cette organisation vous mènera loin :
- Chaque joueur contrôle son propre personnage — un corps local, déplacé par ses propres commandes.
- Sa position est diffusée par
net.stateou par des messages, dix à vingt fois par seconde. - Les personnages de tous les autres sont déplacés avec
follow. - Les objets du monde sont des corps partagés, que la physique garde synchronisés pour vous.
- Le score et l'état de la manche vivent dans
net.state, écrits par la personne chargée de cet événement.
Suivant : Dépannage — que faire quand quelque chose ne fonctionne pas.