enchant.js - 5e partie
Rédigé par Fred - - Aucun commentaire
Une des dernières choses que l’on va voir pour les sprites, c’est la
détection de collisions. Il existe deux méthodes qui font ça :
intersect
et within
.
La méthode intersect
prend un autre sprite comme paramètre :
if (someSprite.intersect(anotherSprite)){ //dosomething }
Le souci avec cette méthode, c’est que la détection se fait pour
l’intersection des rectangles contenant les sprites : un rond créé
avec un new Sprite(32, 32)
sera vu comme un rectangle de 32×32 (les
rectangles rouges que l’on voit en mode debug).
De même, dans le premier exemple, l’utilisation du découpage des images d’un sprite en frames fait que l’image en elle-même fait 20 pixels, alors que le sprite en fait 32. On a 6 pixels de chaque côté de l’image qui peuvent provoquer une collision alors que les voitures ne se touchent en fait pas.
Pour remédier à ce problème, on peut utiliser l’attribut _frameLeft
vu précédemment. Dans l’exemple 2, les sprites ne font plus que 20
pixels de large, et la détection de collision fonctionne comme
attendu.
Toutefois, la méthode intersect
ne suffit pas si le sprite est mis à
l’échelle, voire tourné : si on ajoute car.scale(2,2);
dans
l’exemple, la détection se basera toujours sur un sprite de 20×32 et
non 40×64. Dans ce cas, il faut utiliser la méthode intersectStrict
qui prend en compte cette mise à l’échelle ainsi que les rotations,
mais qui bien évidemment, prend plus de temps à calculer.
Quoi qu'il en soit, dans les deux cas (intersect
et
intersectStrict
), le problème des sprites ronds reste présent. Dans
ce cas, il faut utiliser la méthode within
qui en plus du sprite
prend un paramètre distance
. La collision est alors détectée si
entre les deux sprites la distance entre les deux centres est
inférieure à ce paramètre.
Dans le troisième exemple, on a des sprites ronds, et pour détecter la
collection, on utilise la somme des rayons comme distance :
player.within(someItem, 8*(someItem.scaleX+1))
(le rayon de player
étant 8, celle des items 8*someItem.scaleX
). On peut donc se
déplacer à l’intérieur des carrés rouges du mode debug tant que l’on
ne touche pas les ronds.
D'autres exemples de jeux
Avec tout ça, on peut faire pas mal de jeux différents sur une même base : on déplace un sprite sur une ligne horizontale, en évitant/récoltant d’autres sprites.
À part action
et rpg
(on verra les map
la prochaine fois), les
jeux dans le dossier examples/expert
d’enchant.js sont tous
identiques : des bonus/malus qui se déplacent (on
incrémente/décrémente des positions dans enterframe
), le joueur qui
peut bouger (touchstart/touchmove
), et on enlève des
sprites/augmente le score lors d’une collision entre des sprites
(intersect
).
La différence par exemple, entre goingup et twolanes est vraiment très petite : dans le premier, un ours qui doit éviter des murs ; dans le second, des voitures qui doivent récupérer des pièces et éviter des bombes. Hormis les sprites, et l’ajout de bonus et d’explosion, les deux jeux sont en fait identiques et ne sont pas non plus très différents de l’exemple 2 qu’on a vu plus haut.
Plein d’autres exemples de jeux sont disponibles sur http://9leap.net/ (on peut également ajouter les siens). Et avec tout ce qu’on connait maintenant, on peut reproduire des jeux comme http://r.jsgames.jp/games/2727/, http://r.jsgames.jp/games/382/, http://r.jsgames.jp/games/3147/, http://r.jsgames.jp/games/416/, http://9leap.net/games/1092, http://9leap.net/games/744, ou encore des othello/reversi, démineurs, sudokus…
Au prochain épisode on verra comment construire facilement des cartes pour faire des jeux à la mario ou à la zelda.