Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
1) Voilà, tous les éléments on été créés, il ne nous reste plus qu'à nous attaquer à la partie la plus 'difficile' de ce tuto : le code.
En effet, nous n'allons pas créer un véritable moteur 3D (ce qui, entre nous, est au-delà de mon niveau

) mais plutôt d'en simuler un.
Tout notre code sera placé sur la première image du scénario de la scène principale.
2) On commence par créer quelques variables sur lesquelles va se baser notre animation.
Code : Autre1
2
3
4
5
6
7
| var profondeur:Number = 1000;
var largeur:Number = 200; // ou Stage.width
var hauteur:Number = 200; // ou Stage.height
var centre_x:Number = 100; // ou largeur/2
var centre_y:Number = 100; // ou hauteur/2
var frein:Number = 5;
var interval:Number; |
Ici on veut que l'animation prenne toute la taille du document, et que son centre soit aussi le centre de notre document.
Je vous rappelle que sur la scène principale, le point de coordonnées (0;0) est le coin supérieur-gauche de votre document.
La variable 'profondeur' va être l'une des bases les plus importantes de notre 'simulation' d'effet 3D.
Nous verrons plus tard l'utilité de la variable 'frein' (qui ne porte pas ce nom par hasard vous vous en doutez

).
3) On crée une liste de noms, vous pouvez les remplacer par n'importe quoi bien évidemment (ce seront les mots qui apparaîtront dans les cercles) :
Code : Autre1
| var tab_nom_1:Array = new Array("1","2","3","4","5","6","7","8","9","10"); |
4) Maintenant nous allons créer une fonction qui crée et place nos occurrences (les copies) du clip 'cercle' de la bibliothèque :
on crée la fonction 'creer_btns' à laquelle on passe 2 paramètres.
Le premier, 'chem1' sera l'adresse du clip conteneur de notre animation, dans notre exemple celle-ci aura pour valeur '_root' c'est-à-dire la racine de notre animation.
Le deuxième 'tab_nom' est un tableau contenant des noms (comme son nom l'indique

).
Code : Autre1
2
3
| function creer_btns(chem1:MovieClip, tab_nom:Array):Void {
// les instructions de la fonction
} |
Note : En programmation, il faut toujours essayer de nommer les variables judicieusement, pour qu'au premier coup d'?il on sache vaguement ce qu'elles contiennent, ainsi notre variable 'tab_nom' est le diminutif de 'tableau_de_noms', ce qui se passe d'explications.
Ensuite on crée une boucle 'For' qui va créer autant de clips que de lignes dans le tableau 'tab_nom' (pour obtenir le nombre de lignes on utilise la méthode : monTableau.length).
Code : Autre1
2
3
4
| var taille:Number = tab_nom.length
for (var i:Number=0 ; i<taille ; i++) {
// mes instructions
} |
On va maintenant créer une variable qui nous servira à contenir le niveau de notre clip, celle-ci contiendra un nombre entre 1 et la valeur de la variable 'profondeur' (1000 dans notre cas).
Pour cela on utilise la méthode 'Math.random()' qui nous renvoie un nombre à virgule entre 0 et 1 que l'on multiplie par la valeur de la variable 'profondeur'. Et pour obtenir un nombre entier on utilise la méthode 'Math.round()' qui arrondit notre nombre à l'entier le plus proche.
Code : Autre1
| var var_profondeur:Number = Math.round(Math.random()*profondeur); |
On crée un clip 'conteneur' vide, que l'on nomme en fonction de 'i' (si i=0 le clip sera nommé 'clip0', si i=1 => 'clip1' etc...)
Code : Autre1
| chem1.createEmptyMovieClip("clip"+i, var_profondeur); |
Note : On remarque l'utilisation de 'chem1.' avant l'utilisation de la méthode de création du clip, cela signifie que l'on veut que le clip soit créé à l'intérieur du clip 'chem1' qui je vous le rappelle est l'un des paramètres envoyés à la fonction (dans notre cas ce sera '_root').
Lors de la création dynamique de plusieurs clips en fonction d'une variable, la modification des propriétés de ceux-ci nécessite de connaître leur nom. Ce qui à première vue n'est pas si facile que ça.
Ex : Soient plusieurs clips "clip+i", si i=5, on veut donc travailler uniquement sur le clip 'clip5', il est bien évident que l'on ne peut pas écrire "clip"+i._x (_x retourne l'abscisse du clip). Pour cela on utilisera la syntaxe suivante : clipConteneur["clip"+i]. En lisant cette ligne Flash travaillera sur un seul et unique clip (si i=5 alors il traduira cette ligne par clipConteneur.clip5).
Mais cette notation est lourde, pour simplifier l'écriture du code on va donc créer une variable raccourci :
Code : Autre1
| var chem2:MovieClip = chem1["clip"+i]; |
On va maintenant créer plusieurs variables incluses dans chaque clip.
Les 2 premières sont les positions verticale et horizontale des clips quand ils seront au premier plan, on veut donc une valeur entre -largeur/2 et +largeur/2 (idem avec la variable 'hauteur').
Pourquoi ne pas prendre une valeur entre 0 et 'largeur' pour faire plus simple ?
C'est une simple question de représentation mentale, souvenez-vous on a défini un centre (avec les variables centre_x et centre_y) on calcule donc les coordonnées des clips en fonction de ce centre.
On doit aussi enregistrer la profondeur du clip (puisque l'on aura besoin de la récupérer pour la faire varier).
Enfin, la dernière nous sert juste à enregistrer la valeur actuelle de 'i' (elle nous sera utile pour récupérer les valeurs des variables du clip sur lequel on a cliqué).
Code : Autre1
2
3
4
| chem2.var_x = Math.round(Math.random()*largeur-largeur/2);
chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2);
chem2.var_niv = var_profondeur;
chem2.i = i; |
Enfin on positionne le clip en fonction du centre et de ses coordonnées calculées plus haut.
Code : Autre1
2
| chem2._x = centre_x+chem2.var_x;
chem2._y = centre_y+chem2.var_y; |
Maintenant que l'on a créé les variables et positionné le clip, il faut le remplir avec quelque chose (puisque voir se déplacer des clips vides, entre nous, c'est un peu difficile

).
On va donc y attacher le clip 'cercle' créé à l'étape 2, ainsi qu'un champ texte, dans lequel on va écrire la valeur de la ligne 'i' du tableau 'tab_nom' (qui je vous le rappelle contient des noms).
Code : Autre1
2
3
4
| chem2.attachMovie("cercle", "cercle", 1);
chem2.createTextField("texte", 2, -10, -10, 20, 20);
chem2.texte.text = tab_nom[i];
chem2.texte.selectable = false; |
Bon les clips sont créés, mais il ont tous la même taille (logique ce sont des copies parfaites) et vous serez (j'espère) d'accords avec moi que pour donner un effet d'éloignement ce n'est pas le top

.
On va donc arranger cela en modifiant les propriétés '_xscale' et '_yscale' des clips (elles modifient le % de la taille, par défaut elle sont à 100(%)).
Code : Autre1
2
| chem2._xscale = Math.ceil(chem2.var_niv/(profondeur/100));
chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100)); |
Note : 'chem2.var_niv' varie entre 0 et la valeur de la variable profondeur, il faut donc diviser cette valeur par profondeur/100 pour obtenir une valeur entre 0 et 100.
Maintenant il reste une étape à initialiser, c'est les actions à exécuter quand on clique sur le clip :
On déplace la tête de lecture de ce clip sur la deuxième image (le cercle à fond rouge dans notre cas).
Puis on supprime la temporisation que désigne la variable 'interval' pour éviter de créer 2 fois une même temporisation (ce qui aurait pour effet de doubler la fréquence d'exécution de la fonction temporisée).
Puis on recrée une temporisation de la fonction 'deplacement' toutes les 40 millisecondes à laquelle on envoie 3 paramètres ('chem1' pour l'adresse du clip conteneur; Le numéro d'index du clip sur lequel on a cliqué; et enfin la taille du tableau 'tab_nom', soit le nombre de clips).
Code : Autre1
2
3
4
5
| chem2.onRelease = function():Void{
this.cercle.gotoAndStop(2);
clearInterval(interval);
interval = setInterval(deplacement,40,chem1,this.i,tab_nom.length);
}; |
Récapitulatif de la fonction créée :
Secret (cliquez pour afficher)Code : Autre1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| function creer_btns(chem1:MovieClip, tab_nom:Array) {
var taille:Number = tab_nom.length
for (var i:Number=0 ; i<taille ; i++) {
var var_profondeur:Number = Math.round(Math.random()*profondeur);
var chem2:MovieClip = chem1.createEmptyMovieClip("clip"+i, var_profondeur);
chem2.var_x = Math.round(Math.random()*largeur-largeur/2);
chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2);
chem2.var_niv = var_profondeur;
chem2.i = i;
chem2._x = centre_x+chem2.var_x;
chem2._y = centre_y+chem2.var_y;
chem2.attachMovie("cercle", "cercle", 1);
chem2.createTextField("texte", 2, -10, -10, 20, 20);
chem2.texte.text = tab_nom[i];
chem2.texte.selectable = false;
chem2._xscale = Math.ceil(chem2.var_niv/(profondeur/100));
chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
chem2.onRelease = function():Void{
this.cercle.gotoAndStop(2);
clearInterval(interval);
interval=setInterval(deplacement,40,chem1,this.i,tab_nom.length);
};
}
} |
5) On crée une deuxième fonction prévue pour être exécutée en boucle pour simuler notre effet 3D : la fonction 'deplacement'.
On a vu dans la fonction 1 que l'on avait besoin d'envoyer 3 paramètres importants à la fonction 'deplacement', il faut donc créer des variables réceptrices.
Code : Autre1
2
3
| function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void {
// instructions
} |
La première étape consiste à récupérer le chemin pour accéder aux variables du clip sur lequel on a cliqué, pour cela aucun problème puisque l'on a pensé à envoyer la valeur de la variable 'i' du clip sur lequel on a cliqué.
Code : Autre1
| var chem1:MovieClip = chem["clip"+var_i]; |
À ce niveau une petite vérification s'impose, il faut regarder si le clip est arrivé au premier plan, c'est-à-dire que son niveau est maximal. Si c'est le cas on supprime la temporisation 'interval'.
Code : Autre1
2
3
4
5
| if (chem1.var_niv != profondeur) {
// instruction
} else {
clearInterval(interval);
} |
Si le clip sur lequel on a cliqué n'est pas au premier plan alors il faut déplacer tous les clips, pour cela je vous propose de créer un effet de vitesse qui ralentit.
Je m'explique, on calcule la distance restante à parcourir, puis on demande au clip d'en parcourir la moitié.
À la prochaine exécution de la fonction on lui demande de faire pareil, mais comme la distance qu'il restera à parcourir a été divisée par 2 le clip avancera 2 fois moins vite, et ainsi de suite.
Si on applique cette méthode telle quelle, le clip n'arrivera jamais à destination, en effet il parcourra toujours la moitié de la distance restante, pour palier à ce petit problème de logique mathématique (qui peut donner mal à la tête

) on utilisera la méthode 'Math.ceil()' qui nous renvoie l'arrondi supérieur.
Le déplacement du clip se fera donc toujours d'un nombre entier, et quand la distance restante sera inférieure à 1 alors le clip arrivera à la position finale.
C'est ici qu'apparaît l'utilité de la variable 'frein', c'est elle qui va fixer le % de chemin restant à parcourir. (frein=2, la moitié; frein=3, le tiers, etc...)
Code : Autre1
2
3
| var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein);
var vitesse_x:Number = Math.ceil(chem1.var_x/frein);
var vitesse_y:Number = Math.ceil(chem1.var_y/frein); |
Une fois les vitesses calculées, il faut modifier les variables et les propriétés des clips, on crée donc une boucle 'For' pour traiter tous les clips (le nombre de clips est contenu dans la variable 'nbr').
Code : Autre1
2
3
| for (var i:Number=0 ; i<nbr ; i++) {
// instructions
} |
On édite les variables des clips (on crée aussi un autre raccourci toujours pour simplifier l'écriture du code).
Code : Autre1
2
3
4
| var chem2:MovieClip = chem["clip"+i];
chem2.var_niv += vitesse;
chem2.var_x -= vitesse_x;
chem2.var_y -= vitesse_y; |
Comme on augmente la valeur de la variable de niveau de tous les clips, il faut faire en sorte que les clips qui dépassent le premier plan soient remis en arrière-plan (on en profite aussi pour replacer la tête de lecture du clip 'cercle' sur l'image 1).
Code : Autre1
2
3
4
| if (chem2.var_niv>profondeur) {
chem2.cercle.gotoAndStop(1);
chem2.var_niv -= profondeur;
} |
Il ne nous reste plus qu'à déplacer les clips :
Modifier son niveau :
Code : Autre1
| chem2.swapDepths(chem2.var_niv); |
Modifier sa taille :
Code : Autre1
2
| chem2._xscale=Math.ceil(chem2.var_niv/(profondeur/100));
chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100)); |
Note : on peut aussi écrire cette double instruction comme ceci :
chem2._xscale = chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
Ce qui va diviser son temps d'exécution par 2 (puisqu'avant on faisait faire à l'ordinateur 2 fois le même calcul.)
Enfin la dernière difficulté : pour donner l'impression que les clips viennent de loin (notion de fuyantes) on calcule le % du chemin parcouru et on le réutilise dans le positionnement des clips.
Code : Autre1
2
3
| var coef:Number = (chem2.var_niv/profondeur);
chem2._x = centre_x+coef*chem2.var_x;
chem2._y = centre_y+coef*chem2.var_y; |
Récapitulatif de la deuxième fonction créée :
Secret (cliquez pour afficher)Code : Autre1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void{
var chem1:MovieClip = chem["clip"+var_i];
if (chem1.var_niv != profondeur) {
var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein);
var vitesse_x:Number = Math.ceil(chem1.var_x/frein);
var vitesse_y:Number = Math.ceil(chem1.var_y/frein);
for (var i:Number=0 ; i<nbr ; i++) {
var chem2:MovieClip = chem["clip"+i];
chem2.var_niv += vitesse;
chem2.var_x -= vitesse_x;
chem2.var_y -= vitesse_y;
if (chem2.var_niv>profondeur) {
chem2.cercle.gotoAndStop(1);
chem2.var_niv -= profondeur;
}
chem2.swapDepths(chem2.var_niv);
chem2._xscale=Math.ceil(chem2.var_niv/(profondeur/100));
chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100));
var coef:Number = (chem2.var_niv/profondeur);
chem2._x = centre_x+coef*chem2.var_x;
chem2._y = centre_y+coef*chem2.var_y;
}
} else {
clearInterval(interval);
}
} |
6) Maintenant il suffit d'exécuter la fonction 'creer_btns' pour lancer l'animation (et de lui passer les bons paramètres).
Code : Autre1
| creer_btns(_root, tab_nom_1); |
7) Récapitulatif global (avec commentaires) :
Secret (cliquez pour afficher)Code : Autre1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
| // Création de la fonction 'creer_btns'.
function creer_btns(chem1:MovieClip, tab_nom:Array):Void{
var taille:Number = tab_nom.length;
for (var i:Number=0 ; i<taille ; i++) {
var var_profondeur:Number = Math.round(Math.random()*profondeur);
// Création du clip conteneur et du raccourci.
var chem2:MovieClip = chem1.createEmptyMovieClip("clip"+i, var_profondeur);
// Création des variables de sauvegarde.
chem2.var_x = Math.round(Math.random()*largeur-largeur/2);
chem2.var_y = Math.round(Math.random()*hauteur-hauteur/2);
chem2.var_niv = var_profondeur;
chem2.i = i;
// Positionnement du clip.
chem2._x = centre_x+chem2.var_x;
chem2._y = centre_y+chem2.var_y;
// On y attache le clip 'cercle'.
chem2.attachMovie("cercle", "cercle", 1);
// Création du champs texte.
chem2.createTextField("texte", 2, -10, -10, 20, 20);
// Écriture dans le champ texte.
chem2.texte.text = tab_nom[i];
// Rend le texte impossible à sélectionner.
chem2.texte.selectable = false;
// Redéfinit la taille du clip (en %).
chem2._xscale = chem2._yscale = Math.ceil(chem2.var_niv/(profondeur/100));
// Definit les actions à éxecuter lors du clic sur le clip.
chem2.onRelease = function():Void{
// On place la tête de lecture du clip 'cercle' sur l'image 2.
this.cercle.gotoAndStop(2);
// On supprime la temporisation 'interval' pour ne pas la déclencher 2 fois.
clearInterval(interval);
// On recrée la temporisation 'interval' qui exécutera la fonction 'deplacement', avec 3 paramètres, toutes les 40 millisecondes.
interval = setInterval(deplacement, 40, chem1, this.i, tab_nom.length);
};
}
}
// Création de la fonction 'deplacement'.
function deplacement(chem:MovieClip, var_i:Number, nbr:Number):Void{
// On crée un racourci.
var chem1:MovieClip = chem["clip"+var_i];
// On vérifie si le clip n'est pas déjà au premier plan.
if (chem1.var_niv != profondeur) {
// On calcule les vitesses de déplacement.
// Note : La variable 'frein' diminue les vitesses et donc augmente le temps de déplacement des clips.
var vitesse:Number = Math.ceil((profondeur-chem1.var_niv)/frein);
var vitesse_x:Number = Math.ceil(chem1.var_x/frein);
var vitesse_y:Number = Math.ceil(chem1.var_y/frein);
// On édite les variables et les coordonnées de tous les clips.
for (var i:Number=0 ; i<nbr ; i++) {
// Création d'un raccourci.
var chem2:MovieClip = chem["clip"+i];
// On édite les variables.
chem2.var_niv += vitesse;
chem2.var_x -= vitesse_x;
chem2.var_y -= vitesse_y;
// Si le clip a dépassé le niveau de premier plan.
if (chem2.var_niv>profondeur) {
// On place la tête de lecture du clip 'cercle' sur l'image 1.
chem2.cercle.gotoAndStop(1);
// On édite la variable de niveau.
chem2.var_niv -= profondeur;
}
// On édite le niveau du clip .
chem2.swapDepths(chem2.var_niv);
// On modifie la largeur et la hauteur du clip (en %).
// Note : chem2.var_niv et profondeur, varient entre 0 et 1000, suite au petit calcul de valeur de sortie sont comprises entre 0 et 100.
chem2._xscale = chem2._yscale=Math.ceil(chem2.var_niv/(profondeur/100));
// On calcule le % du chemin parcouru.
var coef:Number = (chem2.var_niv/profondeur);
// On modifie les coordonnées du clip.
chem2._x = centre_x+coef*chem2.var_x;
chem2._y = centre_y+coef*chem2.var_y;
}
} else {
// On supprime la temporisation 'interval' puisque le clip est arrivé au premier plan.
clearInterval(interval);
}
}
// Déclaration des variables globales.
var profondeur:Number = 1000;
var largeur:Number = 200;
var hauteur:Number = 200;
var centre_x:Number = 100;
var centre_y:Number = 100;
var frein:Number = 5;
var interval:Number;
// Création du tableau des noms.
var tab_nom_1:Array = new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
// Exécution de la fonction 'creer_btns' à laquelle on envoie le chemin du clip conteneur (ici la scène principale '_root') et le tableau des noms.
creer_btns(_root, tab_nom_1); |
Note : Les lignes précédées de '//' sont des commentaires, vous pouvez donc les supprimer sans aucun risque.
8) Et pour finir la dernière étape, celle que vous attendiez tous,
l'ENREGISTREMENT de ce que vous avez fait tout au long de l'écriture du code bien évidement

...

... comment ça non ?

RHHAAA pas bien !