vendredi 18 septembre 2015

Création d'un jeu de serpent (snake) en AS2

I. Présentation du jeu

Adobe Flash (anciennement Macromedia Flash) est un logiciel multimédia utilisé pour créer du contenu interactif pour les sites Internets, des jeux vidéo,
des animations, etc. 
Cet article est destiné à toute personne souhaitant développer des jeux vidéo en Flash.
Il présente une étude expliquant la création d'un jeu de serpent en ActionScript2.0. 

I-A. Principe du jeu

Je suppose que vous connaissez déjà le principe du jeu.
Il s'agit d'un serpent qu'on peut déplacer avec les touches de direction du clavier. Le serpent augmente de taille s'il croise l'un des deux types d'objets suivant qu'on peut appeler des bonus.

Image non disponible La taille du serpent augmente d'un élément.


Image non disponible La taille du serpent augmente de deux éléments.


Si le serpent dépasse les quatres extrémités de la surface du jeu ou fait une collision avec lui même, alors le jeu se termine.
Le déplacement du serpent peut se faire dans les huit directions :
Image non disponible

I-B. Aperçu du Jeu

Voici un aperçu de la surface du jeu.

Image non disponible

I-B-1. Essayer le Jeu

Vous pouvez essayer le jeu à cette adresse : ftp://ftp-developpez.com/slim-boukettaya/sources/Snake.swf
Au début, cliquez avec la souris sur l'animation pour lui donner le focus et utilisez ensuite les touches directionnelles du clavier pour jouer.

II. Notions à maîtriser avant de commencer

II-A. Classe Array

D'après la documentation officielle, la classe Array vous permet d'accéder aux tableaux indexés et de les manipuler. Un tableau indexé est un objet dont les propriétés sont identifiées par un nombre représentant leur position au sein de celui-ci. Ce nombre est appelé index. Tous les tableaux indexés sont basés sur zéro, ce qui signifie que le premier élément du tableau est [0], le deuxième est [1], etc. Pour créer un objet Array, utilisez le constructeur new Array(). Pour accéder aux éléments d'un tableau, utilisez l'opérateur d'accès au tableau ([]).
Exemple :

Sélectionnez

var oneArray:Array = new Array("a", "b", "c");
var twoArray:Array = oneArray; // Les deux variables array se rapportent au même tableau.
twoArray[0] = "z"; 
trace(oneArray); // Renvoie : z,b,c.
Parmi les méthodes de la classe Array qu'on va utiliser dans la suite de l'article, on cite la fonction push() :

Sélectionnez

push(value: Object) : Number
qui ajoute un ou plusieurs éléments à la fin d'un tableau et renvoie la nouvelle longueur du tableau.
Exemple :

Sélectionnez

var myPets_array:Array = new Array("cat", "dog");
var pushed:Number = myPets_array.push("bird", "fish");
trace(pushed); // Affiche 4.
Et la fonction splice() :

Sélectionnez

splice(startIndex: Number, [deleteCount: Number], [value: Object]) : Array
qui supprime des éléments dans un tableau.
Exemple :


var myPets_array:Array = new Array("cat", "dog", "bird", "fish");
trace(myPets_array.splice(1)); // Affiche dog,bird,fish.
trace(myPets_array); // cat
 

II-B. Classe MovieClip

Lorsqu'on veut insérer une animation dans la scène principale, on peut dès lors utiliser la classe MovieClip. Chaque objet Movieclip admet une barre scénarios (time-line) indépendante de celle de la scène principale ce qui permet de faire toute sorte de traitement dans un objet MovieClip.
Vous trouvez plus d'information à cette adresse : http://help.adobe.com/fr_FR/FlashPlatform/reference/actionscript/2/help.html?content=Part2_AS2_LangRef_1.html
Parmi les méthodes de la classe MovieClip qu'on va utiliser, la méthode hitTest() :

hitTest(target:Object):Boolean
qui évalue le clip pour savoir s'il recouvre ou recoupe la zone active identifiée par les paramètres de coordonnées target.
Cette méthode sera utilisée pour tester les collisions du serpent avec les bords de la surface du jeu.
Une deuxième méthode à utiliser est removeMovieClip() qui permet de supprimer une occurrence de clip créée avec l'une des méthodes suivantes :

Sélectionnez

duplicateMovieClip(), 
MovieClip.duplicateMovieClip(), 
MovieClip.createEmptyMovieClip() 
MovieClip.attachMovie().
 
On va utiliser pour notre jeu la méthode :

Sélectionnez

attachMovie(id: String, name: String, depth: Number, [initObject: Object]) : MovieClip
qui sélectionne un symbole dans la bibliothèque identifiée par le paramètre id correspondant au nom de liaison d'un clip de la bibliothèque et l'associe au clip défini par le paramètre name à un niveau de profondeur depth.

II-C. Classes personnalisées

On peut créer des classes en ActionScript 2.0. Chaque classe doit être définie dans un fichier externe qui porte le nom de la classe avec l'extesion.as.
Pour créer une classe en Flash, il faut suivre ces étapes :
  1. Sélectionner le menu Fichier ;
  2. Commande Nouveau ;
  3. Fichier ActionScript ;
  4. Valider avec Ok.
Exemple de classe :

Sélectionnez

class HelloWord
{
 var chaine : String;
 
 // function constructeur
 public function HelloWord (message : String)
 {
  chaine = message
 }
}     
 

II-D. Classe key

Pour créer des applications interactives qui exécutent des traitements suite aux appuis des utilisateurs sur les touches du clavier, il faut avoir recours à la classe key et utiliser ses fonctions et ses propriétés. Exemple :

Sélectionnez

if(Key.isDown(key.RIGHT))
     {
  //traitement qui sera exécuté dés l'appui sur la flèche Droit
     }
   else if(Key.isDown(key.LEFT))
     {
  //traitement qui sera exécuté dés l'appui sur la flèche Gauche
     }
   else if(Key.isDown(key.UP))
     {
  //traitement qui sera exécuté dés l'appui sur la flèche Haut
     }
   else if(Key.isDown(key.DOWN))
     {
  //traitement qui sera exécuté dés l'appui sur la flèche Bas
     }
 

III. Création du jeu

III-A. Création de la surface du jeu

Au début, il faut commencer par la création de la surface du jeu :

Image non disponible

On doit choisir une taille pour la surface du jeu :
j'ai opté pour les dimensions 500x300 qui est en fait un choix personnel.
Pour tester si le serpent a dépassé les limites, j'ai pensé à placer quatre rectangles graphiques sur les bornes de la surface.
Ces rectangles sont intitulés : mur_haut, mur_bas, mur_droit, mur_gauche.
Chaque rectangle est un clip, ce qui permet par conséquent d'utiliser la méthode hitTest() dans la fonction collision_mur() pour tester les collisions :

Sélectionnez

function collision_mur()
{
// tete_snake est le clip qui présente la tête du serpent.
if( tete_snake.hitTest(mur_haut) or tete_snake.hitTest(mur_bas) or tete_snake.hitTest(mur_gauche) or tete_snake.hitTest(mur_droit))
    return true;
    else
   return false;
} 
 
Cela pourra se faire autrement si on compare les cordonnées de la tête du serpent avec les cordonnées x et y de chaque mur.
Par exemple on pourra écrire cette instruction :

Sélectionnez

if( tete.snake._x==mur_haut._x and tete_snake._y == mur_haut._y )
//le serpent a dépassé la limite d'en haut.
 

III-B. Ajout d'une image de fond

On peut ajouter une image de fond pour décorer un peu plus notre jeu.
Cette image doit être placée sur un calque et ne doit pas couvrir les rectangles correspondants aux murs des bords.

Image non disponible

III-C. L'objet serpent

Le serpent est composé de trois parties :
  • La tête.
  • Le corps.
  • La queue.
Pour avoir un contrôle complet sur ces trois parties, il faut penser à l'utilisation des clips.
En fait, pour un clip, on peut récupérer son abscisse, son ordonnée et par conséquent, on peut le déplacer si on change les valeurs de ces cordonnées.
Chaque élément sera donc représenté par un clip, et on aura besoin d'un premier pour la tête, un deuxième pour la queue et de plusieurs clips représentant le corps suivant le nombre de bonus obtenus par le serpent.

III-D. Préparation du corps du serpent

La tête peut être un cercle colorié par un dégradé pour donner l'effet 3D. J'ai voulu donner un peu de réalisme au jeu c'est pourquoi j'ai essayé d'utiliser des images pour créer le serpent.
Si vous êtes graphiste, vous pouvez dessiner les objets graphiques du jeu avec un logiciel dédié comme Adobe Illustrator, et les importer dans la bibliothèque.
Mes recherches sur Google m'ont donné ces deux images :

Image non disponible

et avec quelques modifications de l'image de l'élément du corps, on obtient la queue :

Image non disponible

Finalement, pour créer ces trois éléments, il faut créer trois clips vides dans la bibliothèque et mettre dans chacun l'une de ces trois photos.
La tête du serpent va être placée manuellement avec un glisser-déposer sur la scène (ca peut se faire aussi d'une façon dynamique), par contre la queue et les éléments constituant le corps seront ensuite intégrés dynamiquement à la scène avec du code ActionScript en utilisant la méthode attachMovie(). Comme on a vu au début de l'article, cette méthode crée sur la scène une occurrence d'un clip de la bibliothèque. Elle s'utilise de la façon suivante :

Sélectionnez

contenant.attachMovie("nom du clip dans la bibliothèque","nom à donner à l'occurrence du clip", profondeur) ;
Il faut attirer l'attention ici sur le paramètre 'nom du clip dans la bibliothéque' qui doit être le nom de liaison du clip de la bibliothèque qu'on peut spécifier dans cette fenêtre :

Image non disponible

et qui est obtenu après avoir cliqué avec le bouton droit de la souris sur le clip concerné et avoir choisi la commande "liaison".
Voilà donc, chacun de ces trois clips doit avoir un nom de liaison pour pourvoir être placé sur la scène avec la méthode attachMovie().

III-E. Préparation des bonus

Les bonus sont eux aussi des clips, ce qui permet d'utiliser la méthode hitTest() pour tester la collision de la tête du serpent avec ces derniers quand il seront placés sur la scène.
De la même façon que pour la gestion du serpent, il faut créer un clip vide dans la bibliothèque, par type de bonus et y placer une image parmi ces deux :

Image non disponible

Avec un peu d'humour, on peut dire que notre serpent était herbivore.
L'ajout de ces clips dans la scène sera dynamiquement fait avec la méthode attachMovie().
Après avoir préparé les différents éléments graphiques constituant le jeu, passons maintenant à l'écriture du code permettant la manipulation de tous ces éléments.

IV. Implémentation

Généralement, un code ActionScript peut être placé dans trois endroits différents :
  • dans un fichier externe ;
  • sur une image des scénarios ;
  • sur un bouton, un clip, etc.
Pour simplifier les choses, j'ai choisis de placer le code sur des images clés du scénario.
Pour mieux organiser le code, on peut utiliser un nouveau calque CODE.

IV-A. Déplacement de la tête du serpent

Au début, il faut placer le clip correspondant à la tête du serpent au milieu de la scène.
Ensuite, il faut donner un nom à cette occurrence. On va utiliser l'identifiant tete_snake.
Pour déplacer la tête, on doit utiliser les touches directionnelles du clavier. La gestion des appuis clavier est définie dans la fonction mouvement_snake().
Le serpent va se déplacer suivant les huit directions. Cependant sa tête et son corps ne doivent pas garder le même sens et le même angle durant son mouvement suivant ces différentes directions. Ils doivent s'orienter suivant la sens de déplacement du serpent comme le montre la figure suivante :


Image non disponible

La variable sens est utilisée pour déterminer le sens du mouvement du serpent. Elle peut prendre huit valeurs suivant le sens de mouvement. Ces valeurs correspondent en fait aux numéros des images clés dans le clip tête_snake sur lesquelles on va faire une rotation de la tête du serpent pour quelle corresponde à l'une des images dans la figure précédente.
Le scénario du clip tête_snake doit donc contenir huit images clés comme le montre la figure suivante

Image non disponible

Pour naviguer entre ces différentes états, on peut avoir recours à la méthode gotoAndStop(num_image_clé).

Sélectionnez

tete_snake.gotoAndStop(20);
Finalement, la fonction mouvement_snake() devra contenir le code suivant :

Sélectionnez

if(Key.isDown(key.RIGHT) and Key.isDown(key.UP))
     {
  sens = 20;
  tete_snake.gotoAndStop(20);
     }
 else if( Key.isDown(key.RIGHT)  and Key.isDown(key.DOWN) )
     {
  sens = 30;
  tete_snake.gotoAndStop(30);
     }
 else if( Key.isDown(key.RIGHT) and !( Key.isDown(key.UP) ) and !(  Key.isDown(key.DOWN) ) )
     {
  sens = 1;
  tete_snake.gotoAndStop(1);
     }
 
   else if( Key.isDown(key.LEFT)and (Key.isDown(key.UP)) )
     {
  sens = 25;
  tete_snake.gotoAndStop(25);
     }
    else if( Key.isDown(key.LEFT) and (Key.isDown(key.DOWN)) )
     {
  sens = 35;
  tete_snake.gotoAndStop(35);
     }
     else if( Key.isDown(key.LEFT) and !(Key.isDown(key.DOWN)) and !(Key.isDown (key.UP))   )
     {
    sens = 10;
    tete_snake.gotoAndStop(10);
     }
  else if( Key.isDown(key.DOWN) and !(Key.isDown(key.LEFT)) and !(Key.isDown (key.RIGHT))   )
     {
    sens = 5;
    tete_snake.gotoAndStop(5);
     }
 
   else if( Key.isDown(key.UP) and !(Key.isDown(key.LEFT)) and !(Key.isDown (key.RIGHT))   )
     {
    sens = 15;
    tete_snake.gotoAndStop(15);
     }
   if(sens ==1) tete_snake._x +=10;
 else if (sens == 5)  tete_snake._y +=10;
 else if (sens == 10) tete_snake._x -=10;
 else if (sens == 15) tete_snake._y -=10;
 else if (sens == 20) {tete_snake._y -=5;tete_snake._x +=5;}
 else if (sens == 25) {tete_snake._y -=5;tete_snake._x -=5;}
 else if (sens == 30) {tete_snake._y +=5;tete_snake._x +=5;}
 else if (sens == 35) {tete_snake._y +=5;tete_snake._x -=5;}
}
 
Rappelons que le code du jeu sera placé dans des images scénarios sur le calque CODE. Ce code sera donc exécuté à chaque passage de la tête de lecture du flash player par l'image contenant le code.
Vous devez donc écrire la fonction mouvement_snake() sur la première image du scénario (toutes les définitions des méthodes doivent être faites sur cette image), quant à l'appel de cette fonction, il doit se faire dans la deuxième image du scénario.
L'exécution des instructions doit être permanente tant que le jeu n'est pas fini. On peut donc utiliser le gestionnaire d'événement onEnterFrame :

Sélectionnez

stop();
onEnterFrame = function()
{
    mouvement_snake();
    collision_bonus();
    dessiner_snake();
};

IV-B. Affichage des bonus sur la scène

Comme expliqué au début du chapitre, il y a deux objets qui présentent le bonus que le serpent doit atteindre pour augmenter sa taille.
La position de chacun de ces deux objets étant aléatoire et changeable, elle ne doit pas dépasser les limites de la surface du jeu qui est de 500 pixels en largeur et 320 pixels en hauteur.
De plus, la surface du jeu est définie au point supérieur gauche de coordonnées (40,20).
Deux fonctions ( affhcier_bonus_1 et afficher_bonus_2 ) doivent être créés pour regrouper les instructions de gestion de l'emplacement des bonus sur la scène :

Sélectionnez

 
function aléatoire(min:Number, max:Number):Number 
{
       return (max-min)*Math.random()+min;
}
 
// utiliser pour ne pas afficher un bonus sur le corps du serpent.
function  existePosition(tab:Array,position: flash.geom.Point,taille_bonus:Number)
{
   l= taille_bonus/2;
   for(var i=0; i<tab.length ; i++)
   if( 
   (tab[i].posX >= position.x -l) and  (tab[i].posX <= position.x+l) and(tab[i].posY >= position.y -l) and  (tab[i].posY <= position.y+l) 
   )
         return true;
 
   return false;
}
 
function afficher_bonus_1() 
{
 // pour afficher le bonus sur la surface de déplacement du serpent
 // les limites de la surface en x : 59 ---> 552 en y : 56 ---> 340
 Xbonus1 = aléatoire(59, 552);
 Ybonus1 = aléatoire(56, 340);
 
 var posBonus:flash.geom.Point = new flash.geom.Point(Xbonus1,Ybonus1);
 
 // pour ne pas afficher un bonus sur le corsp du serpent.
 if( !(existePosition(array_position_corp,posBonus ,20)))
 {
  //je vais laisser le méme niveau (-1) (car le 0 est occupé par les élement corps )pour que le nouveau bonus remplace l'ancien
  attachMovie("bonus_1", "bonus_1", 100);
  bonus_1._x = Xbonus1;
  bonus_1._y = Ybonus1;
 }
 else 
  afficher_bonus_1();
}
 
 
 
function afficher_bonus_2() 
{
 // pour afficher le bonus sur la surface de déplacement du serpent
 // les limites de la surface en x : 59 ---> 552 en y : 56 ---> 340
 
 Xbonus2 = aléatoire(59, 552);
 Ybonus2 = aléatoire(56, 340);
 
 
 var posBonus:flash.geom.Point = new flash.geom.Point(Xbonus2,Ybonus2);
 
 // pour ne pas afficher un bonus sur le corsp du serpent.
 if( !(existePosition(array_position_corp,posBonus ,30)))
 {
  //je vais laisser le méme niveau (-1) (car le 0 est occupé par les élement corps )pour que le nouveau bonus remplace l'ancien
  attachMovie("bonus_2", "bonus_2", 200);
  bonus_2._x = Xbonus2;
  bonus_2._y = Ybonus2;
 }
 else 
 
  afficher_bonus_2();
}
L'appel de ces deux fonctions doit être fait de façon régulière et après un certain temps de latence.
On peut donc utiliser la méthode setInterval() qui permet d'appeler une fonction ou une méthode d'un objet à des intervalles périodiques pendant la lecture d'un fichier SWF.

Sélectionnez

 //appel à la fonction 
 //afficher_bonus_1  à chaque 3 secondes.
 monBonus1 = setInterval( afficher_bonus_1 , 3000) ;
 
 //appel à la fonction 
 //afficher_bonus_2  à chaque 5 secondes.
 monBonus2 = setInterval( afficher_bonus_2 , 5000) ;
 
L'ensemble du code présenté dans cette partie doit être placé dans la première image du scénario.
À ce niveau, la tête du serpent se déplace bien sur la scène mais la collision avec les objets bonus n'est pas détectée.

IV-C. Détection des bonus

Rappelons que tous les objets graphiques constituant le jeu sont des clips. On peut donc profiter des services de la méthode hitTest() pour tester les collisions.
Si la tête entrelace un objet bonus, alors sa taille augmente. On utilise alors une variable taille_snake pour déterminer la taille actuelle du snake.
Après un contact avec la tête du serpent, le bonus doit disparaître de la scène, ce qui nous ammène à penser à utiliser la fonction removeMovieClip().
Les instructions de traitement sont regroupées dans la fonction collision_bonus() :

Sélectionnez

function collision_bonus()
{
 if(tete_snake .hitTest(bonus_1))
 {
 taille_snake +=1; // nouveau morceau du corp;
 bonus_1.removeMovieClip();
 taille_snake +=1; // place réservée à la queue du snake
 score +=1;
 }
   if(tete_snake .hitTest(bonus_2))
   {
 taille_snake +=2; // nouveau morceau du corp;
 bonus_2.removeMovieClip();
 taille_snake +=1; // place réservée à la queue du snake
 score +=2;
   }
}
 
L'appel de cette méthode doit se faire dans l'image 2 du scénario après la fonction de gestion de déplacement du serpent mouvement_snake() puisque la détection du contact avec les bonus se fait d'une façon itérative après chaque mouvement du serpent.

IV-D. Dessin du serpent

Cette partie est la plus importante de l'article et au cours de celle-ci je vais expliquer l'idée que j'ai suivie pour gérer l'augmentation de la taille du serpent à chaque contact avec un objet bonus.
Durant son mouvement, le serpent passe d'un point à un autre. La vitesse de déplacement est de 10 pixels et la fréquence de l'animation est de huit images par seconde.
L'idée consiste en fait à enregistrer les coordonnées de ces points parcourus par la tête du serpent. Le nombre de ces points doit être égal à la taille du serpent.
La structure de données utilisée pour le stockage de ces points est le tableau array_position_corp.
Chaque point contenu dans ce tableau va correspondre par la suite à la position d'insertion d'un élément du corps sur la scène.

Image non disponible

Quant au dernier élément du tableau, il définirait la positon de la queue.
Puisque le déplacement du serpent suit huit directions, il faut donc adapter ces deux objets constituants le corps et la queue du serpent, au sens de déplacement de la tête à son passage par un point trajectoire. Ce sens de mouvement est important, il faut donc enregistrer les informations sur la direction de la tête à son passage par un tel point.
Bref, on est amené à enregistrer à chaque mouvement de la tête trois propriétés pour chaque point trajectoire :

Image non disponible

Si on suit une approche orienté objet pour garder ces informations, il faut utiliser un type d'objets avec trois propriétés correspondant respectivement à l'abscisse, l'ordonnée et le sens de mouvement des points de la trajectoire.
En ActionScript 2.0, on crée alors une classe personnelle de nom Position_Direction qui admet trois attributs et une méthode constructeur pour initialiser ces attributs :

Sélectionnez

class Position_Direction
{
 //Classe pour présenter les points parcouru par le snake 
 // Chaque point/position admet aussi une direction.
 
 var sens  : Number;
 var posX : Number;
 var posY : Number;
 
function Position_Direction(directTemp : Number, posXTemp :Number, posYTemp:Number)
 {
  this.sens      = directTemp;
  this.posX      = posXTemp;
  this.posY      = posYTemp;
 } 
}
 
L'enregistrement de ces postions (les points de la trajectoire) dans le vecteur array_position_corp doit se faire dès le changement de la position du serpent géré par les appuis sur les touches du clavier.
Il faut donc modifier la fonction mouvement_snake() pour remplir le vecteur array_position_corp :

Sélectionnez

function mouvement_snake()
{
//gestion des événements clavier
[&#8230;]
 
// Déplacement de la tète du snake
[&#8230;]
 
nouvelle_position = new Position_Direction(sens, tete_snake._x , tete_snake._y ) ;
 
[&#8230;]
array_position_corp.unshift( nouvelle_position );
 
[&#8230;]
// il faut garder seulement un nombre d'éléments dans le vecteur égale à la taille du serpent.
array_position_corp.splice(taille_snake+1);
}
 
Les éléments enregistrés dans le vecteur array_position_corp seront utilisés pour déterminer la position d'addition d'un nouvel élément au corps du serpent (un nouveau nœud), ce qui va entraîner l'augmentation de sa taille. Ce nombre d'éléments doit être égal alors à la valeur de la variable taille_snake qui s'incrémente au cas où la tête du serpent atteint un objet bonus.
La taille de ce vecteur est dans certain cas trés supérieure à taille_snake. Il faut donc éliminer les éléments superflus avec la fonction splice().

Sélectionnez

array_position_corp.splice(taille_snake+1);
Après ces traitements, on dispose de toutes les données pour ajouter un élément corps au serpent et augmenter sa taille effective sur la surface du jeu.

Image non disponible

Pour ce faire, il faut créer une occurrence du clip nœud et la positionner sur la scène suivant les propriétés d'un élément du vecteur array_position_corp.
Ce traitement est définit par la fonction dessiner_snake :

Sélectionnez

function dessiner_snake()
{
 for(i=0;i< taille_snake-1;i++)
 {
  attachMovie("corps_snake","corps_snake_"+i,i);
  this["corps_snake_"+i]._x = array_position_corp[i].posX;
  this["corps_snake_"+i]._y = array_position_corp[i].posY;
  this["corps_snake_"+i].gotoAndStop(array_position_corp[i].sens); 
 }
 
  // ajouter la queue du serpent
  attachMovie("queue_snake","queue_snake",300);
  this["queue_snake"]._x = array_position_corp[i].posX;
  this["queue_snake"]._y = array_position_corp[i].posY;
  this["queue_snake"].gotoAndStop(array_position_corp[i].sens);
}
 
Le dernier élément du vecteur est de valeur taille_snake-1 puisqu'on commence par la valeur 0. Cet élément contient les informations pour ajouter la queue au reste du corps du serpent.


Image non disponible

À la fin, il ne reste plus qu'à appeler cette fonction pour exécuter ses instructions durant le déplacement du serpent. On peut donc penser à faire appel dans l'image 2 du scénario qui doit contenir finalement les appels suivants :

Image non disponible

IV-E. Fin du jeu

Comme indiqué dans la partie principe du jeu, le jeu se termine si :
  • le serpent atteint la limite de la surface repérée par les clips mur_bas, mur_haut, mur_gauche, mur_droit ;
  • la tête du serpent entrelace le reste de son corps.
On peut penser donc à afficher un message indiquant la fin du jeu comme "Game Over" qui sera inséré à une image du scénario de numéro num_image (avec num_image >3) et un appel à la méthode gotoAndPlay(num_image) pour atteindre cette image et afficher le message. Dans cet exemple, num_image =5 :

Sélectionnez

if(collision_mur())
   gotoAndPlay(5);
 
 if( !(collision_coprs(nouvelle_position,array_position_corp) ))
 //s'il n'y a pas collision avec son corps alors ajouter un nouvel élément.
 array_position_corp.unshift( nouvelle_position );
 else
 {
  // s'il y a collision avec son corps, alors fin du jeux
  gotoAndPlay(5);
  delete onEnterFrame;
 }
 


Image non disponible

La fonction collision_mur permet de tester le contact entre la tête du serpent et les murs sur les bornes :

Sélectionnez

function collision_mur()
{
 if( tete_snake.hitTest(mur_haut) or tete_snake.hitTest(mur_bas) or tete_snake.hitTest(mur_gauche) or tete_snake.hitTest(mur_droit))
    return true;
 else
   return false;
}
 
la fonction collision_corps() permet de tester s'il y a une collision entre la tête du serpent et le reste du corps :

Sélectionnez

function collision_corps(nouvelle_position : Position_Direction,array_position_corp:Array)
{
 //vérifier si la nouvelle position de la tête est déjà parcourue 
 for(i=0;i<array_position_corp.length  and taille_snake >0 ;i++)
 {
  if(nouvelle_position.posX == array_position_corp[i].posX and nouvelle_position.posY == array_position_corp[i].posY )
 
  //if(  testeCollision(nouvelle_position,array_position_corp[i]) )
 
  return true;
 }
  return false;
}
 
Si le jeu se termine il faut initialiser les variables utiliser et enlever le serpent de la scène ainsi que les bonus affichés :

Sélectionnez

  tete_snake.x  = 304.9;
  tete_snake._y = 160.4;
  sens = 0;//reste fixe au début
 
  for(i=0;i<array_position_corp.length;i++)
   _root["corps_snake_"+i].removeMovieClip();
 
  queue_snake.removeMovieClip();
  clearInterval(monBonus1);
  clearInterval(monBonus2);
 
  bonus_1.removeMovieClip();
  bonus_2.removeMovieClip();
 
  array_position_corp.splice(0);
 

IV-G. Ajouter un son de fond pour le jeu

On peut améliorer le jeu en ajoutant une musique de fond qui se lance au démarrage du jeu ou bien un effet sonore qui accompagne les collisions avec les bonus et les murs d'extrémité.
Prenons l'exemple de doter le jeu d'une musique de fond.
Au début, on doit insérer le fichier son à la bibliothèque et lui attribuer ensuite un nom de liaison, par exemple son_fond.
Enfin, il faut écrire du code ActionScript pour lancer et contrôler la lecture de fichier son :

Sélectionnez

son = new Sound();
son.attachSound("son_fond");
son.start();
son_fond.onSoundComplete = function() 
{
//restart du sons
  this.start();
}
 

V. Sources du jeu

Le fichier .fla du jeu ainsi que le fichier .swf sont disponibles à cette adresse.

VI. Liens utiles

VII. Conclusion

Dans cet article, j'ai donné les étapes à suivre ainsi que le code ActionScrip2.0 à écrire pour réaliser un jeu de serpent en flash.
Le design du jeu peut être amélioré et d'autres fonctionnalités peuvent être ajoutées comme la gestion du niveau de jeu.

Aucun commentaire:

Enregistrer un commentaire