Sous ce titre à priori fort peut explicite, se cache une astuce qui permet de réaliser des collisions entre un clip dont on connaît la forme complexe à l'avance, et un autre clip à la forme complexe. Oui, oui, vous avez bien entendu, on va réaliser le calcul de collision entre deux formes complexes.
En fait, l'astuce est toute simple, on va prendre des points importants de notre clip
boite (ça sera les quatres coins, en toute logique), et on va effectuer un test de collision entre
obstacle_circulaire et chacun des points !

Si je dis que c'est bourrin, c'est parce que, pour 4 points ce n'est pas bien lourd, mais avec des formes vraiment complexes, vous arriverez à des tests de plusieurs dizaines de points, ce qui risque de faire nettement flancher la fluidité de l'animation.
Vous allez donc créer un clip
point représenté par un petit cercle rouge de 2 ou 3 pixels. Vous ne placerez pas ce clip sur la scène principale, mais
dans le clip
boite. Vous copierez-collerez ce clip 3 fois, pour en placer un à chaque coin. Vous nommerez ces clips :
point_1, point_2, point_3, et
point_4.
On va donc changer le code précédent, qui gérait la collision entre le centre de
boite et la forme de
obstacle_circulaire.
On va seulement changer ce qu'il faut pour que la collision s'effectue entre
point_1 et la forme de
obstacle_circulaire.
Ce qui nous donne :
Code : Actionscript | if (_root.obstacle_circulaire.hitTest(this.point_1._x,this.point_1._y,true)) {
this._x = posx;
this._y = posy;
}
|
Testez l'animation.

Pourquoi ça ne marche pas ?
Eh bien en fait, la question à se poser est : quelles sont les coordonnées de
point_1 ?
Dans la mesure où le référentiel dans lequel on se trouve est
boite, on aura donc les coordonnées de
point_1 par rapport à
boite. Ce qui pose un problème, car dans ce cas, les coordonnées restent toujours les mêmes, soit (-12;-12), car
point_1 ne change pas de position par rapport à
boite.
Il faut donc convertir ces coordonnées pour qu'elles correspondent aux coordonnés de
point_1 dans
_root.
Pour cela je vais vous présenter deux solutions.
Un peu de géométrie
Voilà un schéma tout simple, qui va vous aider à comprendre.
Si on est dans le référentiel
boite, alors les coordonnées de point_1 sont :
this.point_1._x
this.point_1._y (avec
this qui correspond à
boite);
Mais si on veut ces mêmes coordonnées dans le référentiel
_root, il faut ajouter les coordonnées de
boite :
this.point_1._x + this._x
this.point_1._y + this._y (avec
this qui correspond à
boite);
Bref, le code donnerait :
Code : Actionscript | vrai_x = this.point_1._x+this._x;
vrai_y = this.point_1._y+this._y;
if (_root.obstacle_circulaire.hitTest(vrai_x,vrai_y,true)) {
this._x = posx;
this._y = posy;
}
|
Et ça fonctionne très bien.
Un peu d'ActionScript
Si vous ne voulez pas vous embêter à réfléchir en dessinant des petits schémas, Flash vous offre une fonction qui va faire le travail pour vous :
localToGlobal()
Cette méthode de la classe
MovieClip permet de convertir des coordonnées locales d'un clip vers des coordonnées globales avec
_root comme référentiel, et ça, quelque soit le clip de départ. L'avantage est donc que cette méthode fonctionne dans tous les cas.
Voilà comment l'utiliser :
Code : Actionscript | var un_point:Object = new Object(); // On créé un objet quelconque
un_point.x = this.point_1._x; // On donne à cet objet des propriétés x et y
un_point.y = this.point_1._y;
|
Il faut tout d'abord créer un objet quelconque comme ci-dessus, et initialiser deux propriétés :
x et
y (et non pas _x et _y).
Ensuite, la fonction
localToGlobal() va travailler un peu :
Code : Actionscript | this.localToGlobal(un_point);
|
On précise avec
this quel était le référentiel local de départ ; ici, il s'agit de
boite : or, vu qu'on est dans un bloc de code lui appartenant, on utilise
this.
Entre les parenthèses, on indique juste l'objet portant les propriétés
x et
y, qui doit être converti.
Et c'est tout.
Si on adapte ça à notre cas, on arrive à :
Code : Actionscript | var un_point:Object = new Object();
un_point.x = this.point_1._x;
un_point.y = this.point_1._y;
this.localToGlobal(un_point);
if (_root.obstacle_circulaire.hitTest(un_point.x,un_point.y,true)) {
this._x = posx;
this._y = posy;
}
|
Comme vous pouvez le voir, c'est plus long. Mais le problème avec l'autre méthode, c'est que quand on cherche les coordonnées globales d'un clip, lui même dans un clip, qui est lui même dans un clip .. ça devient difficile.

Alors que là tout se fait automatiquement.
Les 3 autres points
Bon, on va donc garder la seconde méthode. Mais maintenant vous savez tout ! Alors, un peu à vous de travailler ! Il faut adapter le code précédent pour que la vérification s'effectue sur
les 4 points ! Il faudra bien entendu utiliser une boucle et ce qu'on a vu
ICI.
Correction :
Secret (cliquez pour afficher)Code : Actionscript 1
2
3
4
5
6
7
8
9
10
11
12 | for (i=1; i<=4; i++) { // Boucle de 1 à 4 compris
// Conversion des coordonnées
var un_point:Object = new Object();
un_point.x = this['point_'+i]._x;
un_point.y = this['point_'+i]._y;
this.localToGlobal(un_point);
// Test de collision
if (_root.obstacle_circulaire.hitTest(un_point.x,un_point.y,true)) {
this._x = posx;
this._y = posy;
}
}
|
Et voilà, maintenant la méthode bourrin n'a plus de secret pour vous.
