0% ont trouvé ce document utile (0 vote)
7 vues26 pages

Tuto Racing

Ce document présente un exercice pratique pour créer un jeu de course en utilisant ActionScript 3. Il aborde la conception du circuit, la gestion des collisions et l'interaction des véhicules avec le terrain, en utilisant des Bitmap et une ColorMap pour simplifier le processus. Les prérequis incluent des connaissances en programmation orientée objet et manipulation de tableaux.

Transféré par

spimarzin
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats TXT, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
7 vues26 pages

Tuto Racing

Ce document présente un exercice pratique pour créer un jeu de course en utilisant ActionScript 3. Il aborde la conception du circuit, la gestion des collisions et l'interaction des véhicules avec le terrain, en utilisant des Bitmap et une ColorMap pour simplifier le processus. Les prérequis incluent des connaissances en programmation orientée objet et manipulation de tableaux.

Transféré par

spimarzin
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats TXT, PDF, TXT ou lisez en ligne sur Scribd

---- pageinfo ----

version : as3
resume : Cr�ation d'un jeu de type COURSE
auteur : Monsieur Spi
datecreation : 01/08/2013
revisions :
lienforum :
licence : by-nc-sa
tags : jeux, tableaux, comportement
----

====== Exercice pratique : la COURSE ======

Bonjour,

Aujourd'hui on s'attaque aux jeux de courses, un exercice particulier qui change de


la m�thode habituelle utilis�e dans les exercices pr�c�dents, aussi je vais
�galement adapter mon plan de r�daction et toute l'�tude va se faire pas � pas.
Comme vous allez le voir il s'agit plus ici de dessiner et de partitionner l'espace
que d'utiliser des formules complexes, je vais utiliser des artifices pour �viter
de longues formules de maths mais le r�sultat est le m�me pour la m�thode g�n�rale.

Tout d'abord le r�sultat :

{{.:course:course_mb.swf?800x800}}

**Les sources sont disponibles en fin d'exercice**

====== Les pr�-requis ======

Pour ce programme vous devez conna�tre :


<PREREQUIS>
Variables et types :
[Link]
[Link]#var \\
Fonctions et param�tres :
[Link]
[Link]#function \\
Manipulation de tableaux :
[Link] \\
Ecouteurs d'�v�nements :
[Link]
[Link] \\
Programmation Orient� Objet :
[Link]
classesqqc \\
Exercices pratiques pr�c�dents de la s�rie :
[Link]
</PREREQUIS>

====== Etude pr�liminaire ======

Tout d'abord le JEU DE COURSE c'est quoi ?

On ne parle pas ici d'un jeu en particulier, mais d'une cat�gorie de jeux. Tout le
monde sait en quoi consiste un jeu de course, les joueurs s'affrontent sur un
circuit avec un v�hicule et le premier arriv� � gagn�.
En mati�re de jeux vid�o de course il existe diff�rents rendus : la vue top down,
c'est � dire vu du dessus tel un oiseau, la vue lat�rale, tr�s peu utilis�e, la vue
isom�trique, tr�s employ�e dans les vieux jeux vid�o, les vue � la troisi�me
personne ou subjective, utilis�e dans les jeux plus r�cents utilisant la 3D.

Si vous avez d�j� tent� de r�aliser un jeu de course vous vous �tes s�rement
confront� au probl�me de la gestion des collisions et de la reconnaissance du
terrain par les v�hicules, quelle que soit le rendu choisi. Comment obtenir une
d�tection tr�s fine de la forme de la piste, comment faire r�agir un v�hicule en
fonction du terrain sur lequel il roule, comment indiquer � l'ordinateur qu'il doit
suivre un chemin dans le cas des adversaires contr�l�s par l'ordinateur, comment
g�rer une conduite plus ou moins r�aliste, ... ?

Ce sont autant de questions que nous allons aborder avec cet exercice.

====== Pr�paration - partie 1 ======

Avant de commencer nous allons devoir mettre quelques petites choses au point, si
vous avez d�j� cr�� quelques jeux (ou fait les exercices pr�c�dent de cette s�rie),
vous avez sans doute pris l'habitude de vous servir de grilles, de tuiles, de
tableaux � deux dimensions, et de formules de collisions entre une hitbox et tout
un tas de choses (point, grille, cercle, droite, segment, ...).

Si le principe g�n�ral reste le m�me, les outils dont nous allons nous servir sont
bien diff�rent de ce � quoi on est habitu�. Ici les ma�tres mots seront "Bitmap",
"BitmapData" et "Point".

Notre premier probl�me concerne le circuit lui m�me :

CAPTURE

Comme vous pouvez le constater, le circuit (ici un circuit de Mario Kart que je
vais utiliser pour l'exercice), est plut�t grand. La premi�re option � laquelle on
pense c'est d'utiliser une grille comme pour du Tile Based, et tracer chaque tuile
une par une, sauf que pour obtenir une pr�cision suffisante il faudrait des tuiles
mesurant presque un pixel de c�t�, or pour un terrain de 800*800 pixels cela nous
fait 640 000 tuiles � se dessiner � la main puis � placer dans un tableau, �a fait
beaucoup et ce n'est pas efficace. Une autre option est de s'orienter vers la
technique du flipper, c'est � dire utiliser des formules de math pour d�terminer
chaque courbe, chaque ligne droite, chaque segment, chaque mur, etc..., c'est
compliqu� et l� encore assez peu efficace car si cela nous permet de tracer un
circuit cela ne nous permet pas de d�tecter le terrain et ses variations. Pour
afficher le terrain nous allons donc nous servir tout simplement d'un Bitmap, de
l'image du terrain elle m�me tout simplement, et nous allons g�rer les collisions
d'une autre mani�re, c'est encore la m�thode la plus simple. Notez qu'un Bitmap est
par d�finition un tableau (donc une grille) rempli de pixels de couleur, ce qui
nous ram�ne au Tile Based. En ce qui concerne la pr�paration de l'affichage du
terrain c'est donc tranquille, on se sert juste de l'image du terrain � afficher,
plut�t chouette non ?

Passons � la m�thode pour d�tecter les collisions et les variations de terrain. On


a vu plus haut que les m�thodes habituelles �taient peu pratiques ou impr�cises, il
nous faut donc trouver un autre artifice qui fera l'affaire. Une solution simple,
l� encore, va �tre d'utiliser une ColorMap, une carte des couleurs si vous
pr�f�rez. Il en existe plusieurs types, celle que nous allons utiliser pour les
collisions sera de la forme la plus simple histoire de ne pas compliquer d'avantage
la m�canique :

CAPTURE
Cette image fait exactement la taille du circuit, elle reprend les zones
importantes comme le bitume, l'herbe et les murs mais cette fois avec une palette
de couleurs limit�e. Ici nous avons besoin de diff�rentier 3 choses, nous allons
donc utiliser trois couleurs et uniquement trois couleurs, m�fiez vous des formats
d'images compress�s et utilisez un PNG limit� � 3 couleurs pour �tre sur de ne pas
avoir de couleurs interm�diaires li�es � la compression d'un JPEG par exemple. Pour
savoir ce que le v�hicule rencontre sur son chemin il nous suffit de v�rifier la
couleur de la ColorMap d'un point situ� sur le v�hicule ou autour. Imaginons un
point au centre du v�hicule, si le point correspond � du noir sur la ColorMap alors
on est sur du bitume, du bleu il s'agit d'un mur, du rose c'est de l'herbe, etc...
Bien sur vous pouvez ajouter autant d'obstacles et de types de terrain que vous le
souhaitez, il suffit d'attribuer une couleur � chaque chose : t�che d'huile,
paille, eau, turbo, bonus, ...

Nous avons r�gl� pas mal de probl�mes, d'une part l'affichage du circuit, facile il
s'agit juste d'une image, d'autre part la reconnaissance des surfaces, l� aussi
tr�s simple � l'aide d'une ColorMap de la taille du circuit, reste � pr�sent �
g�rer les d�placements des v�hicules contr�l�s par l'ordinateur. Partis comme on
l'est vous devez vous douter qu'il y aura encore une astuce avec un Bitmap, mais je
ne souhaite pas vous en parler tout de suite, nous verrons cela en temps voulu,
pour le moment nous avons assez d'infos pr�paratoires pour commencer � programmer
notre jeu, limit� au seul v�hicule du joueur.

R�sumons la pr�paration :

Dessinez votre circuit et sa ColorMap, dans la biblioth�que de Flash exportez ces


deux Bitmap pour une utilisation avec AS (cela se fait exactement comme pour les
MovieClip), le circuit portera le nom de "Terrain" et la ColorMap le nom de
"ColormapCollisions".

Cr�ez ensuite un MovieClip nomm� "Joueur" dans lequel vous allez placer la voiture,
faites en sorte que le rep�re de position du clip soit au centre de la voiture, ce
sera plus pratique pour les calculs, et exportez le pour AS.

Cr�ez �galement un MovieClip nomm� "Marqueur" qui contiendra uniquement un point de


la taille que vous souhaitez et dont le rep�re de position est lui aussi au centre
du point, et exportez le pour AS. Ce marqueur ne nous servira que pour vous montrer
visuellement les points qu'on va utiliser au cours de l'exercice, il est donc
inutile pour une version d�finitive de votre jeu.

C'est tout pour la pr�paration, il y aura d'autres choses � cr�er par la suite mais
on verra �a en temps et heure. Pour le moment notre objectif va �tre d'afficher le
terrain, d'y poser la voiture, de permettre au joueur de la diriger et de g�rer les
interactions avec les diff�rentes surfaces, on s'occupera des adversaires dans un
second temps.

====== Programme principal ======

Notre programme va pour le moment comporter une partie principale au sein de votre
FLA, et les classes "Marqueur" pour afficher les points de rep�re, "Joueur" pour
toute la gestion du joueur et "Collisions" pour toute la gestion des collisions,
voici ce que cela donne.

Sur la premi�re frame de votre FLA �crivez :

<code actionscript>
var mapCollisions:BitmapData;
var terrain:Bitmap;
var joueur:Joueur;

init();

function init():void{

mapCollisions = new ColormapCollisions();


terrain = new Bitmap(new Terrain());
joueur = new Joueur(75,370,mapCollisions);

addChild(terrain);
addChild(joueur);
}
</code>

On cr�e tout simplement tout le mat�riel dont on a besoin, � savoir la map pour les
collisions, le terrain pour l'affichage et le joueur. Vous noterez qu'il n'y a pas
besoin d'ajouter la map des collisions � la liste d'affichage, on a juste besoin
qu'elle existe.

====== Classe Joueur ======

Voyons la classe "Joueur", � la racine de votre projet cr�ez un nouveau document AS


nomm� "Joueur" et �crivez :

<code actionscript>
package {

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class Joueur extends MovieClip {

private var W:Number;


private var H:Number;

private var angle:Number;


private var dir:Number;
private var acc:Number;
private var vitMax:Number;
private var dirMax:Number;

public var dx:int;


public var dy:int;
public var vit:Number;
public var rebond:Boolean;
public var fri:Number;
public var freine:Boolean;
public var sante:int;

private var idealX:Number;


private var idealY:Number;
private var moveX:Number;
private var moveY:Number;
private var glisse:Number;
public var p1:Point = new Point(W, -H);
public var p2:Point = new Point(-W, -H);
public var p3:Point = new Point(W, H);
public var p4:Point = new Point(-W, H);
public var p5:Point = new Point(0, H);
public var p6:Point = new Point(0, -H);

private var pt1:Marqueur = new Marqueur(p1.x, p1.y);


private var pt2:Marqueur = new Marqueur(p2.x, p2.y);
private var pt3:Marqueur = new Marqueur(p3.x, p3.y);
private var pt4:Marqueur = new Marqueur(p4.x, p4.y);
private var pt5:Marqueur = new Marqueur(p5.x, p5.y);
private var pt6:Marqueur = new Marqueur(p6.x, p6.y);

private var col:Collisions;


private var mapCollisions:BitmapData;

private var gauche:int;


private var droite:int;
private var haut:int;
private var bas:int;

public function Joueur (X:int, Y:int, mapColl:BitmapData) {

x = X;
y = Y;

addChild(pt1);
addChild(pt2);
addChild(pt3);
addChild(pt4);
addChild(pt5);
addChild(pt6);

mapCollisions = mapColl;
col = new Collisions();

addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event):void {


sante = 100;
glisse = .12;
moveX = 0;
moveY = 0;
angle = 0;
dir = 0;
acc = .30;
vitMax = 5;
dirMax = 1.5;
W = width/2;
H = height / 2;
dx = 0;
dy = 0;
vit = 0;
rebond = false;
fri = .95;
freine = false;
addEventListener(Event.ENTER_FRAME, update);
[Link](KeyboardEvent.KEY_DOWN, appuyer);
[Link](KeyboardEvent.KEY_UP, relacher);
removeEventListener(Event.ADDED_TO_STAGE, init);
}

// appuyer sur une touche


public function appuyer (e:KeyboardEvent):void{
if ([Link] == 37) gauche = 1;
if ([Link] == 39) droite = 1;
if ([Link] == 38) haut = 1;
if ([Link] == 40) bas = 1;
}

// Rel�cher une touche


public function relacher (e:KeyboardEvent):void{
if ([Link] == 37) gauche = 0;
if ([Link] == 39) droite = 0;
if ([Link] == 38) haut = 0;
if ([Link] == 40) bas = 0;
}

private function update(e:Event):void {

[Link](this,mapCollisions);

if (!rebond) {
dx = droite-gauche;
dy = haut-bas;
angle = Math.atan2(dy, dx);
}

if (freine) vit *= 0.9;

vit += acc*dy;
dir += dx*0.2;
dir *= fri;

if ([Link](vit) > vitMax) vit = vitMax*dy;


if ([Link](dir) > dirMax) dir = dirMax*dx;
if ([Link](dir) < 0.05) dir = 0

vit *= fri;
if (0.1 > [Link](vit) > 0) vit = 0;

rotation += dir*vit;
angle = (rotation - 90) * [Link] / 180;
idealX = [Link](angle)*vit;
idealY = [Link](angle)*vit;
moveX += (idealX-moveX)*glisse;
moveY += (idealY-moveY)*glisse;
if (rebond) {
x -= moveX;
y -= moveY;
} else {
x += moveX;
y += moveY;
}
dir -= (dir * 0.1);
}
}
}
</code>

Je consid�re que vous avez lu les pr�-requis, on va donc estimer que vous savez
cr�er et utiliser une classe et avancer un peu plus vite.

On a beaucoup de variables, je ne vais pas les expliquer une par une mais on va les
passer en revue par blocs utiles.

<code actionscript>
private var W:Number;
private var H:Number;

private var angle:Number;


private var dir:Number;
private var acc:Number;
private var vitMax:Number;
private var dirMax:Number;

public var dx:int;


public var dy:int;
public var vit:Number;
public var rebond:Boolean;
public var fri:Number;
public var freine:Boolean;
public var sante:int;

private var idealX:Number;


private var idealY:Number;
private var moveX:Number;
private var moveY:Number;
private var glisse:Number;
</code>

Tout ceci nous sert pour diriger le v�hicule, angle, acc�l�ration, direction,
vitesse max, friction, etc....

<code actionscript>
public var p1:Point = new Point(W, -H);
public var p2:Point = new Point(-W, -H);
public var p3:Point = new Point(W, H);
public var p4:Point = new Point(-W, H);
public var p5:Point = new Point(0, H);
public var p6:Point = new Point(0, -H);
</code>

Ces variables publiques sont des points de contr�le que l'on va placer sur le
v�hicule, comme en formule 1, il s'agit de petits capteurs plac�s � des endroits
importants qui vont nous servir pour obtenir les informations sur le terrain. J'ai
fait le choix de cr�er 6 points de contr�le, vous pouvez en mettre plus ou moins
selon la pr�cision que vous souhaitez obtenir. J'ai choisi d'en placer un sur
chaque angle de la voiture, plus un au centre du pare choc avant et un au centre du
pare choc arri�re, ce devrait �tre suffisant pour nos besoins.

<code actionscript>
private var pt1:Marqueur = new Marqueur(p1.x, p1.y);
private var pt2:Marqueur = new Marqueur(p2.x, p2.y);
private var pt3:Marqueur = new Marqueur(p3.x, p3.y);
private var pt4:Marqueur = new Marqueur(p4.x, p4.y);
private var pt5:Marqueur = new Marqueur(p5.x, p5.y);
private var pt6:Marqueur = new Marqueur(p6.x, p6.y);
</code>

Ces marqueurs ne sont l� que pour vous indiquer visuellement les points de contr�le
qu'on � pos�, ils ne servent strictement � rien dans le jeu lui m�me et vous pouvez
vous en passer. Ils d�pendent qu'une classe "Marqueur" qu'on �tudiera plus tard
mais qui ne contient que le positionnement du marqueur et son lien avec le
MovieClip "Marqueur".

<code actionscript>
private var col:Collisions;
private var mapCollisions:BitmapData;
</code>

Ici nous avons la gestion des collisions qui correspond � l'objet priv� "col" et la
ColorMap des collisions qui correspond � l'objet "mapCollisions".

<code actionscript>
private var gauche:int;
private var droite:int;
private var haut:int;
private var bas:int;
</code>

Et on termine cette longue liste de variables avec celles qui servent au joueur �
contr�ler son v�hicule.

<code actionscript>
public function Joueur (X:int, Y:int, mapColl:BitmapData) {

x = X;
y = Y;

addChild(pt1);
addChild(pt2);
addChild(pt3);
addChild(pt4);
addChild(pt5);
addChild(pt6);

mapCollisions = mapColl;
col = new Collisions();

addEventListener(Event.ADDED_TO_STAGE, init);
}
</code>

Le constructeur du joueur, on lui passe trois param�tres qui sont sa position sur
X, sa position sur Y et la ColorMap des collisions. On place le joueur, on ajoute
les Marqueurs (inutiles sauf pour d�boguer), on initialise la map des collisions et
le calcul des collisions (que nous �tudierons un peu plus tard), et pour finir on
attend que le joueur soit ajout� � la liste d'affichage avant de faire quoi que ce
soit d'autre.

<code actionscript>
private function init(e:Event):void {
sante = 100;
glisse = .12;
moveX = 0;
moveY = 0;
angle = 0;
dir = 0;
acc = .30;
vitMax = 5;
dirMax = 1.5;
W = width/2;
H = height / 2;
dx = 0;
dy = 0;
vit = 0;
rebond = false;
fri = .95;
freine = false;
addEventListener(Event.ENTER_FRAME, update);
[Link](KeyboardEvent.KEY_DOWN, appuyer);
[Link](KeyboardEvent.KEY_UP, relacher);
removeEventListener(Event.ADDED_TO_STAGE, init);
}
</code>

Le joueur a �t� ajout� � la liste d'affichage, on va donc initialiser toutes les


variables utiles, retirer l'�couteur d'ajout � la liste d'affichage, ajouter les
�couteurs clavier et un �couteur pour mettre � jour le joueur.

<code actionscript>
// appuyer sur une touche
public function appuyer (e:KeyboardEvent):void{
if ([Link] == 37) gauche = 1;
if ([Link] == 39) droite = 1;
if ([Link] == 38) haut = 1;
if ([Link] == 40) bas = 1;
}

// Rel�cher une touche


public function relacher (e:KeyboardEvent):void{
if ([Link] == 37) gauche = 0;
if ([Link] == 39) droite = 0;
if ([Link] == 38) haut = 0;
if ([Link] == 40) bas = 0;
}
</code>

Bon, l� rien de bien neuf, on voit ce genre de chose depuis le d�but des exercices,
on passe donc tout de suite � ce qui nous int�resse vraiment, la gestion du joueur.

<code actionscript>
private function update(e:Event):void {

[Link](this,mapCollisions);

if (!rebond) {
dx = droite-gauche;
dy = haut-bas;
angle = Math.atan2(dy, dx);
}

if (freine) vit *= 0.9;

vit += acc*dy;
dir += dx*0.2;
dir *= fri;

if ([Link](vit) > vitMax) vit = vitMax*dy;


if ([Link](dir) > dirMax) dir = dirMax*dx;
if ([Link](dir) < 0.05) dir = 0

vit *= fri;
if (0.1 > [Link](vit) > 0) vit = 0;

rotation += dir*vit;
angle = (rotation - 90) * [Link] / 180;
idealX = [Link](angle)*vit;
idealY = [Link](angle)*vit;
moveX += (idealX-moveX)*glisse;
moveY += (idealY-moveY)*glisse;
if (rebond) {
x -= moveX;
y -= moveY;
} else {
x += moveX;
y += moveY;
}

dir -= (dir * 0.1);


}
</code>

Ok, le joueur est mis � jour � chaque frame du programme.

<code actionscript>
[Link](this,mapCollisions);
</code>

On commence par regarder les collisions (on �tudie la classe Collisions juste apr�s
rassurez-vous).

<code actionscript>
if (!rebond) {
dx = droite-gauche;
dy = haut-bas;
angle = Math.atan2(dy, dx);
}
</code>

Lorsque le joueur tape un mur il rebondit, avant de modifier ses param�tre on


regarde donc si il n'est pas en train de rebondir, en effet quand le joueur
rebondit on consid�re qu'il n'a plus la ma�trise de son v�hicule. Si il ne rebondit
pas donc, on r�cup�re la direction sur chaque axe et l'orientation qui en r�sulte.

<code actionscript>
if (freine) vit *= 0.9;
</code>
Si le joueur freine ou est frein� par quelque chose, sa vitesse se r�duit
progressivement, �a il peut le faire m�me quand il rebondit sur un mur, c'est un
r�flexe de pilote ;-)

<code actionscript>
vit += acc*dy;
dir += dx*0.2;
dir *= fri;
</code>

On calcule ensuite la vitesse (d�pend de l'acc�l�ration et de l'action choisie par


le joueur, acc�l�rer ou freiner), la direction (d�pend de la direction choisie par
le joueur, droite ou gauche, et de l'angle de braquage, ici je ne l'ai pas plac�
dans une variable, faites le si cela vous d�range). La direction est �galement
influenc�e par la friction du sol, qui pourra bien sur varier selon nos besoins.

<code actionscript>
if ([Link](vit) > vitMax) vit = vitMax*dy;
if ([Link](dir) > dirMax) dir = dirMax*dx;
if ([Link](dir) < 0.05) dir = 0
</code>

On limite la vitesse et la direction aux valeurs maximales que le v�hicule est


capable de supporter, et on ajoute une valeur minimale � la direction, chose qui
nous est utile pour lisser un peu le comportement de la voiture.

<code actionscript>
vit *= fri;
if (0.1 > [Link](vit) > 0) vit = 0;
</code>

La vitesse est influenc�e par la friction du sol, et l� aussi on lisse un peu le


comportement en �vitant que la vitesse soit une valeur qui n'atteigne jamais z�ro,
donc toujours active.

<code actionscript>
rotation += dir*vit;
angle = (rotation - 90) * [Link] / 180;
idealX = [Link](angle)*vit;
idealY = [Link](angle)*vit;
moveX += (idealX-moveX)*glisse;
moveY += (idealY-moveY)*glisse;
</code>

La rotation de la voiture d�pend de la direction et de la vitesse, son angle est


�gal � sa rotation (en radians) auquel je retire 90 degr�s afin de placer ma
voiture dans le sens de la marche. Je d�termine ensuite deux choses, tout d'abord
les mouvements id�aux sur X et Y, � savoir le mouvement normal que devrait avoir la
voiture si on ne cherchais pas � rendre la conduite plus souple, comprenez par l�
qu'il s'agit du mouvement que le pilote cherche � faire. Puis le mouvement r�el,
c'est � dire ce que fait vraiment la voiture suite aux instructions du pilote, ce
mouvement d�pend du mouvement actuel, du mouvement id�al et du facteur de glisse.
Ce que j'ai appel� "facteur de glisse" est en fait l'adh�rence de la voiture en
fonction du terrain, vous pouvez faire fluctuer cette valeur en fonction de la
surface avec laquelle le v�hicule est en contact, par exemple du bitume r�agira
mieux que de l'herbe et encore mieux que de l'huile, etc... Cette petite astuce va
nous permettre de g�rer le comportement de la voiture sans entrer dans des notions
de forces et de physique bien complexes et que l'on devrait utiliser si on
cherchait � faire un jeu de course 3D dit de simulation, fort heureusement ce n'est
pas notre cas.

<code actionscript>
if (rebond) {
x -= moveX;
y -= moveY;
} else {
x += moveX;
y += moveY;
}
</code>

Il ne nous reste plus qu'� d�placer la voiture, mais tout d�pend si elle rebondit
suite � une collision ou pas, si elle rebondit elle repart en sens inverse du
mouvement actuel.

<code actionscript>
dir -= (dir * 0.1);
</code>

Et enfin, dans tous les cas la direction subit un effet de friction, tant que le
joueur tourne cela n'influence que tr�s peu le comportement du v�hicule, mais d�s
qu'il arr�te de tourner la direction revient peu � peu au centre, ce qui est le
comportement normal de tout v�hicule ayant une certaine vitesse, si vous l�chez le
volant les roues reviennent dans le sens de la marche.

C'est termin� pour le joueur, rien de tr�s complexe normalement, il nous reste
quand m�me � voir comment son g�r�es les collisions.

====== Classe Collisions ======

A la racine de votre projet cr�ez un nouveau document AS nomm� "Collisions" et


�crivez :

<code actionscript>
package {

import [Link];
import [Link];

public class Collisions {

public function Collisions () {}

public function hitTest(ob:Object, map:BitmapData):void {

var terre:int = 16711935;


var mur:int = 6750207;

// converti les coordonn�es des points


var p1:Point = [Link](ob.p1);
var p2:Point = [Link](ob.p2);
var p3:Point = [Link](ob.p3);
var p4:Point = [Link](ob.p4);
var p5:Point = [Link](ob.p5);
var p6:Point = [Link](ob.p6);

// trouve les couleurs sous les points


var c1:int = [Link](p1.x, p1.y);
var c2:int = [Link](p2.x, p2.y);
var c3:int = [Link](p3.x, p3.y);
var c4:int = [Link](p4.x, p4.y);
var c5:int = [Link](p5.x, p5.y);
var c6:int = [Link](p6.x, p6.y);

with (ob) {
[Link] = false;
if(c1==terre || c2==terre ||c3==terre || c4==terre)
[Link] = true;

if(rebond){
if ([Link](vit) > 0.1) {
vit *= fri;
} else {
rebond = false;
vit = 0;
}
} else {
if (vit>0) {
if(c6 == mur){
vit = -vit/2;
dy = 0;
rebond = true;
sante -= 25;
return;
}
if(c1 == mur) rotation -= vit*vit;
if(c2 == mur) rotation += vit*vit;
}
if (vit<0) {
if(c5 == mur){
vit = -vit/2;
dy = 0;
rebond = true;
sante -= 25;
return;
}
if(c3 == mur) rotation += vit*vit;
if(c4 == mur) rotation -= vit*vit;
}
}
}
}
}
}
</code>

Comme vous pouvez le voir dans les imports on n'utilisera dans cette classe que
deux choses essentielles, un BitmapData et des Points.

<code actionscript>
public function hitTest(ob:Object, map:BitmapData):void { ... }
</code>

Cette fonction sert pour le test de collision entre un objet et la ColorMap des
collisions, on lui passe donc ces deux param�tres.

<code actionscript>
var terre:int = 16711935;
var mur:int = 6750207;
</code>

Je d�fini deux variables, l'une repr�sente la couleur que doit avoir la terre sur
la ColorMap, l'autre la couleur que doivent avoir les murs.

<code actionscript>
// converti les coordonn�es des points
var p1:Point = [Link](ob.p1);
var p2:Point = [Link](ob.p2);
var p3:Point = [Link](ob.p3);
var p4:Point = [Link](ob.p4);
var p5:Point = [Link](ob.p5);
var p6:Point = [Link](ob.p6);
</code>

Notre voiture poss�de 6 points de contr�le, chacun plac� dans la voiture et ayant
donc des coordonn�es locales � cette voiture, j'ai besoin de r�cup�rer ces points
mais de les convertir en coordonn�es globales pour savoir o� chacun se situe sur la
ColorMap et non juste au sein de la voiture.

<code actionscript>
// trouve les couleurs sous les points
var c1:int = [Link](p1.x, p1.y);
var c2:int = [Link](p2.x, p2.y);
var c3:int = [Link](p3.x, p3.y);
var c4:int = [Link](p4.x, p4.y);
var c5:int = [Link](p5.x, p5.y);
var c6:int = [Link](p6.x, p6.y);
</code>

Pour chaque point je cherche la couleur qu'il survole sur la ColorMap.

<code actionscript>
with (ob) { ... }
</code>

Nous allons � pr�sent travailler directement dans notre objet, la voiture, et


modifier les param�tres en fonction du terrain.

<code actionscript>
[Link] = false;
if(c1==terre || c2==terre || c3==terre || c4==terre) [Link] = true;
</code>

Par d�faut la voiture ne freine pas, cependant si un des points de contr�le se


trouve sur de la terre la voiture est ralentie.

<code actionscript>
if(rebond){
if ([Link](vit) > 0.1) {
vit *= fri;
} else {
rebond = false;
vit = 0;
}
}
</code>
Si la voiture est en train de rebondir suite � une pr�c�dente collision (c'est
important), si sa vitesse est sup�rieur � une vitesse minimale la voiture est
ralentie, sinon on consid�re que l'action du rebond est termin�e et que la voiture
est arr�t�e.

<code actionscript>
} else {
</code>

Si elle n'est pas en train de rebondir...

<code actionscript>
if (vit>0) {
if(c6 == mur){
vit = -vit/2;
dy = 0;
rebond = true;
sante -= 25;
return;
}
if(c1 == mur) rotation -= vit*vit;
if(c2 == mur) rotation += vit*vit;
}
</code>

Si la voiture est en train d'avancer, si le point central du pare choc avant


rencontre un mur elle rebondit et elle prend du d�g�t, sa vitesse s'inverse et se
divise par deux (effet du choc) et sa direction est fig�e au centre. J'ai ajout�
une notion de d�g�ts (sante), on ne s'en servira pas pour le joueur mais pour les
adversaires, vous verrez dans quel contexte. Si le point avant gauche ou le point
avant droit touche un mur, la voiture racle contre le mur on simule �a avec une
petite rotation de la voiture dans un sens ou dans l'autre, ceci �vite de se
retrouver bloqu� face � un mur.

<code actionscript>
if (vit<0) {
if(c5 == mur){
vit = -vit/2;
dy = 0;
rebond = true;
sante -= 25;
return;
}
if(c3 == mur) rotation += vit*vit;
if(c4 == mur) rotation -= vit*vit;
}
</code>

Si la voiture est en train de reculer, on r�it�re la m�me op�ration mais cette fois
avec les points de contr�le situ�s � l'arri�re du v�hicule. Cette op�ration dans un
sens puis dans l'autre selon si la voiture avance ou recule va nous permettre de
mieux g�rer des collisions multiples, par exemple lorsque la voiture se trouve
coinc�e entre deux murs proches, on ne regarde la collision que dans le sens o� la
voiture se d�place et on �vite ainsi les situations o� la voiture se retrouve
bloqu�e � rebondir � l'infini entre les deux murs.

C'est termin� pour les collisions, bien sur vous pouvez affiner et ajouter des
facteurs qui influencent le comportement lors d'une collision, par exemple les
t�ches d'huiles, les turbos, les autres v�hicules, etc....

Nous avons vu l'essentiel, comment conduire le v�hicule et comment g�rer facilement


les collisions. Je ne vous ai pas parl� de la classe "Marqueur", on va s'en
d�barrasser tout de suite avant de passer � la seconde partie de l'exercice
concernant les adversaires.

====== Classe Marqueur ======

A la racine de votre projet cr�ez un nouveau document AS nomm� "Marqueur" et


�crivez :

<code actionscript>
package {

import [Link];

public class Marqueur extends Sprite {

public function Marqueur (X:int, Y:int) {


x = X;
y = Y;
}
}
}
</code>

Bon l� pas grand chose � dire, les marqueurs ne sont que des rep�res visuels aidant
au d�bogage, cette classe ne sert qu'� placer chaque marqueur au moment de sa
cr�ation, vous pouvez tr�s bien vous en passer.

Allez on attaque la seconde partie, les adversaires.

====== Pr�paration - partie 2 ======

Si vous avez compris tout ce que nous venons de faire dans la premi�re partie vous
devriez vous en sortir haut la main dans celle-ci. Cette fois on s'attaque aux
adversaires, la r�action des v�hicules et les collisions ne devraient pas trop
poser de probl�me car sensiblement identiques � celles du joueur � quelques d�tails
pr�s. Ce qui va nous int�resser en revanche c'est l'IA, l'intelligence de chaque
adversaire pour suivre le parcours du circuit sans avoir une trajectoire trop
parfaite, ni compl�tement al�atoire.

Avant toute chose il nous faut une nouvelle voiture � afficher pour repr�senter les
adversaires, cr�ez donc un nouveau MovieClip nomm� "Ordinateur" et exportez-le pour
AS. Dedans mettre la m�me voiture que pour le joueur (avec les m�mes contraintes et
la m�me taille) d'une couleur diff�rente.

Il nous faudra bien sur une classe "Ordinateur" pour piloter les voitures mais on
verra �a plus tard.

Si vous avez d�j� jou� � un jeu de voiture vous savez que le secret d'une course
r�ussie r�side dans la trajectoire que vous choisissez d'emprunter, un m�me virage
pouvant se passer � fond si vous l'engagez correctement, ou pas si vous y entrez
n'importe comment. Certains jeux dit "r�alistes" vous affichent sur la piste une
tra�n� lumineuse qui vous indique la meilleure trajectoire possible pour r�aliser
un record. Tous vos adversaires vont essayer de suivre au plus pr�s cette marque
afin d'optimiser leur conduite, et c'est pr�cis�ment ce dont nous allons nous
servir pour donner un chemin � suivre � l'ordinateur. Mais si l'on se contentait de
tracer un chemin et posions les voitures dessus, elle se d�placeraient comme sur un
rail et il n'y aurait plus de d�fit, on va donc n'utiliser que des points de
rep�res � atteindre en fonction de chaque virage, un point plac� � un endroit
strat�gique devient une cible � atteindre par la voiture qui va le viser. Mais cela
entra�ne un autre probl�me, comment d�terminer quel point la voiture doit viser en
fonction de sa position sur le circuit ?

La solution passe une nouvelle fois par un Bitmap qui va nous permettre de
d�terminer des zones, tant que la voiture se trouve dans une zone elle dispose d'un
point unique � atteindre pour cette zone. On va donc cr�er une nouvelle ColorMap,
mais cette fois elle ne servira que pour d�couper le circuit en zones plus petites.
Pour bien vous montrer le d�coupage voici une capture o� je superpose le terrain et
la ColorMap :

CAPTURE

Si on retire le terrain voici ce que nous obtenons :

CAPTURE

Chaque couleur repr�sente une zone, on d�terminera les points � atteindre plus
tard. Lorsqu'un adversaire contr�l� par l'ordinateur se d�place, il regarde sur
quelle zone il se trouve sur la ColorMap et r�agit en cons�quence, exactement de la
m�me mani�re que nous l'avons fait pour d�terminer les surfaces du terrain lors des
collisions. Attention, une fois de plus la ColorMap doit �tre un PNG avec une gamme
de couleurs limit�e pour s'assurer qu'il n'y ait pas de couleurs parasites li�es �
la compression, de plus vous ne devez laisser aucun trou entre les zones sinon les
voitures pourraient se retrouver bloqu�es sans savoir quoi faire.

Cr�ez donc cette nouvelle ColorMap, un simple Bitmap sous Photoshop par exemple,
donnez lui le nom de "ColormapTrajets" et exportez le pour AS.

C'est tout pour la pr�paration, passons au code.

====== Modifications ======

On va commercer par modifier l�g�rement le programme principal, �ditez votre projet


et �crivez :

<code actionscript>
var zones:Array = [14211288, 11645361, 10395294, 8750469, 7500402, 6381921,
4934475, 3552822, 2039583,12698111, 9671679, 7105791, 5197823, 2829311, 251, 223,
179, 151, 119, 91, 66, 16777215];

var cibles:Array = [new Point(54,144), new Point(162,33), new Point(254,86), new


Point(339,224), new Point(483,214), new Point(563,82), new Point(677,65), new
Point(744,208), new Point(717,312), new Point(312,424), new Point(294,457), new
Point(337,488), new Point(659,482), new Point(756,550), new Point(723,672), new
Point(632,727), new Point(512,702), new Point(438,658), new Point(369,642), new
Point(267,715), new Point(104,727), new Point(64,595)];

var i:int;
var X:int;
var Y:int;

var mapCollisions:BitmapData;
var mapTrajets:BitmapData;
var terrain:Bitmap;
var joueur:Joueur;
var ordi:Ordinateur;
var p:Point;

init();

function init():void{

mapCollisions = new ColormapCollisions();


mapTrajets = new ColormapTrajets();
terrain = new Bitmap(new Terrain());
joueur = new Joueur(75,370,mapCollisions);

addChild(terrain);
addChild(joueur);

for (i=0; i<7;i++){


X = (i%2+1)*25+25;
Y = i*20+370;
ordi = new Ordinateur(X,Y, mapTrajets,zones,cibles,mapCollisions);
addChild(ordi);
}

for each(p in cibles){


addChild(new Marqueur(p.x,p.y));
}
}
</code>

Le premier tableau repr�sente les couleurs de chaque zone du d�coupage du terrain,


le second contient chaque point cible � atteindre pour une zone pr�cise. Les deux
tableaux correspondent exactement, c'est � dire que pour la zone 1 vous avez une
couleur qui correspond au point 1 du tableau des cibles. Chaque point est plac� �
la main, c'est � dire que �a va �tre � vous de minutieusement placer les points sur
le circuit et d'�tudier la trajectoire id�ale en prenant en compte le comportement
des voitures. Les points se placent � l'intersection de deux zones et � la fin de
la zone concern�e afin que le joueur cible ce point tant qu'il se trouve sur la
zone.

On cr�e ensuite la map des trajets qu'on vient de dessiner, ainsi qu'une variable
"ordi" qui servira � placer les adversaires, et un point "p" qui servira uniquement
� placer des marqueurs sur chaque point r�f�renc� dans le tableau des cibles, cela
va vous permettre de voir o� se trouvent les points que vous avez pos�.

Dans la fonction "init", � part le fait d'initialiser la nouvelle ColorMap, on cr�e


une boucle pour poser 7 adversaires et les placer, vous noterez que chaque
adversaire d�pend d'une classe "Ordinateur" � laquelle on passe des param�tres qui
sont : la position, la ColorMap des trajets, les zones, les cibles et la ColorMap
des collisions.

Enfin, pour chaque cible on pose un marqueur sur le circuit afin de mieux les voir
tant qu'on travaille.

Allez on attaque le code...

====== Classe Ordinateur ======

A la racine de votre projet cr�ez un nouveau document AS nomm� "Ordinateur" et


�crivez :
<code actionscript>
package {

import [Link];
import [Link];
import [Link];
import [Link];

public class Ordinateur extends MovieClip {

private const W:Number = width/2;


private const H:Number = height/2;

private var p:Point;


private var cible:Point
private var cibles:Array;
private var portions:Array;
private var col:Collisions;
private var mapTrajets:BitmapData;
private var mapCollisions:BitmapData;

private var dx:int;


private var dy:int;
private var zone:int;
private var _X:Number;
private var _Y:Number;
private var dir:Number;
private var acc:Number;
private var diff:Number;
private var vitMax:Number;
private var dirMax:Number;
private var moveX:Number;
private var moveY:Number;
private var angle:Number;
private var idealX:Number;
private var idealY:Number;
private var glisse:Number;
private var angleActuel:Number;
private var angleCible:Number;

public var sante:int;


public var vit:Number;
public var fri:Number;
public var rebond:Boolean;
public var freine:Boolean;

public var p1:Point = new Point(W, -H);


public var p2:Point = new Point(-W, -H);
public var p3:Point = new Point(W, H);
public var p4:Point = new Point(-W, H);
public var p5:Point = new Point(0, H);
public var p6:Point = new Point(0, -H);
public var p7:Point = new Point(0, 0);

public function Ordinateur (X:int, Y:int, mapTrajectoires:BitmapData,


zones:Array, cib:Array, mapColl:BitmapData) {
mapTrajets = mapTrajectoires;
mapCollisions = mapColl;
col = new Collisions();
portions = zones;
cibles = cib;
_X = X;
_Y = Y;
init(X, Y);
}

function init(X:int, Y:int):void {


x = X;
y = Y;
dx = 0;
dy = 0;
vit = 0;
dir = 0;
fri = .95;
acc = .30;
angle = 0;
moveX = 0;
moveY = 0;
sante = 100;
vitMax = 5;
dirMax = 1.5;
glisse = .12;
rotation = 0;
rebond = false;
freine = false;
angle = -[Link] / 2;
addEventListener(Event.ENTER_FRAME, update);
}

private function update(e:Event):void {

// d�tecte le sol
p = [Link](this.p7);// converti les coordonn�es des
points
zone = [Link](p.x, p.y);// trouve les couleurs sous
les points
cible = cibles[[Link](zone)];// trouve le point �
cibler

// g�re les collisions


[Link](this, mapCollisions);

// limitation de vitesse selon les zones


if (zone == 6381921) vitMax = 3;
else if (zone == 179) vitMax = 2;
else if (zone == 151) vitMax = 3;
else vitMax = 5;

// d�placements
if (!rebond) {
dx = cible.x-x;
dy = cible.y-y;
angleCible = angle360(Math.atan2(dy, dx) /
[Link]*180);
angleActuel = angle360(angle / [Link]*180);
diff = angleActuel - angleCible;
if (diff <= 0) diff += 360 else diff -= 360;
diff = angle360(diff);
if (diff < 180) dir -= 0.2;
if (diff > 180) dir += 0.2;
if (dir > 1.5) dir = 1.5;
if (dir < -1.5) dir = -1.5;
if (vit < vitMax) vit += 0.5;
if (freine) vit *= 0.9;
vit *= fri;
idealX = [Link](angle)*vit;
idealY = [Link](angle)*vit;
moveX += (idealX-moveX)*glisse;
moveY += (idealY-moveY)*glisse;
x += moveX;
y += moveY;
} else {
moveX *= 0.7;
moveY *= 0.7;
x -= moveX;
y -= moveY;
}

// tourner
angle += dir*vit*.030;
if(diff>3 && diff<357) rotation = angle * 180/[Link]+90;
dir -= (dir * 0.1);

// gestion des degats


if (sante <= 0) {
removeEventListener(Event.ENTER_FRAME, update);
init(_X, _Y);
}
}

// convertir un angle sur 360 degres


private function angle360(t:Number):Number {
t %= 360;
if(t < 0) t+= 360;
return t
}
}
}
</code>

La construction est globalement la m�me que pour le joueur, on va donc se passer


d'�tudier les variables, vous verrez les nouvelles au fur et � mesure. Certains se
demanderont peut-�tre pourquoi je ne cr�e pas une classe g�n�rique "V�hicule" et
deux classes "Joueur" et "Ordinateur" qui �tendent la classe "V�hicule" afin de
clarifier mon code. Tout simplement parce que nous ne sommes pas en train
d'apprendre � faire de la POO propre, mais de voir une m�thode pour cr�er un jeu de
course. C'est moins compliqu� pour moi de r��crire tout le code et de bien s�parer
les choses lorsque je tente de vous expliquer l'exercice, que de faire des
modifications constantes avec des retours dans des classes qu'on � d�j� vues
auparavant. Bref, ce n'est pas le sujet qui nous int�resse, le but des exercices
n'est pas de vous donner un moteur tout pr�t, mais des sujets de r�flexions autour
de techniques d�di�es au jeu vid�o, mais sachez que vous pouvez bien sur simplifier
tout �a selon votre niveau en programmation et votre ma�trise de la POO.

On refait donc ce qu'on � d�j� fait avec le joueur, c'est � dire cr�er les
diff�rentes variables (friction, vitesse, etc....), et en ajouter de nouvelles que
l'on d�taillera en cours de route, puis placer non plus 6 mais 7 points de
contr�le. En effet pour les ordinateurs j'ai ajout� un point central � la voiture,
vous verrez pourquoi un peu plus tard.

<code actionscript>
public function Ordinateur (X:int, Y:int, mapTrajectoires:BitmapData, zones:Array,
cib:Array, mapColl:BitmapData) {
mapTrajets = mapTrajectoires;
mapCollisions = mapColl;
col = new Collisions();
portions = zones;
cibles = cib;
_X = X;
_Y = Y;
init(X, Y);
}
</code>

Lorsqu'un adversaire est cr��, on lui passe les diff�rents maps dont il a besoin
pour les collisions et le trajet ainsi que les points cibles, et on enregistre sa
position sur la grille de d�part. Notez ici que pour bien faire il faudrait ajouter
un �couteur pour savoir quand la voiture est ajout�e � la liste d'affichage, mais
on va s'en passer pour l'exercice.

<code actionscript>
function init(X:int, Y:int):void {
x = X;
y = Y;
dx = 0;
dy = 0;
vit = 0;
dir = 0;
fri = .95;
acc = .30;
angle = 0;
moveX = 0;
moveY = 0;
sante = 100;
vitMax = 5;
dirMax = 1.5;
glisse = .12;
rotation = 0;
rebond = false;
freine = false;
angle = -[Link] / 2;
addEventListener(Event.ENTER_FRAME, update);
}
</code>

On initialise toutes les variables et on place la voiture sur le circuit.

<code actionscript>
private function update(e:Event):void { ... }
</code>

La fonction qui met � jour l'adversaire.

<code actionscript>
// d�tecte le sol
p = [Link](this.p7);// converti les coordonn�es des points
zone = [Link](p.x, p.y);// trouve les couleurs sous les points
cible = cibles[[Link](zone)];// trouve le point � cibler
</code>

La voiture � besoin de d�tecter la zone qu'elle est en train de traverser, c'est �


�a que sert le point central que j'ai ajout�. Je commence donc par convertir les
coordonn�es du point en coordonn�es globales, puis je r�cup�re la couleur de la
zone que la voiture traverse, et le point qu'elle doit cibler pour cette zone.

<code actionscript>
// g�re les collisions
[Link](this, mapCollisions);
</code>

La gestion des collisions est exactement la m�me que pour le joueur.

<code actionscript>
// limitation de vitesse selon les zones
if (zone == 6381921) vitMax = 3;
else if (zone == 179) vitMax = 2;
else if (zone == 151) vitMax = 3;
else vitMax = 5;
</code>

L'autre int�r�t des zones c'est de pouvoir influer sur la vitesse de la voiture,
l'ordinateur n'ayant pas appris les notions de vitesse relative, de courbe, de
forces, et globalement de physique, il ne sait pas quand il doit ralentir et fonce
tout le temps � fond. Gr�ce aux zones nous pouvons lui signifier que dans une
certaine zone sa vitesse doit �tre limit�e, ce qui lui permet de mieux aborder le
virage suivant. L� aussi ce sera � vous de t�tonner pour trouver les bonnes
vitesses pour chaque zone en fonction du comportement de la voiture. M�fiez-vous
�galement des couleurs, vous n'aurez sans doute pas le m�me nombre de couleurs pour
tous vos circuits et une m�me couleur n'aura pas forc�ment la m�me action sur le
comportement de la voiture d'un circuit � l'autre. L� j'ai cod� �a comme un sauvage
en dur directement dans la classe "Ordinateur" pour vous montrer le principe en
trois lignes, mais bien sur c'est � vous de cr�er un tableau par circuit comprenant
toutes les zones de freinage, voire de cr�er une nouvelle ColorMap par circuit pour
y coller des zones de freinages qui peuvent �tre diff�rentes des zones utilis�es
pour le trajet, les deux n'�tant pas forc�ment li�es, bref sur le m�me principe
vous pouvez faire un peu ce que vous voulez pour obtenir une plus grande pr�cision.

Revenons � nous moutons et voyons de plus pr�s comment la voiture doit se d�placer.

<code actionscript>
// d�placements
if (!rebond) {
dx = cible.x-x;
dy = cible.y-y;
angleCible = angle360(Math.atan2(dy, dx) / [Link]*180);
angleActuel = angle360(angle / [Link]*180);
diff = angleActuel - angleCible;
if (diff <= 0) diff += 360 else diff -= 360;
diff = angle360(diff);
if (diff < 180) dir -= 0.2;
if (diff > 180) dir += 0.2;
if (dir > 1.5) dir = 1.5;
if (dir < -1.5) dir = -1.5;
if (vit < vitMax) vit += 0.5;
if (freine) vit *= 0.9;
vit *= fri;
idealX = [Link](angle)*vit;
idealY = [Link](angle)*vit;
moveX += (idealX-moveX)*glisse;
moveY += (idealY-moveY)*glisse;
x += moveX;
y += moveY;
} else {
moveX *= 0.7;
moveY *= 0.7;
x -= moveX;
y -= moveY;
}
</code>

La grosse diff�rence avec le joueur c'est les touches de direction, le joueur


choisi de lui m�me la direction qu'il doit suivre, mais l'ordinateur va suivre un
chemin qu'on lui a balis� avec des cibles � atteindre. On commence donc par
regarder la direction � suivre sur chaque axe en fonction de la position actuelle
et de la position de la cible � atteindre.

Un premier probl�me li� � l'Actionscript survient, tous les angles sont compris
entre 0 et 180 ou 0 et -180, AS ne travaillant pas avec des angles sur 360 degr�s.
Or pour savoir o� se trouve une cible par rapport � l'orientation actuelle de la
voiture il nous faut raisonner sur des angles � 360 degr�s. Pour ce faire on va
utiliser une petite fonction que je vous d�taille tout de suite et qui a pour but
de convertir un angle sur 360 degr�s.

<code actionscript>
// convertir un angle sur 360 degres
private function angle360(t:Number):Number {
t %= 360;
if(t < 0) t+= 360;
return t
}
</code>

C'est tout b�te mais �a va nous rendre un immense service, revenons aux
d�placements de notre voiture.

On cherche l'angle de la cible par rapport � la voiture et l'angle actuel de la


voiture, les deux sur un cercle de 360 degr�s. On regarde la diff�rence entre ces
deux angles, on fait une petite correction pour inverser l'angle trouv�, puis on le
recalcule sur 360 degr�s (pour le cas o� il serait n�gatif). C'est de la trigo et
du calcul d'angle, on ne va pas entrer dans les d�tails car ce n'est pas ce qui
nous int�resse vraiment ici, le but est juste de trouver l'angle r�sultant entre
l'angle actuel et l'angle cibl�.

On va ensuite faire tourner la voiture selon l'angle qu'on � trouv�, s'il est
inf�rieur � 180 on tourne vers la gauche et s'il est sup�rieur on tourne � droite,
180 �tant donc l'angle pr�cis � atteindre sur notre cercle, si la voiture est
orient�e dessus on ne tourne pas bien sur. Plut�t que de dire "tourner" je devrait
dire "corriger la trajectoire" car c'est en fait ce qu'il se passe ici, on corrige
la trajectoire pour essayer d'atteindre l'angle optimal.

On limite l'angle de braquage, �a c'est le comportement normal de la voiture, et on


stipule � l'ordinateur que tant qu'il na pas atteint sa vitesse maximale il doit
acc�l�rer, il acc�l�re donc toujours � fond selon la vitesse limite de chaque zone.
Comme pour le joueur on fait entrer en jeu le freinage et la friction, les
comportements normaux de la voiture. Puis on cherche le mouvement id�al et le
mouvement r�el, qui d�pend du "facteur d'adh�rence" et enfin on d�place la voiture.
Notez que cette fois aussi on regarde si la voiture est en train de rebondir suite
� une collision ou pas, j'ai l�g�rement augment� le freinage car un �tre humain
aurait le r�flexe de rester appuy� sur l'acc�l�rateur pour repartir plus vite alors
que l'ordinateur ne fait rien tant qu'il n'a pas re�ut d'instructions dans ce sens,
un petit artifice qui en vaut un autre...

<code actionscript>
// tourner
angle += dir*vit*.030;
if(diff>3 && diff<357) rotation = angle * 180/[Link]+90;
dir -= (dir * 0.1);
</code>

Cette petite partie est importante, l'angle actuel de la voiture dont on se sert
pour d�terminer le mouvement, d�pend de la direction, de la vitesse et du temps de
r�action du pilote, plus ce temps est long et plus le pilote tournera tard, plus il
est court et plus le pilote corrigera vite sa direction. Dans les faits ce n'est
pas exactement ce que fait cette formule, mais c'est la meilleure mani�re que j'ai
trouv� de vous l'expliquer simplement. Imm�diatement apr�s on va v�rifier que la
diff�rence entre l'angle actuel de la voiture et l'angle de la cible est sup�rieure
� 3 degr�s, ceci va �viter des corrections permanentes de la trajectoire pour des
angles assez petits que la voiture n'arrivera jamais a atteindre. Et enfin comme
pour le joueur, la direction revient lentement au centre si on cesse de tourner.

<code actionscript>
// gestion des degats
if (sante <= 0) {
removeEventListener(Event.ENTER_FRAME, update);
init(_X, _Y);
}
</code>

Dernier petit artifice, les d�g�ts, ils me servent essentiellement � �viter qu'une
voiture reste bloqu�e derri�re un mur trop longtemps. En effet il se peut qu'un mur
emp�che la voiture d'atteindre sa cible, pour m'�viter de nombreuses lignes de code
pour palier � cet inconv�nient, je vais tout simplement r�duire la sant� du
v�hicule quand il tape un mur, lorsque sa sant� est � z�ro la voiture est
repositionn�e sur la grille de d�part.

Et nous avons termin� ce petit exercice.

====== Conclusion ======

Pour cet exercice j'ai utilis� une technique qui s'appuie sur des Bitmaps, mais
sachez que vous pouvez les remplacer par des tuiles ou tout autre construction de
votre cru si vous trouvez plus simple. Mon but n'�tait encore une fois de vous
montrer LA solution parfaite, mais une m�thode utilis�e dans beaucoup de jeux pour
cr�er une IA pour un jeu de course. Si vous souhaitez affiner le comportement des
voitures pilot�es par l'ordinateur vous pouvez ajouter d'autres points de contr�le,
m�me si ils se trouvent en dehors de la voiture, par exemple un point plac� � une
cinquantaine de pixels devant la voiture pourrait permettre de d�tecter des
obstacles avant d'�tre dessus et ainsi de corriger la trajectoire pour les �viter
ou au contraire aller dessus (bonus, turbos, ...). Ce m�me point pourrait servir
pour anticiper les collisions, voire d�tecter une sortie de piste si la trajectoire
n'est pas corrig�e rapidement. Bref, plus vous aurez de points de contr�les bien
plac�s et plus vous pourrez affiner les comportements de l'ordinateur et ajouter
des facteurs al�atoire pour que chaque voiture r�agisse diff�remment des autres.
====== Les sources ======

<DOWNLOAD>
{{:tutoriaux:flashplatform:jeux:course:course_mb.zip|}} version CS6
</DOWNLOAD>

<DOWNLOAD>
{{:tutoriaux:flashplatform:jeux:course:course_mb_cs5.zip|}} version CS5
</DOWNLOAD>

Vous aimerez peut-être aussi