Aller au menu - Aller au contenu

Fil rouge - On The Road Again


Informations sur le tutoriel

Avatar
Auteur : SuprazZz
Visualisations : 71 010


Plus d'informations Plus d'informations

Historique des mises à jour

  • Le 20/03/2010 à 11:19:57
    La bonne réponse d'un QCM n'existait pas
  • Le 18/01/2010 à 09:55:35
    Correction orthographique
  • Le 28/07/2009 à 17:44:39
    Bug du zCode
Voilà le TP de fin de chapitre. :D
Vous allez créer votre premier mini-jeu, et pas n'importe lequel : un jeu de voitures pour 2 joueurs (sur un seul clavier ;) ).

Voilà le résultat final de notre futur jeu, que l'on nommera "On The Road Again" :

Chapitre précédent Sommaire Chapitre suivant

Point de départ

J'espère que vous avez essayé OTRA (= On The Road Again), ça va vous donner une idée des clips qu'on va avoir besoin de créer.
Ils sont au nombre de 5 :
  • une voiture
  • un compteur (de vitesse et de tour, tout intégré :)
  • un feu tricolore
  • une route
  • des Goals (ou waypoints, ce sont les "tiges" blanches)


Une voiture



Oui, j'ai bien dit une voiture, et une seule. Il suffira de créer deux instances sur scène, et de changer leur couleur pour pouvoir différencier les deux voitures : a et b.

Image utilisateur

Voilà comment j'ai dessiné la voiture, c'est pas du grand art, mais on reconnaît 4 roues et un cockpit. :D Arrangez-vous pour centrer la voiture avec le centre du clip : comme ça, on aura des collisions assez précises, puisque la voiture est un clip de petite taille.
Surtout, il faut que vous dirigiez la voiture comme moi, c'est-à-dire de gauche à droite. Sinon vous aurez des problèmes après...

Créez donc deux occurrences de votre voiture sur la scène, changez un peu la couleur des deux voitures, et donnez-leur comme nom voiture_a et voiture_b.

Un compteur



Le compteur de vitesse est la pièce maîtresse de ce jeu, puisqu'il affiche à la fois la vitesse de la voiture, mais aussi le nombre de tours effectués. On va donc distinguer les deux parties.

Le compteur de tours est un bête champ texte dynamique, on lui assigne la variable tour (attention j'ai bien dit la variable, pas le nom d'occurrence).

Pour identifier la voiture à laquelle appartient le compteur, créez un champ de texte dynamique de variable voiture.

Image utilisateur

Le compteur de vitesse est un peu plus complexe. Il faut dessiner un rectangle coloré (ou blanc, si le fond de votre scène est coloré) qui correspond à la taille maximum du compteur (la vitesse maximum). Convertissez ce rectangle en un clip, que vous nommerez vitesse (là, je parle du nom d'occurrence, pas du nom dans la bibliothèque ;) ). Cette fois, positionnez le bord droite du rectangle sur le centre du clip.

Vous allez donc ranger le clip vitesse et les deux champs de texte dynamique de variable tour et voiture dans un nouveau clip, que l'on nommera compteur_a. Créez une autre occurrence de ce clip, que vous nommerez compteur_b (pour l'autre voiture).

Image utilisateur

Voilà à quoi ressemblent vos deux compteurs, côte à côte :




Un feu tricolore



Le feu tricolore est un clip que vous nommerez feu_tricolore sur la scène principale. A l'intérieur, vous dessinez un rectangle arrondi foncé. A côté, créez un clip blanc circulaire que vous dupliquerez 2 fois pour faire les 3 feux ; vous les nommerez de haut en bas : couleur_1, couleur_2 et couleur_3.
Image utilisateur


Une route



Ça peut paraître évident, mais sans route, le jeu va être drôlement moins intéressant ! Bref, le circuit, c'est un simple clip nommé route (vous avez, j'en suis sûr, remarqué l'extrême originalité dont je fais preuve quand je nomme un clip). Dans ce clip, vous dessinez votre route, tout bêtement. Au début, faites un circuit simple, sans "branches", parce que ça posera des problèmes au niveau des waypoints que l'on va voir tout de suite.

Image utilisateur


Des Goals


Image utilisateur

Pour l'instant, vous ne savez pas encore vraiment comment ils vont fonctionner, mais si vous avez un peu joué, vous savez déjà que si vous vous sortez de la route, vous êtes replacé sur le dernier Goal où vous êtes passé. Les Goals permettent aussi de vérifier que vous avez bien fait tout le tour du circuit avant de repasser par la ligne de départ.

Les lignes de départ et d'arrivée sont d'ailleurs des goals comme les autres, on leur donne juste un peu de couleur dans leur occurrence.
Vous pouvez le dessiner comme vous le souhaitez, le goal doit simplement être à peu près rectangulaire, dirigé vers le haut, avec son centre au niveau du centre du clip.
Ensuite, vous allez en placer aux endroits stratégiques de votre route. Vous nommerez le premier (la ligne de départ) goal0. Ensuite, vous avez compris : tous les suivants porteront les noms goal1, goal2 ...

Vous pouvez changer les propriétés des lignes de départ et d'arrivée, pour qu'on puisse les identifier plus facilement. ;)

Image utilisateur



Et pour les feignants ?



J'allais oublier les plus paresseux d'entre vous, ou tout simplement pour comparer avec ce que vous avez. Je vous invite quand même à le prendre pour continuer, comme ca vous êtes sur de tout avoir. ;)


Faire mumuse avec la voiture

On va commencer par s'atteler à la partie la plus fun : le déplacement des voitures. :D

Pour avoir un code propre, on écrira tout le code que je vous donnerai dans ce TP, sur la scène principale !

Structure fonctionnelle



On va créer deux tableaux contenant chacun les 3 touches nécessaire au déplacement des voitures. Le premier tableau contiendra les valeurs des touches pour déplacer la voiture A, et le second, les valeurs pour la voiture B.

Code : Autre
1
2
var touches_a:Array = new Array(Key.LEFT, Key.RIGHT, Key.UP);
var touches_b:Array = new Array(81, 68, 90);


Ensuite, puisqu'on a deux voitures, on va créer une seule et unique fonction de déplacement, qu'on associera aux deux voitures :

Code : Autre
1
2
3
4
5
6
this.controle_voiture = function() {
        //Le code pour le déplacement
}
// On associe la fonction aux événements onEnterFrame des deux voitures
this.voiture_a.onEnterFrame = this.controle_voiture; 
this.voiture_b.onEnterFrame = this.controle_voiture;


Le problème, c'est que je ne veux pas associer les événements à la fonction dès le départ, sinon le jeu commencerait tout de suite !
On va donc créer une fonction qui activera les voitures. Et pour l'instant, on appelera cette fonction une fois pour chaque voiture dès le départ, pour pouvoir tester nos voitures !

Code : Autre
1
2
3
4
5
6
7
8
9
this.controle_voiture = function() {
        //Le code pour le déplacement
}
this.activer_voiture = function(nom) {
        this['voiture_'+nom].onEnterFrame = this.controle_voiture; 
        this['voiture_'+nom].nom = nom; // On donne son nom à la voiture ...
}
this.activer_voiture('a');
this.activer_voiture('b');


Déplacements



On va d'abord s'interroger sur le fonctionnement de la voiture. Elle devra avoir deux variables : rotation et vitesse.

Rotation


Pour la rotation c'est facile, on va utiliser la propriété _rotation du clip, ça nous fera gagner du temps :p

On va effectuer une condition assez complexe. On veut vérifier que la touche gauche est pressée. On utilise donc
Key.isDown(latouche).

Mais la valeur de cette touche est contenue dans un tableau sur la scène principale :
Key.isDown(this._parent.letableau[latouche])

Le tableau se nomme touches_a, ou touches_b, selon la voiture, ça tombe bien, puisque que dans la fonction activer_voiture, on a transmis à la voiture son nom dans la variable nom.
Key.isDown(this._parent['touches_'+this.nom][latouche])

La touche correspondante à gauche, c'est la première valeur du tableau, ce qui nous donne :
Key.isDown(this._parent['touches_'+this.nom][0])

Vous refaites ce raisonnement pour l'autre touche, et ça nous donne ce code :

Code : Autre
1
2
3
4
5
6
7
8
this.controle_voiture = function() {
        if (Key.isDown(this._parent['touches_'+this.nom][0])) {
                this._rotation += -5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][1])) {
                this._rotation += 5;
        }
}


A ce stade, vous pouvez déjà tester votre code en déplaçant les voitures sur la scène avant de compiler. Vous verrez qu'elles tournent selon la touche appuyée.

En avant


On sait tourner, mais il faudrait maintenant avancer !
Si vous connaissez un peu la mécanique newtonienne, et si vous ne la connaissez pas, vous pouvez l'imaginer, quand vous appuyez sur l'accélérateur de la voiture, vous agissez sur son accélération. L'accélération, c'est la dérivée de la vitesse par rapport au temps ; en clair : à chaque fois que vous appuyez sur l'accélérateur, vous incrémentez la vitesse de la voiture. Et la vitesse de la voiture, c'est la dérivée de la position par rapport au temps : en clair, la position est égale à la position d'avant plus la vitesse.

Si vous n'avez pas compris, ce n'est pas bien grave, puisque je ne vais pas utiliser de formule de physique, mais simplement des équations que tout le monde peut deviner par lui-même.
La première chose à faire, c'est de créer une variable vitesse pour chaque voiture. Ça va être facile, puisqu'on a une fonction activer_voiture :

Code : Autre
1
2
3
4
5
this.activer_voiture = function(nom) {
        this['voiture_'+nom].onEnterFrame = this.controle_voiture;
        this['voiture_'+nom].nom = nom;
        this['voiture_'+nom].vitesse = 0; //La vitesse est nulle au départ
};


Ensuite, il faut faire en sorte d'augmenter la vitesse à chaque fois qu'on appuie sur la touche avant :

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
this.controle_voiture = function() {
        if (Key.isDown(this._parent['touches_'+this.nom][0])) {
                this._rotation += -5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][1])) {
                this._rotation += 5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][2])) {
                        this.vitesse += 0.5;
        }
};


Il faut maintenant rajouter une condition pour limiter la vitesse ; moi, j'ai décidé de fixer une limite à 10pixels/images.
Il faut aussi prendre en compte les frottements : pour tricher avec la physique, on va dire que quand on n'accélère pas, la voiture perd de la vitesse jusqu'à atteindre la vitesse nulle (sinon elle repart en arrière :( ).

Code : Autre
1
2
3
4
5
6
7
8
9
if (Key.isDown(this._parent['touches_'+this.nom][2])) {
        if (this.vitesse<10) {
                this.vitesse += 0.5;
        }
} else {
        if (this.vitesse>0) {
                this.vitesse -= 0.5;
        }
}


Le problème, c'est que la voiture n'avance pas pour autant. :D
Il va falloir faire un lien entre la vitesse de la voiture, et sa vitesse sur l'axe des abscisses et des ordonnées, en fonction de la rotation.

On va donc utiliser les fonctions trigonométriques que sont sinus et cosinus. Pour ceux qui ont lu l'annexe sur la rotation d'un clip en fonction de la souris, vous connaissez déjà la technique !
Sauf que là, on fait exactement l'inverse. :D

Image utilisateur

En fait, on va projeter la vitesse sur les deux axes, pour savoir comment faire avancer la voiture.
On cherche le projeté vitesse_x sur l'axe des abscisses, et le projeté vitesse_y sur l'axe des ordonnées. Normalement, depuis le collège, vous devriez savoir faire ça.

Sur le schéma à droite, j'ai récapitulé les "formules" de base de trigonométrie dans le triangle rectangle.
Le petit point noir représente la voiture, le trait rouge la vitesse, et les traits bleus et verts les projetés de cette vitesse sur les axes. Ce qu'on veut, c'est ajouter à la position de la voiture la valeur de ces projetés.

Flash nous offre les fonctions Math.sin() et Math.cos(), qui fonctionnent en radians. Le problème, c'est que _rotation s'exprime en degrés. Pour convertir un degré en radian, il faut le multiplier par PI (Math.PI), et le diviser par 180.

Je vais arrêter le suspense ici, et vous laisser contempler le code qui va vous permettre d'avancer :
Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
this.controle_voiture = function() {
        if (Key.isDown(this._parent['touches_'+this.nom][0])) {
                this._rotation += -5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][1])) {
                this._rotation += 5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][2])) {
                if (this.vitesse<10) {
                        this.vitesse += 0.5;
                }
                
        } else {
                if (this.vitesse>0) {
                        this.vitesse -= 0.5;
                }
        }
        this._y += Math.sin(this._rotation*(Math.PI/180))*this.vitesse;
        this._x += Math.cos(this._rotation*(Math.PI/180))*this.vitesse;
};


Vous pouvez tester, c'est déjà entièrement fonctionnel. Mais ce que je n'aime pas, c'est la tenue de route de la voiture. J'aimerais qu'elle puisse déraper à fond. Pour donner une conduite un peu plus "fun" à notre voiture, on va faire en sorte qu'elle ne tourne QUE quand on accélère. :p

En clair, on récupère l'angle de la voiture quand elle accélère, et on l'utilise pour calculer les projetés. Quand la voiture n'accélère pas, on conserve l'angle précédent. Ça nous donne donc :

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
this.controle_voiture = function() {
        if (Key.isDown(this._parent['touches_'+this.nom][0])) {
                this._rotation += -5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][1])) {
                this._rotation += 5;
        }
        if (Key.isDown(this._parent['touches_'+this.nom][2])) {
                if (this.vitesse<10) {
                        this.vitesse += 0.5;
                }
                this.direc = this._rotation;
        } else {
                if (this.vitesse>0) {
                        this.vitesse -= 0.5;
                }
        }
        this._y += Math.sin(this.direc*(Math.PI/180))*this.vitesse;
        this._x += Math.cos(this.direc*(Math.PI/180))*this.vitesse;
};


Libre à vous de conserver le code précédent : mais je trouve celui-là beaucoup plus intéressant à jouer.

Pour ceux qui voudraient comparer leur source avec la mienne à ce stade :


Les goals

Maintenant commence la partie sur les collisions. Ce qu'on veut, c'est que la voiture reste sur la route : en clair, elle peut avancer tant qu'il y a collision entre le clip voiture_a (et voiture_b aussi, bien sûr) et le clip route.
Sinon, qu'est-ce qui se passe ? On remet la voiture au Goal précédent.

On va devoir tester les collisions entre goals et voiture. Il faudra effectuer un test entre la voiture et le goal suivant. Ça va être facile puisque les goals portent les noms goal0, goal1, goal2, etc.

Dans activer_voiture, vous allez rajouter cette ligne :
Code : Autre
1
this['voiture_'+nom].dernier_goal = -1;


En clair, on crée une variable dernier_goal pour chaque voiture. Pour l'instant cette variable vaut -1.

On va donc effectuer à chaque image un test de collision entre la voiture et le clip goal, suivi du nombre dernier_goal+1.

Le petit problême qui se pose, c'est que les clips goals ne sont pas dans le même clip que voiture...
Prenons l'exemple de voiture_a :

voiture_a appartient à _root.
Donc, pour accéder à _root depuis voiture_a, on écrit this._parent (on pourrait écrire _root tout simplement, mais je préfère qu'on s'amuse un peu avec les chemins relatifs).

goalX (avec X représentant le numéro du goal) appartient à route qui appartient à _root.

Pour accéder à un goal depuis voiture_a, il faudra donc écrire :

this._parent.route["goal"+X]

Et X représente le numéro du dernier goal franchi, plus 1 !

On a donc this._parent.route["goal"+(this.dernier_goal+1)]

Quand on passe par un goal, on va enregistrer la position de la voiture, ainsi que sa rotation, pour pouvoir la replacer à l'endroit exact où elle est passée, quand elle touchera un mur.

Code : Autre
1
2
3
4
5
6
if (this._parent.route["goal"+(this.dernier_goal+1)].hitTest(this._x, this._y, true)) {
        this.dernier_goal++;
        this.dernier_x = this._x;
        this.dernier_y = this._y;
        this.dernier_rotation = this._rotation;
}


Vous pouvez tester en incluant un trace('je passe la porte'+this.dernier_goal); dans le code précédent, tout fonctionne !

Mais un nouveau problême se pose ! :D Au bout d'un moment, on repassera par la porte numéro 0 ! Il va donc falloir ruser. :p Je suppose que vous êtes d'accord pour dire que la solution la plus simple est de remettre dernier_goal à -1 quand on passe la dernière porte. Mais comment connaître le numéro de la dernière porte, puisque, quand on construit le circuit, on en met autant qu'on veut ? :euh:

On pourrait tout simplement créer une variable nombre_goal, où on indiquerait le nombre de portes qu'on a mis. Mais cette solution ne me satisfait pas, je veux que ce soit fait dynamiquement, et que je puisse changer le circuit quand je veux, sans toucher à l'ActionScript.

Bon. Je vous donne une solution, qui vaut ce qu'elle vaut (forcément :D ).
Au tout début début de votre code, on va chercher ce que vaut la variable nombre_goal. Pour cela, on va faire une boucle qui incrémentera la variable nombre_goal ,tant qu'elle trouvera un goal.

Code : Autre
1
2
3
4
var nombre_goal = 0;
while (this.route['goal'+nombre_goal] != undefined) {
        nombre_goal++;
}


Comme vous pouvez le deviner, au bout d'un moment, this.route['goal'+nombre_goal] ne fera plus référence à un clip, et deviendra donc vide, c'est-à-dire undefined.
La variable nombre_goal contiendra donc le nombre de portes. :D

Bien entendu, vous faites ce calcul qu'une seule et unique fois au début de l'animation ; n'allez pas mettre cette boucle dans le onEnterFrame des voitures. :p


Bon ! Maintenant qu'on sait combien on a de goals, on va rajouter une condition dans controle_voiture.

Après le test de collision, rajoutez ce bloc :
Code : Autre
1
2
3
4
if (this.dernier_goal == (this._parent.nombre_goal-1)) {
        this.dernier_goal = -1;
        this.tour++;
}


Pas besoin de vous l'expliquer. Par contre, vous pouvez vous poser des questions quant à la variable tour. Je viens de l'introduire, elle va permettre de comtper le nombre de tours de circuit effectué par la voiture. Mais pour l'instant, elle ne fonctionnera pas, parce qu'on ne l'a pas déclarée à 0 au départ.
Rajoutez donc cette ligne dans activer_voiture :
Code : Autre
1
this['voiture_'+nom].tour = 0;

Collisions inside

On a déjà écrit 60% du code, et pourtant, il manque quelque chose de primordial : les collisions, pour ne pas pouvoir sortir du circuit !

Vous allez voir, c'est très facile ! Toujours dans la fonction controle_voiture, il va falloir tester si la voiture est bien en collision avec le clip route, et si elle ne l'est pas (c'est-à-dire si elle est sortie de la route), il va falloir la ramener au point qu'on avait sauvegardé dans les variables dernier_x, dernier_y, et dernier_rotation.

Je pense que vous devriez essayer un peu tout seul, parce que c'est vraiment facile. :p Si vous n'avez pas trouvé dans 10 minutes, la solution est ci-dessous :

Secret (cliquez pour afficher)
Code : Autre
1
2
3
4
5
6
if (!this._parent.route.hitTest(this._x, this._y, true)) {
        this._x = this.dernier_x;
        this._y = this.dernier_y;
        this._rotation = this.dernier_rotation;
        this.vitesse = 0;
}


Bah voilà, c'est fini. :D
Vous pouvez remarquer qu'on remet la vitesse à 0 pour éviter que la voiture se prenne un mur en boucle. ;)


Fignolages

Eh oui, on a le coeur du système, mais il va falloir fignoler !

Prêt ? Partez !



On va déjà activer notre feu tricolore.
Supprimez les deux lignes suivantes de votre code :
Code : Autre
1
2
this.activer_voiture('a');
this.activer_voiture('b');


Rajoutez ça à la place :
Code : Autre
1
2
3
4
this.feu_tricolore.onRelease = function() {
        this._parent.compteur_temps = 0;
        this.onEnterFrame = this._parent.activation_feu;
};


Quand on cliquera sur le feu tricolore, on va initialiser la variable compteur_temps sur _root à 0, et associer _root.onEnterFrame à une fonction qu'on va écrire maintenant.

Dans cette fonction, on va incrémenter de façon constante la variable compteur_temps, et à chaque fois qu'elle dépassera un certain seuil, on allumera une loupiotte du feu tricolore. :D

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
this.activation_feu = function() {
        this._parent.compteur_temps++;
        if (this._parent.compteur_temps == 10) {
                // Première lampe
        } else if (this._parent.compteur_temps == 30) {
                // Seconde lampe
        } else if (this._parent.compteur_temps == 50) {
                // Troisième lampe + départ
        } else if (this._parent.compteur_temps>=50) {
                // c'est fini, on fait disparaitre le feu, et on arrête le onEnterFrame
                this._alpha--;
                if (this._alpha<=0) {
                        this.onEnterFrame = null;
                }
        }
};


Maintenant, on va changer la couleur des lampes ; allez vite potasser le cours précédent pour retrouver les fonctions qui permettent de colorer un clip. :)

Je vous rappelle qu'il va falloir importer des librairies tout au début du code :
Code : Autre
1
2
import flash.geom.ColorTransform;
import flash.geom.Transform;


Il va falloir créer des transformations de couleurs.

Code : Autre
1
2
3
4
5
6
/* -> Couleur rouge */
var couleur_rouge:ColorTransform = new ColorTransform();
couleur_rouge.rgb = 0xFF0000;
/* -> Couleur verte */
var couleur_vert:ColorTransform = new ColorTransform();
couleur_vert.rgb = 0x00FF00;


Il faut aussi créer des transformations pour les clips du feu tricolore :
Code : Autre
1
2
3
var vers_rouge_1:Transform = new Transform(feu_tricolore.couleur_1);
var vers_rouge_2:Transform = new Transform(feu_tricolore.couleur_2);
var vers_vert:Transform = new Transform(feu_tricolore.couleur_3);


Et ensuite, il ne reste plus qu'à associer les deux, et à lancer la partie. Donc, pour reprendre le code dans sa totalité, on a :


Code : Autre
1
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
import flash.geom.ColorTransform;
import flash.geom.Transform;

// -TOUT LE RESTE DU CODE DEJA MIS

/* Démarrage du jeu - feu tricolore */
/* -> Couleur rouge */
var couleur_rouge:ColorTransform = new ColorTransform();
couleur_rouge.rgb = 0xFF0000;
/* -> Couleur verte */
var couleur_vert:ColorTransform = new ColorTransform();
couleur_vert.rgb = 0x00FF00;
/* -> Assignation des transformations aux clips */
var vers_rouge_1:Transform = new Transform(feu_tricolore.couleur_1);
var vers_rouge_2:Transform = new Transform(feu_tricolore.couleur_2);
var vers_vert:Transform = new Transform(feu_tricolore.couleur_3);

this.activation_feu = function() {
        this._parent.compteur_temps++;
        if (this._parent.compteur_temps == 10) {
                vers_rouge_1.colorTransform = couleur_rouge;
        } else if (this._parent.compteur_temps == 30) {
                vers_rouge_2.colorTransform = couleur_rouge;
        } else if (this._parent.compteur_temps == 50) {
                vers_vert.colorTransform = couleur_vert;
                this._parent.activer_voiture('a');
                this._parent.activer_voiture('b');
        } else if (this._parent.compteur_temps>=50) {
                this._alpha--;
                if (this._alpha<=0) {
                        this.onEnterFrame = null;
                }
        }
};
/* -> Lancement du jeu si clic de la souris */
this.feu_tricolore.onRelease = function() {
        this._parent.compteur_temps = 0;
        this.onEnterFrame = this._parent.activation_feu;
};


Activation des voitures et du compteur



Comme vous pouvez le constater, au départ les voitures ne sont pas placées sur la ligne de départ. Nous allons y remédier, en créant une fonction qui place tout bien au départ :

Code : Autre
1
2
3
4
5
6
7
8
9
10
11
12
this.creer_voiture = function(nom) {
        var voiture = this['voiture_'+nom];
        voiture.nom = nom;
        voiture._x = this.route.goal0._x;
        voiture._y = this.route.goal0._y;
        voiture._rotation = this.route.goal0._rotation;
        voiture.vitesse = 0;
        voiture.dernier_goal = -1;
        voiture.tour = 0;
};
this.creer_voiture('a');
this.creer_voiture('b');


Comme vous pouvez le constater, cette fonction ressemble beaucoup à activer_voiture, mais elle est appelée dès le départ !

Rajoutez dans cette fonction ces quelques lignes :

Code : Autre
1
2
3
4
5
var compteur = this['compteur_'+nom];
compteur.nom = nom;
compteur.voiture = 'Voiture '+nom;
compteur.tour = '0 / '+this.nombre_tour;
compteur.vitesse._xscale = 0;


Cela permet d'initialiser les compteurs.

On va d'ailleurs s'en occuper, des compteurs !

On va créer une fonction qui va leur permettre d'aller chercher les infos qui les intéressent dans le clip voiture, ce qui va être facile, puisqu'on a introduit dans chaque compteur un nom qui correspond au nom de la voiture (a ou b).

Code : Autre
1
2
3
4
this.controle_compteur = function() {
        this.tour = this._parent['voiture_'+this.nom].tour+' / '+this._parent.nombre_tour;
        this.vitesse._xscale = 10*this._parent['voiture_'+this.nom].vitesse;
};


Et il faut bien sûr associer cette fonction au onEnterFrame de chaque compteur dans la fonction activer_voiture. Rajoutez donc dedans :

Code : Autre
1
this['compteur_'+nom].onEnterFrame = this.controle_compteur;


Voilà, maintenant tout est parfaitement fonctionnel ! On a juste oublié un tout petit détail. :D La fin du jeu !

C'est tout bête, il suffit de créer un champ de texte dynamique sur la scène principale, portant la variable gagnant.

Ensuite allez chercher cette ligne de code :
Code : Autre
1
2
3
4
if (this.dernier_goal == (this._parent.nombre_goal-1)) {
        this.dernier_goal = -1;
        this.tour++;
}


Et faites fonctionner vos méninges pour savoir ce qu'il faut y rajouter :D

Solution :

Secret (cliquez pour afficher)
Code : Autre
1
2
3
4
5
6
7
if (this.dernier_goal == (this._parent.nombre_goal-1)) {
        this.dernier_goal = -1;
        this.tour++;
        if ((this.tour == this._parent.nombre_tour) && (_root.gagnant == null)) {
                _root.gagnant = 'Le gagnant est voiture '+this.nom;
        }
}

Des améliorations

On va apporter une petite amélioration, et ensuite vous pourrez proposer les vôtres dans les commentaires. :D

Personnellement, j'adore les effets de transparence, et je trouve que ça ne se voit pas assez quand on passe par une porte.

On va donc créer une fonction qui baisse la transparence au cours du temps, jusqu'à 50% :

Code : Autre
1
2
3
4
5
this.controle_goal = function() {
        if (this._alpha>50) {
                this._alpha--;
        }
};


Et on va l'associer avec le onEnterFrame de chaque goal dans la boucle qu'on utilisait pour déterminer le nombre de portes, qui devient donc :

Code : Autre
1
2
3
4
while (this.route['goal'+nombre_goal] != undefined) {
        this.route['goal'+nombre_goal].onEnterFrame = this.controle_goal;
        nombre_goal++;
}


Faites attention à placer la fonction controle_goal AVANT la boucle, sinon l'association ne pourra pas se faire puisque la fonction n'existe pas encore pour Flash.

Maintenant, c'est à vous de faire fonctionner vos méninges, et d'apporter vos propres améliorations pour faire un petit jeu convivial. Je peux vous donner quelques pistes :
- permettre de faire plusieurs chemins possibles (problème des goals, il faut actuellement passer par tous ; alors, on ne peut pas en mettre dans les branches ...).
- Rajouter des armes :p (un super-pouvoir pour chaque voiture, activable une seule fois par exemple, qui crée un tremblement de terre, ou stoppe la voiture ennemie ...).

Si ce que vous avez fait ne fonctionne pas ou mal, ou que vous n'avez pas compris certains passages de mon tutorial, voilà la source du jeu fini et (plus ou moins) commenté :



Bon. Après un gros tuto comme ça, je vais aller prendre quelques semaines de sommeil, moi. :p

J'en profite pour préciser que si vous avez des idées pour le fil rouge du 6ème chapitre (c'est pas demain la veille), donnez-les maintenant, que je m'y prépare. ;)
Chapitre précédent Sommaire Chapitre suivant

Informations sur le tutoriel

Retour en haut Retour en haut

Créé : Le 30/11/2005 à 19:39:43
Modifié : Le 15/05/2009 à 15:38:14
Avancement : 100%
Licence : Copie non autorisée

16 commentaires