Aller au menu - Aller au contenu

Icône Rotation 2D

Mise à jour : 13/01/2009
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-SA
110 visites depuis 7 jours , dont 14 sur ce chapitre , classé 546/777
Dans ce premier chapitre, on va apprendre à faire tourner un clip autour d'un point ; vous comprendrez plus tard comment on exploitera ce système pour passer à la 3D. :)
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Introduction

Pour ce chapitre et quelques-uns des autres, nous aurons besoin d'un clip simple.

Créez un nouveau clip (Insertion => Nouveau symbole ou Ctrl + F8).
Puis dessinez-y un cercle de 20 pixels de diamètre et déplacez celui-ci en (x:-10 ; y:-10) pour le centrer.
Puis dans la bibliothèque (Ctrl + L), faites un clic droit sur le clip que nous venons de créer, puis cliquez sur Liaison.
Cochez Exporter pour ActionScript et dans la case identifiant, donnez lui pour nom boule.

Voilà : on peut commencer.
Ici, notre but va être d'arriver à faire tourner un clip autour d'un point précis.
Pour cela, on va devoir définir les coordonnées du point central, puis définir un rayon, puis on utilisera les cosinus et sinus que nous avons vus au chapitre précédent pour positionner notre clip.

Positionner un clip sur un cercle

Bon : en tout premier lieu, nous allons voir comment positionner notre clip sur un cercle de rayon et de centre prédéfinis.
À savoir, à moins que je ne vous le précise, le code se situe sur la première image de la scène principale.

Par exemple, je vous propose de prendre comme point central un point A de coordonnées (100,100) et de choisir un rayon de 100.

Code : Actionscript
1
2
3
var centreX:Number = 100;
var centreY:Number = 100;
var rayon:Number = 100;


Avant de positionner notre clip, il serait judicieux de le créer, car si vous avez fait comme je vous l'ai dit, votre clip boule est présent dans la bibliothèque, mais pas sur la scène.
On va donc créer une occurrence de ce clip en utilisant la méthode MovieClip.attachMovie().

Code : Actionscript
1
2
3
var clip:MovieClip = this.attachMovie('boule','mc_boule',1);
// Je rappelle cette méthode : créer dans le clip désigné (ici : par 'this', soit la scène où il y a le code) une occurrence du clip de la bibliothèque ayant pour nom de liaison 'boule' ; ce clip aura pour nom d'occurrence 'mc_boule' et sera créé au niveau 1.
// La variable 'clip', elle, désigne le clip créé. En modifiant les propriétés du MovieClip 'clip', on modifiera donc ici les propriétés du clip 'mc_boule'.


Maintenant, il faut positionner le clip sur le cercle.
Pour cela, nous allons utiliser les cosinus et sinus vus dans le chapitre précédent. Nous allons donc avoir besoin d'une autre variable angle.
Code : Actionscript
1
2
3
4
5
var angle:Number = 0; // Pour le début, prenons un angle nul. ^^
clip._x = Math.cos(angle);
clip._y = Math.sin(angle);
trace(clip._x) // On affiche la valeur de l'abscisse de notre clip.
trace(clip._y) // Même chose pour l'ordonnée.

Si vous avez bien lu le chapitre précédent, vous devriez comprendre sans problème pourquoi s'attribuent à l'abscisse de mon clip un cosinus et à son ordonnée un sinus ; si ce n'est pas le cas, vous devriez aller le relire plus attentivement.

Testez votre code : Ctrl + Entrée.
...
...
Si tout se déroule correctement, vous devriez avoir dans la fenêtre de sortie le message suivant :
Citation : Sortie
1
0

Apparemment notre clip n'est pas bien placé. Il devrait se trouver à 100 pixels de notre centre de coordonnées (100,100).
En fait, c'est tout à fait normal : souvenez-vous, un cosinus et un sinus sont compris entre -1 et 1, donc quelle que soit la valeur de l'angle, notre clip sera toujours très proche de (0,0), qu'il prend actuellement comme centre.
Pour modifier le centre, nous allons déjà additionner les coordonnées de notre centre aux coordonnées actuelles de notre clip.
Puis nous allons multiplier notre cosinus et notre sinus par la valeur du rayon choisi.
Cela nous donne donc :
Code : Actionscript
1
2
3
4
5
var angle:Number = 0;
clip._x = centreX + Math.cos(angle)*rayon;
clip._y = centreY + Math.sin(angle)*rayon;
trace(clip._x)
trace(clip._y)

Citation : Sortie
200
100

Ah ! Eh bien ça marche :) , notre clip est bien situé à 100 pixels du centre.
Mais ne nous réjouissons pas non plus trop vite, ce n'est pas parce que notre code marche pour un angle précis qu'il est exact.
On a peut-être aussi fait n'importe quoi et on est tombé sur un résultat cohérent par un coup de chance. ^^

Mais on peut vérifier tout ça : par exemple, modifions la valeur de la variable angle sur \pi :
Code : Actionscript
1
var angle:Number = Math.PI;

Pour ceux qui se demandent pourquoi \pi, je leur rappelle que les méthodes Math.sin() et Math.cos() doivent recevoir en paramètre un angle en radians, et que \pi \, radians correspond à un angle de 180° ; donc, si tout se passe bien, notre clip devrait se retrouver de l'autre côté du centre.


Alors ? Les coordonnées de notre clip sont bien (0,100) ? Si oui, notre clip a l'air de bien fonctionner.
Vous pouvez faire d'autres tests avec d'autres angles si vous voulez mais bon, comme en théorie notre algorithme est correct et comme en pratique il semble bien marcher, on va dire que c'est bon. ^^

Avant d'aller plus loin, je vais vous demander de faire un choix : soit ça ne vous dérange pas de manipuler des angles en radians (pour une raison ou pour une autre ^^ ), soit vous êtes plus à l'aise avec les degrés (c'est en général le cas).
Dans le deuxième cas, je vous conseille d'utiliser la fonction que je vous ai fait créer dans le chapitre précédent :
Code : Actionscript
1
2
3
function conversion_radians(degre:Number):Number{
    return degre/180*Math.PI;
}


Avec cette fonction, ces deux lignes deviennent équivalentes :
Code : Actionscript
1
2
var angle:Number = Math.PI; // ici Math.PI radians
var angle:Number = conversion_radians(180); // ici 180 degrés convertis en Math.PI radians


Voilà : on peut maintenant passer à la prochaine étape, on va mettre notre clip en mouvement sur le cercle.

Mise en mouvement

On va donc créer une fonction qui va modifier la valeur de la variable angle.
Puis on va repositionner notre clip en fonction de cette nouvelle valeur.

Je vous propose d'utiliser l'évènement MovieClip.onEnterFrame() qui va exécuter notre fonction en boucle :
Code : Actionscript
1
2
3
4
5
this.onEnterFrame = function(){
    angle = angle + conversion_radians(5);  // on augmente la valeur de la variable 'angle'
    clip._x = centreX + Math.cos(angle)*rayon; // on repositionne le clip
    clip._y = centreY + Math.sin(angle)*rayon;
}


Allez, on passe tout ça à la moulinette : Ctrl + Entrée.
Votre clip devrait réaliser une jolie courbe autour du point de coordonnées (100,100).
Si ce n'est pas le cas, vérifiez votre code ligne par ligne pour trouver votre erreur (s'il y a une ligne que vous ne comprenez pas, revenez à la partie du tuto qui la traite, et relisez bien les commentaires que j'y ai fait).
Je ne vous donne volontairement pas le récapitulatif du code pour que vous vous entraîniez à la recherche de "bogues" sur un exemple simple : c'est une compétence indispensable dans la programmation, car tout le monde (même les meilleurs) font des erreurs (que ce soit une erreur d'algorithme ou une simple faute de frappe).

Si votre animation est saccadée, c'est dû au fait que l'évènement onEnterFrame() se base sur la fréquence de votre animation (le nombre d'images par seconde). Vous pouvez aller la modifier dans : Modification => Document (ou Ctrl + J) et modifier la cadence (à 25 images par seconde environ).

Autre méthode

Notre code marche, mais il a un gros défaut.
En effet pour faire tourner un seul clip, nous avons besoin de 2 variables, celle qui contient le rayon et celle qui contient l'angle.
Donc si nous voulons ajouter d'autres clips, nous allons devoir utiliser d'autres variables, et vous vous en doutez, ce n'est pas l'idéal.

Nous allons voir une autre manière pour réaliser les mêmes actions, celle-ci est un peu plus difficile d'utilisation, mais a l'avantage de ne pas mobiliser de variables, ce qui simplifiera notre code par la suite.

En fait, dans notre premier algorithme, on augmente (ou diminue) la valeur de la variable angle, puis on recalcule les coordonnées.
Dans notre nouvel algorithme, nous allons calculer les nouvelles coordonnées de notre clip sans connaître la valeur de l'angle, ni le rayon de départ.
Bon : c'est un peu flou mais, comme toujours, je vais vous expliquer tout ça en détails.

Supposons le schéma suivant : notre clip se trouve au point B, mais l'angle $a$ nous est inconnu :
Angle inconnu.
Nous savons que les coordonnées du point $B \, sont \, (\cos{(a)},\sin{(a)})$.
Si maintenant nous voulons augmenter l'angle a de 5 degrés par exemple pour faire tourner notre clip.
Nous obtiendrons un point $B'$ de coordonnées $(\cos{(a+5)},\sin{(a+5)})$.

Or, souvenez-vous du chapitre sur la trigonométrie, à la fin je vous ai donné 2 formules à apprendre :
  • \cos{(a+b)} \, = \, \cos{(a)}*\cos{(b)}-\sin{(a)}*\sin{(b)}
  • \sin{(a+b)} \, = \, \sin{(a)}*\cos{(b)}+\cos{(a)}*\sin{(b)}

Si on les applique à notre exemple, on obtient donc :
  • \cos{(a+5)} \, = \, \cos{(a)}*\cos{(5)}-\sin{(a)}*\sin{(5)}
  • \sin{(a+5)} \, = \, \sin{(a)}*\cos{(5)}+\cos{(a)}*\sin{(5)}

Et si l'on regarde bien les formes obtenues, on remarque qu'aucune valeur ne nous est inconnue ; en effet :
  • nous pouvons très facilement obtenir la valeur du cosinus et du sinus de 5 ;
  • la valeur du cosinus et du sinus de $a$ correspond à l'abscisse et l'ordonnée de notre point B.

Nous avons donc gagné, nous avons déterminé les coordonnées du point B' uniquement avec les coordonnées du point B et de l'angle qui sépare nos deux points (5 degrés dans notre exemple).

Passons maintenant à l'application en ActionScript.
Nous allons créer une fonction qui recevra en paramètre l'angle de rotation, puis nous allons calculer les nouvelles coordonnées de notre clip, et enfin nous allons appliquer ces nouvelles valeurs à notre clip.
Code : Actionscript
1
2
3
4
5
6
7
8
function rotation(angle:Number):Void{
    var cosAngle:Number = Math.cos(conversion_radians(angle));
    var sinAngle:Number = Math.sin(conversion_radians(angle));
    var newX:Number = clip._x*cosAngle-clip._y*sinAngle;
    var newY:Number = clip._y*cosAngle+clip._x*sinAngle;
    clip._x = newX;
    clip._y = newY;
}


À ce niveau, si vous testez l'animation (déjà, le clip devrait tourner ; si ce n'est pas le cas, revérifiez votre code et relisez le chapitre ^^ ), vous devriez remarquer que le clip prend pour centre le point de coordonnées (0,0) ; or nous, nous voulons que la rotation soit effectuée autour du point de coordonnées (100,100).
Pour cela, nous allons devoir ajouter les coordonnées du centre à celles de notre clip.
Mais, une chose importante : nous allons aussi devoir les soustraire, lors du calcul des nouvelles coordonnées, pour que les formules restent cohérentes.
Nous obtiendrons le code suivant :
Code : Actionscript
1
2
3
4
5
6
7
8
function rotation(angle:Number):Void{
    var cosAngle:Number = Math.cos(conversion_radians(angle));
    var sinAngle:Number = Math.sin(conversion_radians(angle));
    var newX:Number = (clip._x-centreX)*cosAngle-(clip._y-centreY)*sinAngle;
    var newY:Number = (clip._y-centreY)*cosAngle+(clip._x-centreX)*sinAngle;
    clip._x = centreX+newX;
    clip._y = centreY+newY;
}

Code : Actionscript
1
2
3
this.onEnterFrame = function(){
        rotation(5) // 5 en degrés, la conversion en radians est faite dans notre fonction.
}


Voilà, les variables rayon et angle ne nous sont plus utiles, nous pouvons donc les supprimer :
var rayon:Number = 100
var angle:Number = 0


Une dernière petite modification : si nous supprimons ces variables, nous ne pouvons plus les utiliser lors du 'placement' initial de notre clip.
Nous allons le faire manuellement, de façon à ce qu'il soit à 100 pixels de notre point de centre :
Code : Actionscript
1
2
clip._x = centreX + 100;
clip._y = centreY + 0;


Voilà : nous en avons terminé pour ce chapitre ; pour ceux qui se seraient emmêlé les pinceaux, je mets à votre disposition un récapitulatif du code mais pour votre formation, je vous conseille fortement de chercher un peu par vous-mêmes vos erreurs.
Dans la vie courante, on n'a pas tout le temps un gentil tutoriel à sa disposition. ^^

Secret (cliquez pour afficher)
Code : Actionscript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function conversion_radians(degre:Number):Number{
    return degre/180*Math.PI;
}
function rotation(angle:Number):Void{
    var cosAngle:Number = Math.cos(conversion_radians(angle));
    var sinAngle:Number = Math.sin(conversion_radians(angle));
    var newX:Number = (clip._x-centreX)*cosAngle-(clip._y-centreY)*sinAngle;
    var newY:Number = (clip._y-centreY)*cosAngle+(clip._x-centreX)*sinAngle;
    clip._x = centreX+newX;
    clip._y = centreY+newY;
}
var centreX:Number = 100;
var centreY:Number = 100;
var clip:MovieClip = this.attachMovie('boule','mc_boule',1);
clip._x = centreX + 100;
clip._y = centreY + 0;
this.onEnterFrame = function(){
        rotation(5)
}
Vous connaissez maintenant deux méthodes pour faire tourner un clip autour d'un point.
Dans la suite du tuto, du fait que nous aurons plusieurs points à gérer, nous utiliserons toujours la seconde méthode.

Allez, à la suite. ^^
Chapitre précédent Sommaire Chapitre suivant

Partager

1 commentaire pour "Rotation 2D"
Note moyenne : 3.40 / 4 (5 votes)
Pseudo Commentaire
Hors ligne kaham # Posté le 30/03/2008 à 03:07:58

Sa va pour le moment l'ActionScript n'est pas trop poussé :D . Ce ne sont que des variables et des coordonnées. Si sa reste comme sa jusqu'à la fin du tutoriel je vais pouvoir suivre. :p

Voir tous les commentaires
Ce tutoriel a été corrigé par les zCorrecteurs.