Premier des 8 projets sur lequel je me suis mis : le prototypage de physique. C’est du code, c’est des maths et de la découverte de bas niveau mais je me suis vraiment ambiancé.

Pourquoi « It lives » ?

Dans ma checklist de trucs à faire pour ce sujet, c’était le premier nom, il concernait le fait de faire tourner un canvas, à 60 images par seconde sur un navigateur et d’avoir un petit rond bleu qui bouge sur fond gris en fonction de comment on bougeait un joystick de manette. It lives fait référence à plusieurs trucs, un synonyme de « Hello world! » qui est la première étape de beaucoup de projets de développement, Le monstre de Frankenstein, dont je n’ai jamais ni lu ni vu de représentation mais dont l’anecdote est universelle et aussi « It lives » un des premiers « grands » boss du jeu Binding of Isaac qui sera mon inspiration principale quant aux différents défis que vais me donner.

Les défis

1. It lives

J’ai donc créé un espace dans lequel bouge un rond grâce à une manette. J’ai choisit la manette car c’est plus agréable à utiliser et que ça représente une première facilité technique :

2. It is smooth

Je voulais que mon personnage se déplace grâce à de la vélocité. Avant, il avançait aussi rapidement que le joystick était orienté, maintenant, les joysticks alimentent une vélocité qui donne une poussé à mon perso. Ça permet notamment qu’il « glisse » une fois le joystick relâche

Mouvement basé directement sur les joysticks
Avec de la vélocité

3. It is blocked

Ce défi me demandait de faire en sorte que si le rond atteignait les bords du canvas je le bloque. J’ai d’abord voulu le faire rebondir, c’est à dire que s’il atteignait un bord j’inversais sa poussée pour qu’il « rebondisse » sur le mur, mais finalement je l’interdit juste d’aller plus loin que le canvas en baissant sa vitesse à 0.

4. They block

« They » représente les éléments extérieurs au personnage. Le but était donc de créer d’autres rond et d’avoir une collision avec eux. Et c’est là que commence vraiment le travail de physique. Ça m’a demandé plusieurs choses : comment détecter que deux ronds sont en collision, une fois que je détecte qu’ils sont l’un dans l’autre, comment repositionner mon personnage à l’endroit où il devrait être et quel comportement à un rond quand il rencontre un autre rond (comment le faire « glisser » de sorte à ce qu’il finisse par passer à côté). 

Mon plus grand ami ici a été Pythagore, j’ai fouillé dans les tréfonds de ma mémoire (et sur Google pour vérifier), je me rappelais qu’une collision entre rond était plus simple à définir qu’une collision de carrés : si la distance qui les sépare est plus petite que l’addition de leurs deux rayons alors ils sont l’un sur l’autre.

// this : rond qui bouge
// t : diminutif de target, l'autre rond
getHypothenuseWith(t) {
    let xDistance = t.x - this.x;
    let yDistance = t.y - this.y;
    return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
}

doItCollidesWith(t) {
    return this.getHypothenuseWith(t) <= this.radius + t.radius;
}

Cool, et maintenant, ils se chevauchent ils changent de couleur quand il sont l’un sur l’autre, ça fonctionne… Mais je voudrais qu’ils arrêtent de se chevaucher ou plutôt, que lorsqu’un chevauchement est détecté, mon perso se replace là où il devrait être bloqué. Et pour ça, encore une fois c’est grâce à l’hypoténuse que je l’ai trouvé. Je vois la distance en x et en y qui les sépare, et je le recule proportionnellement pour arriver à un hypothénuse qui soit égal à leur deux rayons… Ouch, c’est chiant à écrire… Donc à lire j’imagine pas, voilà une illu :

Une fois que j’avais ça, ma dernière question qui était « comment faire en sorte que mon perso glisse sur l’autre pour finalement en faire le tour » s’est résolu tout seul. Si je me dirige sans arrêt dans une direction, les deux ronds collisionnent, mon héros est replacé, ils recollisionnent mais le perso à un peu avancé, donc il est replacé un peu plus loin etc. Et ça fait le taf ✨

Conclusion

Voilà un petit aperçu de mon avancée sur ce projet. La liste de défi ne fait que se remplir donc je n’ai clairement pas finit d’en parler, mais 4 points pour commencer je trouve ça suffisant 🤯

Je suis curieux d’avoir votre avis sur le format, j’ai pas mal d’idée de mise en forme celle là était la plus intuitive pour moi, mais je peux couper avec des « scènes jouables » pour illustrer plutôt que des capture ou des animations par exemple ou mettre plus de code ou moins de code ou … enfin bref, hésitez pas à me dire !

A plus 🎉

PS : pour les plus techoss / curieux voilà le github
 (npm install, npm start et c’est parti sur localhost:3000)