Ce court article va vous expliquer ce qu'est une collision en flash, comment les détecter et dans quel cadre les utiliser. Vous devez disposer du flash player 7 pour pouvoir visualiser les animations. Il est disponible sur le site de Macromedia.
Une collision de deux Movie Clip en flash se produit lorsque ceux-ci se rencontrent. Il suffit que l'un des pixels d'un movie clip rencontre un pixel appartenant à l'autre movie clip pour provoquer une collision.
Les collisions sont principalement utilisées dans les jeux. Tous les jeux de balles s'y prêtent bien. Les jeux consistant à tirer sur certaines cibles aussi. Dans les exemples qui vont suivre, je vais d'ailleurs vous montrer comment détecter si un « vaisseau ennemi » a été touché ou non.
Il existe plusieurs méthodes pour détecter une collision. La plus précise mais certainement la plus complexe aussi consiste à utiliser des calculs mathématiques. Ceci est surtout nécessaire lorsque l'on désire connaître l'angle de la collision. Une autre méthode, beaucoup plus simple consiste à utiliser une fonction flash prévue à cet effet. C'est l'utilisation de cette fonction que nous allons aborder. Cette fonction ne permet malheureusement pas de déterminer un quelconque angle de collision.
Cliquez au sein de l'animation pour lui donner le focus et bougez le cercle à l'aide des flèches et allez à la rencontre du carré.
Cliquez pour lire la vidéo
Flash n'est pas installé, Flash n'est pas à jour 7.0.0, cliquez sur l'image ci-dessous.
Dans cet exemple simple, nous avons deux movie clip, un cercle et une barre verticale. Nous désirons simplement savoir si le cercle a touché la barre verticale ou non.
Note: comme vous l'aurez certainement constaté, la détection de la collision dans cet exemple n'est pas parfaite, ceci est dû au fait que le cercle est englobé dans un MC carré. Donc lorsqu'une des extrémités du carré touche la barre, flash détecte une collision même si le cercle ne l'a pas touché. Pour éviter cela, soit vous devez préférer une autre méthode de détection, soit ne travailler qu'avec des formes géométriques se rapprochant le plus possible d'un carré ou d'un rectangle.
Le cercle est nommé « mc1 » et la barre « mc2 ». Voici le code nécessaire pour réaliser cette animation :
mc1.xMin=mc1._x;
mc1.xMax=mc1._x+300;
mc1.yMin=mc1._y-150;
mc1.yMax=mc1._y+150;
mc1.onEnterFrame=function()
{
//On détecte si l'une des flèches est enfoncée et on fait bouger le cercle
//si celui-ci est dans les limites _x _y autorisées.
if(Key.isDown(Key.RIGHT) && this._x<this.xMax)
{
this._x+=10;
}
if(Key.isDown(Key.LEFT) && this._x>this.xMin)
{
this._x-=10;
}
if(Key.isDown(Key.UP) && this._y>this.yMin)
{
this._y-=10;
}
if(Key.isDown(Key.DOWN) && this._y<this.yMax)
{
this._y+=10;
}
}
mc2.onEnterFrame=function()
{
Collision.text="";
//hitTest permet de détecter si un clip "clip" est entré en collision avec le clip
//courant. Dans ce cas, nous testons si mc1 est entré en collision avec "this" c'est-à-dire mc2.
if(mc1.hitTest(this))
{
Collision.text="Collision détectée";
}
}
Le but du jeu est simple, c'est le classique jeu de fusée auquel on jouait quand on était petit :)). Des vaisseaux ennemis tentent d'atteindre le bas de l'écran. Vous devez tirer dessus pour les en empêcher, si l'un d'entre eux parvient à atteindre le bas de l'écran vous perdez. Ce petit jeu illustre bien l'utilisation de « hitTest() » et la détection de collision.
Du point de vue technique, nous avons deux MC chargés statiquement, il s'agit de la fusée et du clip qui gère les vaisseaux ennemis. Les flèches de gauche et droite servent à déplacer la fusée et la barre d'espace à tirer sur les vaisseaux. Vous pouvez la maintenir enfoncée pour envoyer une série de balles.
Nous devons donc gérer :
les flèches du clavier ;
la barre d'espace ;
l'envoi automatique de vaisseaux ennemis ;
détecter si une balle touche un vaisseau ennemi et supprimer celui-ci ;
détecter si un vaisseau ennemi a atteint le bas de l'écran auquel cas, le joueur perd.
Cliquez pour lire la vidéo
Flash n'est pas installé, Flash n'est pas à jour 7.0.0, cliquez sur l'image ci-dessous.
//tableau contenant le nom des instances ennemies
ennemi=new Array();
//Compteur pour les balles
fusee.currentItem=0;
//code exécuté en boucle pour la fusée
fusee.onEnterFrame=function()
{
//Gestion du déplacement gauche-droite
if(Key.isDown(Key.LEFT))
{
this._x-=50;
}
if(Key.isDown(Key.RIGHT))
{
this._x+=50;
}
//La touche espace déclenche un tir
if(Key.isDown(Key.SPACE))
{
//On ajoute le clip sur la scène et on le positionne
_root.attachMovie("bullet","bullet"+this.currentItem,100+this.currentItem);
_root["bullet"+this.currentItem]._x=this._x+25;
_root["bullet"+this.currentItem]._y=this._y-30;
//En boucle, la balle va vers le haut de l'écran
//et on regarde si on touche un ennemi
_root["bullet"+this.currentItem].onEnterFrame=function()
{
if(this._y<0) this.removeMovieClip();
//Ennemi est un tableau associatif contenant le
//nom d'instance de tous les ennemis envoyés
//On parcourt le tableau pour voir si on touche
//un des ennemis ou non
for(value in ennemi)
{
//hittest détecte la collision
if(_root[value].hitTest(this))
{
//ici, la collision est détectée
//Suppression du vaisseau ennemi
_root[value].removeMovieClip();
//suppression de la clé dans le tab. assoc.
delete(_root.ennemi[value]);
//Suppression de la balle
this.removeMovieClip();
}
}
this._y-=45;
}
this.currentItem++;
}
}
//Ennemis est le MC qui va envoyer les ennemis
//tout au long de l'animation à raison de 1 ennemi par sec.
ennemis.timeStarted=getTimer()/1000;
ennemis.interval=1;
ennemis.item=1;
ennemis.onEnterFrame=function()
{
if((getTimer()/1000) > (this.timeStarted+this.interval))
{
//si l'intervalle est écoulé, on envoie un nouvel ennemi
_root.attachMovie("ennemi","ennemi"+this.item,200+this.item);
//On ajoute la clé dans le tab. assoc.
_root.ennemi["ennemi"+this.item]=1;
_root["ennemi"+this.item]._x=random(300);
//En boucle pour l'ennemi
_root["ennemi"+this.item].onEnterFrame=function()
{
//On le fait descendre de 10px
this._y+=10;
//Si _y > 300, on ne l'a pas touché et donc
//on a perdu
if(this._y>300)
{
this.removeMovieClip();
gotoAndStop(3);
}
}
this.item+=1;
this.interval+=1;
}
}
stop();
//Suppression des ennemis restant
for (value in ennemi)
{
_root[value].removeMovieClip();
}
//Code du bouton recommencer
recommencer.onPress=function()
{
gotoAndPlay(2);
}