Les 12 étapes du tuto-jeu !

title png

Apprendre AS 3.0 en développant un jeu. Partie 1: Mise en place.

1. AS3 Avoider Game Tuto, Partie 1: Mise en place
  1. 2. AS3 Avoider Game Tuto, Partie 2: Ennemis multiples
  2. 3. AS3 Avoider Game Tuto, Partie 3: Game Over
  3. 4. AS3 Avoider Game Tuto, Partie 4: Menus et Boutons
  4. 5. AS3 Avoider Game Tutorial, Part 5: Un score et un compteur
  5. 6. AS3 Avoider Game Tutorial, Part 6: Petites améliorations
  6. 7. AS3 Avoider Game Tutorial, Part 7: Contrôle du clavier
  7. 8. AS3 Avoider Game Tutorial, Part 8: Ajouter un preloader
  8. 9. AS3 Avoider Game Tutorial, Part 9: Musique et Effets sonores
  9. 10. AS3 Avoider Game Tutorial, Part 10: Multiples Niveaux
  10. 11. AS3 Avoider Game Tutorial, Part 11: Enregistrer et charger
  11. 12. AS3 Avoider Game Tutorial, Part 12: Ramasse-miettes

Il y a plusieurs manières d'implémenter du code Actionscript 3.0 dans une animation Flash. On peut le faire de manière directe sur la ligne du temps ou on peut utiliser des fichiers d'Actionscript externes au document.

La première option n'est valable que lorsqu'il y a peu à programmer, sinon les recherches sur la timeline deviennent vite  fastidieuses.

La deuxième option permet un code plus ordonné et réutilisable dans d'autres projets. Elle permet aussi, en cas de collaboration avec des graphistes des échanges de fichiers plus cohérents: le code étant traité à part ainsi que les animations, nul besoin pour les programmeurs de donner leurs sources aux graphistes, et 
réciproquement.

Nous suivrons les 5 règles principales suivantes:

  • Nous utiliserons un seul calque.
  • Nous utiliserons une seule frame.
  • Nous ne mettrons rien sur la scène.
  • Nous n'utiliserons pas de codes sur la ligne du temps.
  • Nous n'utiliserons pas de codes dans les symboles.

Bien que ce tuto ne parle que de la programmation en Actionscript, j'essaierai d'expliquer quelques questions basiques de Flash pour ceux qui n'ont jamais utilisé le programme.

Si vous n'avez jamais utilisé Flash, peut-être que les règles dont nous venons de parler ne vous paraissent pas importantes, mais elles sont réellement nécessaires pour maintenir le projet le plus ordonné et le plus propre possible.

Ces règles sont importantes pour marquer le point de départ de notre jeu, mais par la suite, nous allons devoir réaliser quelques modifications qui vont à l'encontre de ce que nous avons décidé (spécialement quand nous ajouterons un preloader).

Première étape!

Avant de commencer, préparez un dossier dans lequel vous allez conserver tous les fichiers que vous créerez. En cas de collaboration avec d'autres, je vous conseille de mettre vos initiales à la fin du nom du dossier. Ainsi moi j'appelle mon dossier "AvoiderGame-MJW". Comme ça, si je dois passer mon fichier à quelqu'un, on voit tout de suite qui en est l'auteur. Dans ce dossier créez un nouveau dossier qui s'appellera "Classes" et où nous   classes mettrons tous les fichiers d'actionscript que nous créerons. Enfin, cliquez sur Fichier > Nouveau > Fichier Flash (AS 3.0).conservez votre fichier dans le dossier AvoiderGame, en prenant soin de garder le même nom que le fichier. Le mien s'appelle: "AvoiderGame.fla". Faites aussi attention aux majuscules et aux minuscules.

Il y a aussi quelques paramètres que vous devez mettre au point avant de commencer à programmer le jeu. Allez dans Fichier > Paramètres de publication et de là, dans l'onglet Flash, puis cliquez sur le bouton Configuration qui se trouve à côté du menu déroulant Actionscript 3.0
flash

Dans l'espace de configuration, cliquez sur le signe "+" et écrivez ./Classes/ pour indiquer à Flash où il devra chercher les classes
d'Actionscript que nous utiliserons dans notre jeu. Vous devez aussi cocher l'option "Déclarer les instances automatiquement" si elle ne l'est pas.

settings

Maintenant nous devons modifier quelques propriétés de la scène. Cliquez sur Modifier > Document et configurez-le comme vous voulez. Moi, je vais garder les propriétés du tuto original et mettre les dimensions de la scène à 400 x 300 pixels avec un fond gris. Ne vous inquiétez pas si, par la suite, vous devez les changer, le jeu fonctionnera quand même (même si, peut-être, vous devrez remettre au point quelques lignes de code que nous utiliserons dans les prochains chapitres. Je vous recommande une vitesse de 24 fps (Frames per second).
Sur l'image ci-dessous, vous pouvez voir ma configuration:

proprietes

Bon, après les configurations nécessaires à ce fichu set-up, nous pouvons créer notre premier ennemi!

Création d'un ennemi !

title png

L'ennemi sera l'objet que nous, comme joueurs, devrons éviter. Avant de lui donner vie, commençons à le dessiner. Cliquez sur  Insérer > Nouveau symbole... et dans la boîte de texte qui apparaît, écrivez comme nom de symbole Enemy (avec un E majuscule) et dans "Type", choisissez Clip (puisque nous allons devoir l'animer). Cliquez sur OK. Dans la bibliothèque, vous allez voir apparaître le nouveau symbole Enemy.

symbole

Si vous ne voyez pas la Bibliothèque, assurez-vous que Fenêtre > Bibliothèque est activé. De façon prédeterminée, Flash nous amène dans la fenêtre d'édition du symbole que nous venons de créer. Nous le voyons grâce à la barre qui apparaît au-dessus de la scène.

barreSi pour quelque raison que ce soit, vous n'êtes pas dans l'éditeur de symboles, faites un double clic sur le symbole de la bibliothèque ou faites un clic droit et sélectionnez Editer.

Michael a choisi comme ennemi un joli petit émoticon et une tête de mort comme avatar, allez savoir pourquoi! Peut-être du "british humour"!

 emoticon

Le traducteur espagnol a dessiné un petit tank animé bleu comme ennemi et vert comme avatar.

Moi j'ai simplement dessiné un carré rouge avec un bord noir qui représentera l'ennemi et un émoticon jaune souriant qui me tiendra lieu d'avatar. Mais pour des raisons de facilités d'édition, je me servirai des captures de Michael.

Quand nous éditons un symbole, nous remarquons qu'il y a une petite croix noire, c'est le point d'enregistrement du symbole. L'idéal c'est de centrer notre ennemi par rapport à ce centre  et pour cela, nous avons les options d'alignement. (Allez à Fenêtre > Aligner). Là, cochez la case "Par rapport à la scène" puis centrer horizontalement et verticalement.

aligner
Voilà, notre ennemi est bien cadré. Sortons de l'éditeur en cliquant sur Scène1. Enregistrez votre travail si vous ne l'avez pas encore fait avec Fichier > Enregistrer.

Instructions pour l'ennemi

Jusqu'à présent, nous avons préparé le jeu, dessiné notre ennemi. Le moment d'écrire du code est arrivé: grâce à lui, nous allons pouvoir indiquer à Flash quel va être le comportement de notre ennemi. Comme je l'ai dit au début, nous allons écrire le code dans des fichiers externes, pour les raisons déjà mentionnées.

Nous allons créer un nouveau fichier , mais auparavant nous allons créer un dossier appelé Classes où nous allons conserver tous nos fichiers de code.
Maintenant allez dans Fichier > Nouveau et choisissez l'option Fichier Actionscript. Un fichier vierge va s'ouvrir. Je vous recommande de l'enregistrer tout de suite, d'aller ce dossier et de conserver le fichier sous le nom de Enemy.as.Ce fichier va contenir la classe Enemy. Pour que vous compreniez un peu ce qu'est une classe, je dirai que c'est comme un manuel d'instructions de notre objet. C'est là que nous allons préciser tout ce que l'objet va pouvoir faire ou ne pas faire quand il sera dans notre jeu (plus loin, j'expliquerai en détail ce qu'est une classe et une instance de classe, qui sont deux concepts importants qu'il faut comprendre pour programmer).
Une fois le fichier enregistré, commencez à taper ce qui suit:

package 
{

}

Le mot package  nous indique à nous et à Flash que tout ce qui va être contenu dans les accolades est un paquet, c'est à dire un ensemble d'instructions. Dans l'affaire qui nous occupe, nous allons créer un paquet qui contiendra la classe Enemy et tous ses comportements.

package 
{
public class Enemy extends MovieClip
{
 
}
}

Bon, voyons ces mots nouveaux un par un.

  • class Enemy - Là, nous définissons la classe Enemy. Tout ce qui  apparaîtra à l'intérieur des accolades {} fera partie des propriétés de cette classe. Comme nous le disions précédemment les classes sont les instructions d'un objet, non l'objet lui-même. Les objets que nous ajouterons ensuite sur la scène seront des instances de la classe.
  • public - Grâce à ce mot, nous permettons que d'autres fichiers      d'actionscript accèdent à la classe Enemy et l'utilisent; si, au lieu de public, nous avions défini la clase comme private ou internal seul un code qui se trouverait à l'intérieur du paquet pourrait y accéder.
  • extends MovieClip - Là, nous disons à Flash que la classe Enemy peut faire tout ce que fait la classe MovieClip et même beaucoup plus, puisque nous pouvons lui ajouter des fonctions, des propriétés, des variables et tout ce dont nous aurons besoin.
Bon, continuons. Le problème maintenant c'est que, bien que la classe MovieClip soit très importante et très utilisée, Flash (CS4) ne sait pas de quoi il s'agit si nous ne lui disons pas que nous utilisons la classe MovieClip (ou n'importe quelle autre classe de notre choix).
Aussi nous devons ajouter cette nouvelle ligne:

package 
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
 
}
}

 Maintenant que nous avons importé la classe MovieClip, Flash sait de quoi il s'agit et ne nous causera plus de problème.
Ensuite, une fois que la classe est définie, nous devons ajouter une fonction "Constructor". La fonction constructeur est une fonction qui a le même nom que la Classe et elle a la particularité de s'activer chaque fois que nous créons  une instance de la classe.
Donc, créons la fonction constructeur, en tenant compte du fait qu'elle doit avoir le même nom que la classe et que le fichier:

package 
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
public function Enemy()
{
 
}
}
}


Nous retrouvons le mot public. remarquez que la fonction Enemy a deux parenthèses vides sur lesquelle nous reviendrons un peu plus tard.
Maintenant que nous avons créé notre classe Enemy, nous allons devoir la lier à notre objet qui se trouve dans la bibliotèque. Enregistrez le fichier AS et réouvrez le FLA.
Faites un clic droit sur le symbole Enemy et dans la fenêtre de Propriétés, cliquez sur Avancé et cochez l'option "exporter pour actionscript". Assurez-vous que dans la boîte Classe soit écrit Enemy. Si tout va bien, en faisant un clic sur le crayon (souligné en rouge sur la capture), le fichier Enemy.as devrait s'ouvrir.

Cliquez sur OK.
Nous allons programmer le comportement de notre ennemi. Ce que nous voulons c'est :
  • Que notre ennemi apparaisse sur l'écran.
  • et que notre ennemi aille de la partie supérieure vers la partie inférieure de l'écran.

package {
import flash.display.MovieClip;
public class Enemy extends MovieClip {
public function Enemy() {
x = 100;
y = 0;
}
}
}

La classe MovieClip a comme propriétés les paramètres x et y. Comme notre classe Enemy a hérité des propriétés de la classe MovieClip (rappelez-vous que nous avons utilisé le mot extends pour que l'objet hérite des propriétés de cette classe) elle a donc aussi hérité de cette propriété.
Les personnes qui connaissent les axes cartésiens de coordonnées, doivent penser ceci "Comment mettre l'ennemi dans la partie supérieure de l'écran et nous dire que les coordonnées sont à 0". C'est vrai, mais n'oublions pas que si la coordonnée y est à 0 c'est parce que Flash utilise un axe cartésien différent. Voyez le schéma ci-dessous:
coordon

Ici nous voyons les dimensions de notre animation, 400 x 300 c'est-à-dire, 400 px sur l'axe des x et 300 px sur l'axe des y. Pensez-y parce que quand nous donnerons l'ordre à notre ennemi d'aller vers le bas, nous allons devoir incrémenter la valeur de y au lieu de la diminuer.

Ne vous en faites pas, avec le temps vous allez vous habituer.

On va créer une fonction qui va se charger du mouvement de notre objet. Comme la classe Movieclip n'a pas de fonction pour le faire, nous allons la créer à l'intérieur de notre nouvelle classe Enemy, et nous allons l'écrire ce qui suit.

package 
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
public function Enemy()
{
x = 100;
y = 0;
}
 
public function moveDownABit():void
{
y = y + 3;
}
}
}

Expliquons ce que nous sommes entrain de faire.
  • function moveDownABit() - Tout ce qui se trouve à l'intérieur des accolades de cette fonction sont et seront les instructions que nous donnerons à l'objet Enemy. 
  • () Remarquez qu'à l'intérieur des parenthèses, nous ne mettons rien (vous allez bientôt comprendre pourquoi). Nous déclarons la fonction comme "public" au cas où nous aurions besoin d'y accéder plus tard. Un autre point important c'est que cette fonction est en dehors de la fonction Constructor, ce qui veut dire qu'elle ne s'exécutera que si nous l'appelons.
  • :void - cette fonction ne retourne aucun type de données.Je vous donne l'info mais ne vous tracassez pas avec ça pour l'instant. Quand nous rencontrerons une fonction qui retourne des données, je vous expliquerai de quoi il s'agit.
  • y = y+3; - Cette formule augmente la valeur de y de 3 pixels (souvenez-vous que cela veut dire que l'ennemi va descendre et non monter.

Mettre l'ennemi sur la scène


Enregistrez le fichier Enemy.as et revenez au fichier FLA. Jusqu'à présent nous n'avons fait que les plans de notre ennemi, nous ne lui avons donné que quelques propriétés.
Notre prochain travail sera de faire que notre ennemi apparaisse sur la scène.
Avant de poursuivre, rappelons que Flash est à l'origine un outil d'animation, et malgré son développement actuel,il se comporte toujours comme si tout ce qui se crée est un  MovieClip. Comme nous savons que la classe MovieClip a une fonction Constructeur qui se met en route dès qu'est créé un objet MovieClip, nous allons étendre cette fonction pour qu'elle crée notre ennemi quand le jeu commence. Mais il y a un problème! Comment allons-nous accéder à la fonction constructeur du fichier Enemy.as ?
Si vous avez répondu "avec un autre fichier AS", vous avez gagné!
Donc ouvrez un nouveau fichier .AS, écrivez-y les lignes ci-dessous et conservez-le dans le dossier Classes sous le nom AvoiderGame.as et réenregistrez-le.

package 
{
import flash.display.MovieClip;
public class AvoiderGame extends MovieClip
{
public function AvoiderGame()
{
 
}
}
}

Les chose deviennent plus familières, non? Au delà du fait que le nom de la classe et de la fonction constructeur ont changé, les termes sont les mêmes que ceux de la classe Enemy quand nous l'avons créée. Maintenant nous allons lier ce fichier au fichier FLA.



Revenez donc au fichier FLA et assurez-vous de ne pas être dans l'éditeur de symboles. Cherchez la fenêtre de Propriétés (si vous ne la voyez pas, vous pouvez y accéder en allant à Fenêtre > Propriétés et cochez le panneau Proprietés). Remarquez que là se trouve une boîte de texte nommée Classe: Entrez-y le nom AvoiderGame. Attention aux majuscules et aux minuscules.
Comme nous avons appelé le fichier AvoiderGame.as et la classe à l'intérieur du fichier AvoiderGame, nous devons mettre la classe de document au même nom.D'ailleurs, pour vérifier que tout est en ordre, cliquez sur le crayon, vous devriez ainsi ouvrir le fichier AvoiderGame.as.

Génial! Maintenant nous pouvons éditer la fonction constructeur de notre jeu pour qu'elle crée un ennemi dès le début.

package 
{
import flash.display.MovieClip;
public class AvoiderGame extends MovieClip
{
public function AvoiderGame()
{
enemy = new Enemy();
}
}
}

Soyez très attentif aux majuscules. Enemy avec un E majuscule fait référence à notre classe, celle que nous venons de créer et qui contient toutes les données et les propriétés de notre objet, alors qu'enemy fait référence à une instance de cette classe. Pour donner un exemple, voyez le mot Enemy comme équivalent à Automobile, et enemy comme équivalent à fiat 600 ou à ferrari. Ainsi vous pouvez comprendre le fait qu'on dise qu'une classe peut avoir des milliers d'instances, mais une instance n'a qu'une seule classe.
Actuellement l'instance enemy de la classe Enemy n'est disponible qu'à l'intérieur de la fonction constructeur de la classe AvoiderGame puisque nous l'avons déclaré dans la fonction. Comme nous avons besoin que l'ennemi soit disponible dans tout le jeu, nous devons ajouter une ligne supplémentaire (ligne 6). Mais avant de déclarer la fonction constructeur, déclarons une variable.

package 
{
import flash.display.MovieClip;
public class AvoiderGame extends MovieClip
{
public var enemy:Enemy;
 
public function AvoiderGame()
{
enemy = new Enemy();
}
}
}
  • public - Vous savez déjà ce que ce mot veut dire.
  • var - Définit une variable. Une variable est un bloc d'information que nous reservons en mémoire et auquel nous donnerons plus tard une valeur.
  • enemy:Enemy - La variable se nomme enemy et est une instance de la classe Enemy.
Comme la variable enemy est déclarée en dehors de la fonction constructeur, elle sera disponible pour toute la classe. Nous venons donc de créer notre ennemi et c'est le moment de l'inclure sur la scène.

public function AvoiderGame() 
{
enemy = new Enemy();
addChild( enemy );
}

Nous trouvons là une nouvelle fonction: addChild(). Cette fonction sert pour faire apparaître un objet sur la scène. Tout objet ajouté à la classe du document va apparaître sur la scène (dans la mesure où ses coordonnées x et y sont contenues dans la fenêtre).
Nous disons que enemy est un child (fils) de la classe AvoiderGame, et que la classe AvoiderGame est le parent de enemy. Un objet ne peut avoir qu'un parent mais il peut avoir autant de child(s) que nécessaire.
Finalement,  après toutes ces explications, nous pouvons tester notre animation pour voir le résultat. Enregistrez tous les fichiers et allez à Contrôle >Tester l'animation (Ctrl + Enter sur PC et Command + enter sur Mac ). Vous devriez obtenir quelque chose comme ça:
                            petit

Génial!!! Notre ennemi est sur la scène, mais nous ne voulons pas qu'il apparaisse là.
Ce qui serait bien c'est qu'il soit en dehors de la scène et qu'ensuite il descende. Ce qu'a fait Flash ici, c'est de mettre le point d'enregistrement de notre ennemi là où nous le lui avons indiqué (x=100 Y=0). Nous pourrions changer le point d'enregistrement de notre symbole, mais je ne recommande pas cette solution. Le mieux c'est de changer le code pour qu'au lieu que l'objet apparaisse au point y=0, il apparaisse un peu plus haut. En ce qui me concerne, je vais changer le code pour qu'il apparaisse au point y=-40. Pour ce faire, ouvrons le fichier Enemy.as et modifions la fonction constructeur ainsi:

public function Enemy() 
{
x = 100;
y = -40;
}


Animer l'ennemi

Nous avons déjà inclus quelques fonctionnalités pour que l'ennemi se déplace, mais nous n'avons pas encore écrit de code qui lui dise qu'il doit se déplacer, aussi faisons-le.
L'idée c'est de faire en sorte que le jeu dise à l'ennemi toutes les x secondes qu'il doit se déplacer. Pour obtenir ce résultat, nous allons utiliser la classe Timer qui répond exactemente à ce que nous souhaitons.
Editez la fonction constructeur du jeu (AvoiderGame.as, en créant une instance gameTimer de la classe Timer. Comme la classe Timer fait partie de Flash, il n'est pas  nécessaire de créer un nouveau fichier AS.

public function AvoiderGame() 
{
enemy = new Enemy();
addChild( enemy );
 
gameTimer = new Timer( 25 );
}

Remarquez que la parenthèse après le nom de la classe Timer n'est pas vide.Ce numero 25 est en train de dire à Flash que nous voulons un intervalle de 25 millisecondes (1000 millisecondes = 1 seconde), c'es-à-dire que nous voulons que quelque chose se passe toutes les 25 millisecondes.
Comme nous voulons que le Timer soit disponible pour tout le jeu, nous devons le déclarer hors de la fonction constructeur comme nous l'avons fait avant. La classe Timer est comme la classe MovieClip, il faut avertir Flash que nous allons l'utiliser à l'intérieur de notre classe et c'est pourquoi nous devons l'importer. Nous ajoutons donc les lignes suivantes:

package 
{
import flash.display.MovieClip;
import flash.utils.Timer;
 
public class AvoiderGame extends MovieClip
{
public var enemy:Enemy;
public var gameTimer:Timer;
 
public function AvoiderGame()
{
enemy = new Enemy();
addChild( enemy );
 
gameTimer = new Timer( 25 );
}
}
}

Très bien. Donc, nous avons notre Timer qui fonctionne toutes les 25 millisecondes, mais malgré tout, si vous regardez bien, rien ne le relie au reste du code et si nous testions maintenant notre jeu, nous obtiendrions le même résultat qu'avant!. Alors que faire? Regardez les lignes ci-dessous que nous ajoutons au code.

public function AvoiderGame() 
{
enemy = new Enemy();
addChild( enemy );
 
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
}

  • gameTimer.addEventListener - On pourrait traduire cette expression par "Dites au gameTimer qu'il soit attentif aux paramètres qui sont entre parenthèses, et chaque fois  que tu vois (écoutes) que ces paramètres sont sollicités, active la fonction moveEnemy". Un eventListener est une fonction qui est tout le temps en fonctionnement, dans l'attente que quelque chose se passe. S'il ne se passe rien, elle ne fait rien, mais dès qu'elle détecte que les paramètres sont sollicités, elle appelle la fonction que nous avons écrit.
  • TimerEvent.TIMER - Cet événement s'active chaque fois que la fonction Timer complète un intervalle; dans notre cas, cet événement se produira toutes les 25 millisecondes qui est le temps que nous avons défini.
  • moveEnemy - C'est la fonction qui va s'activer chaque fois que l'événement (TimerEvent.TIMER) se produit, nous n'avons pas encore écrit ce code, mais nous allons le faire dans deux minutes.
Au point où nous sommes arrivés, nous nous rendons compte que Flash a besoin que tout lui soit signifié, et comme il ne connaît pas non plus la classe TimerEvent, nous allons devoir l'importer au début de notre classe.

package 
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;

Maintenant il nous faut ajouter la fonction moveEnemy:

public class AvoiderGame extends MovieClip 
{
public var enemy:Enemy;
public var gameTimer:Timer;
 
public function AvoiderGame()
{
enemy = new Enemy();
addChild( enemy );
 
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
}
 
public function moveEnemy( timerEvent:TimerEvent ):void
{
 
}
}

Nous avons à nouveau une information à l'intérieur des parenthèses. Ceci permet à eventListener de passer l'information sur l'événement à la fonction moveEnemy sous forme d'instance (timerEvent) de la classe TimerEvent. Nous n'avons pas besoin d'en savoir davantage, pour le moment, à ce sujet, aussi continuons.
Tout ce qui nous reste à faire, c'est d'utiliser la nouvelle fonction pour dire à l'ennemi ce qu'il doit faire. Vous vous souvenez de la fonction moveDownABit que nous avons créé auparavant? Eh bien, il est temps de l'utiliser.

public function moveEnemy( timerEvent:TimerEvent ):void 
{
enemy.moveDownABit();
}



Donc nous pouvons dire à l'instance enemy qu'elle mette en route la fonction moveDownABit. Enregistrez tout et testez l'animation (Contrôle > Tester (Ctrl + Enter sur PC et Command + enter sur Mac )).
Il ne s'est rien passé?... Hé hé, bien sûr, parce que nous n'avons jamais dit au gameTimer de commencer à compter! Aussi éditons la fonction constructeur du jeu une fois encore.

public function AvoiderGame() 
{
enemy = new Enemy();
addChild( enemy );
 
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.start();
}

Réenregistrez tout et testez l'animation. Objectif atteint!!! L'ennemi se déplace vers le bas de l'écran à une vitesse constante de 3 pixels toutes les 25 ms (ou 120 px par seconde).
Maintenant nous allons créer un peu d'interactivité, car c'est une animation.

Enfin créons notre avatar à nous!

title png

Dans le fichier FLA, créez un nouveau symbole de type MovieClip appelé Avatar (révisez la section sur comment créer un ennemi si vous ne vous le rappelez pas). Dessinez votre personnage, selon votre goût. Si vous voulez dupliquer votre ennemi ou prendre lke même clip que pour l'ennemi mais le mettre d'une autre couleur, voilà la marche à suivre.

• Faites un clic droit sur le symbole de l'ennemi dans la bibliothèque et là, choisissez dupliquer.
• Une nouvelle fenêtre de création de symboles apparaît.
• Changez le nom contre celui d'Avatar et sélectionnez MovieClip (rappelez-vous de faire en sorte que le point d'enregistrement reste au centre).
• Le symbole étant dupliqué, vous allez pouvoir l'éditer: vous pouvez changer ses couleurs, modifier ce que vous voulez et même tout effacer et repartir de zéro

Bon....maintenant...qu'est-ce qu'on va faire?... Réfléchissons!... Nous venons de créer notre personnage et nous voulons qu'il fasse partie de notre jeu, nous devons lui donner des indications... Comment faire???
On va créer un nouveau fichier d' Actionscript!!! Eh bien, faisons-le: ouvrons un nouveau fichier AS et enregistrons-le sous le nom d'Avatar.as. Vous savez dans quel dossier le ranger, n'est-ce pas? Bien sûr, dans le dossier Classes que nous avons créé auparavant. Une fois enregistré, écrivons-y ce qui suit:

package 
{
import flash.display.MovieClip;
public class Avatar extends MovieClip
{
public function Avatar()
{
}
}
}

Bien, voilà donc notre code qui représente notre avatar. Mais comment Flash va savoir que le symbole qui est dans sa bibliothèque est en relation avec le fichier que nous venons de créer? Eh bien, comme nous l'avons vu auparavant, nous devons les lier.
Allez donc dans la bibliotèque, faites un clic droit sur votre Avatar y sélectionnez propriétés. Là, vous sélectionner "Exporter pour Actionscript" et vous cliquez sur le crayon pour vérifiez que le symbole et le fichier Avatar.as sont bien liés.

Bon, réfléchissons... Que voulons-nous que fasse notre Avatar? En premier lieu, qu'il suive le pointeur de la souris sur l'écran. Nous pouvons modifier la position de notre avatar depuis la classe AvoiderGame.as, aussi ouvrez-la et nous allons éditer un certain nombre de choses.
D'abord, nous devons ajouter une instance de notre avatar sur la scène. Je vais grouper tout le code puisque vous commencez maintenant à comprendre, plus ou moins, ce que je suis en train de faire.

public class AvoiderGame extends MovieClip 
{
public var enemy:Enemy;
public var avatar:Avatar;
public var gameTimer:Timer;
 
public function AvoiderGame()
{
enemy = new Enemy();
addChild( enemy );
 
avatar = new Avatar();
addChild( avatar );
 
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.start();
}
 
public function moveEnemy( timerEvent:TimerEvent ):void
{
enemy.moveDownABit();
}
}

Avant que je vous dise quelles lignes j'ai ajouté, essayez de regarder le code.

D'abord et c'est le plus important, j'ai déclaré une variable en dehors de la fonction constructeur pour qu'elle soit accessible pour toute la classe et ensuite j'ai ajouté à l'intérieur de la fonction constructeur un code identique à celui que nous avons utilisé pour faire apparaître notre ennemi sur la scène, le addChild.
Si vous testez le jeu maintenant, vous verrez que l'instance de notre avatar apparaît dans la coin supérieur gauche (aux coordonnées x=0 Y=0).
Ce que nous allons faire maintenant c'est de dire à Flash que nous voulons que l'avatar commence là où se trouve le pointeur de la souris. Flash contient 2 proprietés qui peuvent nous aider à le faire: mouseX qui nous donne la coordonnée de l'axe X et mouseY qui nous donne la coordonnée de l'axe Y. Comme nous l'avons dit auparavant, toute classe qui étend la classe MovieClip possède les propriétée de X et de Y et donc nous éditons notre code en ce sens, à nouveau.

public function AvoiderGame() 
{
enemy = new Enemy();
addChild( enemy );
 
avatar = new Avatar();
addChild( avatar );
avatar.x = mouseX;
avatar.y = mouseY;
 
gameTimer = new Timer( 25 );
gameTimer.addEventListener( TimerEvent.TIMER, moveEnemy );
gameTimer.start();
}

Si vous testez le jeu, l'avatar va apparaître là où se trouve la souris (c'est plus facile de le tester en utilisant le raccourci). Puisque nous utilisons le gameTimer pour modifier la position de l'ennemi tous les n intervalles, nous pourrions aussi utiliser la même fonction pour faire se déplacer notre avatar.

public function moveEnemy( timerEvent:TimerEvent ):void 
{
enemy.moveDownABit();
avatar.x = mouseX;
avatar.y = mouseY;
}
En y réfléchissant, le choix du nom de moveEnemy (déplacer ennemi) pour notre fonction n'est pas très judicieux, car nous ne déplaçons pas que l'ennemi, mais aussi l'avatar...
Changeons-le pour movenemyAndAvatar (déplacer ennemi et avatar), et voilà!!!

public function moveEnemyAndAvatar( timerEvent:TimerEvent ):void 
{
enemy.moveDownABit();
avatar.x = mouseX;
avatar.y = mouseY;
}

Mais il y a un autre problème... si nous modifions le nom de la fonction, il faut modifier aussi le eventListener du gameTimer, sinon quand Flash ira chercher la fonction moveEnemy s'il ne la trouve pas, il y aura un message d'erreur, donc nous la changeons aussi.

gameTimer.addEventListener( TimerEvent.TIMER, moveEnemyAndAvatar );
 
Nous avons modifié le nom de la fonction, le reste demeure identique.
Maintenant enregistrez tout et testez votre nouvel avatar!!!

Ajouter des collisions

Vous avez déjà du vous rendre compte que si notre avatar touche l'ennemi, .. il ne se passe absolument rien... Ca alors!! C'est quoi ce jeu débile ???
Allez, on va corriger ça.
Comment pouvons-nous dire à Flash qu'un objet en heurte un autre ? Eh bien, c'est plus facile que ce que vous pouvez imaginer. La classe MovieClip possède une fonction appelée hitTestObject qui détecte quand un MovieClip en heurte un autre. Naturellement notre avatar et notre ennemi ont la même fonction... et vous savez pourquoi?  
Allez, réfléchissez deux secondes...
Si vous avez pensé qu'ils ont la même fonction parce que nos classes étendent la classe MovieClip, vous avez raison ! Rappelez-vous que le fait d'étendre une classe fait qu'il y a héritage des propriétés et des fonctions. (Plus loin, nous verrons qu'il y a des façons d'éviter qu'une fonction n'hérite ou qu'il y a des moyens d'éviter que se modifie une fonction, mais on verra ça plus tard). Comme les objets ne se déplacent que lorsque le gameTimer s'active, nous devrions vérifier s'il y a une collision dans la fonction qui est appelée par l'eventListener du gameTimer.

public function moveEnemyAndAvatar( timerEvent:TimerEvent ):void 
{
enemy.moveDownABit();
avatar.x = mouseX;
avatar.y = mouseY;
 
if ( avatar.hitTestObject( enemy ) )
{
 
}
}
avatar.hitTestObject(enemy) - Ceci renvoie une valeur true (vrai) si le child avatar heurte le child enemy.
  • if - if signifie si. Ici nous disons à Flash que si (if) les paramètres que nous entrons dans les parenthèses sont vrais, alors qu'il exécute le code qui se trouve dans les accolades {}.
Actuellement il n'y a rien dans les accolades,aussi rien ne se passerait si nous testions le jeu. Avant de continuer, nous devrions faire quelque chose à propos du nom de cette fonction, car si nous ajoutons encore du code, nous allons avoir un nom de fonction pour identifier ce que nous faisons, du genre: moveEnemyAndAvatarAndAlsoCheckToSeeIfTheyHaveCollided (deplaceEnnemiEt AvatarEtVerifie sils seHeurtent). Nous allons trouver un nom plus court, regardez ci-dessous.

  • Tick - Chaque fois que s'accomplit le temps du gameTimer, nous allons dire qu'un tick (une impulsion) s'est produit.Tout ce qui se passera, passera par ce tick.
Aussi modifions le nom de la fonction par onTick:

public function onTick( timerEvent:TimerEvent ):void 
{
enemy.moveDownABit();
avatar.x = mouseX;
avatar.y = mouseY;
 
if ( avatar.hitTestObject( enemy ) )
{
 
}
}

N'oubliez pas de modifier le nom de la fonction dans l'eventListener du gameTimer, ne vous inquiétez pas, nous ne le modifierons plus dorénavant.
Finalement faisons en sorte que le jeu réalise une action quand l'avatar touche l'ennemi. Comme nous n'avons pas encore créé ni vies ni tirs, ni écran de game over, ni score, c'est le moment de vous montrer quelque chose.
Vous souvenez-vous du code que nous avons utilisé pour dire au Timer de commencer à fonctionner? Oui, eh bien, ajoutez cette ligne à l'intérieur de la fonction onTick:

public function onTick(event:TimerEvent):void {
enemy.moveDownABit();
avatar.x=mouseX;
avatar.y=mouseY;
 
if (avatar.hitTestObject(enemy)) {
gameTimer.stop();
}
}

gameTimer.stop(); sert pour arrêter le Timer.
Maintenant enregistrez et regardez ce qui se passe quand les objets se touchent.
Ne vous inquiétez pas , le jeu ne va pas être abimé. Si vous regardez bien, l'animation continue de fonctionner; ce qui a changé c'est que le Timer ne fonctionne plus, la fonction Tick ne se met pas non plus en route. Ceci fait que l'ennemi ne se déplace plus vers le bas et que l'avatar ne peut actualiser les coordonnées X et Y de la souris.

Nous pouvons en tirer deux observations:
1. Le détecteur de collisions de Flash est TERRIBLE!!!
2. Ca va être très facile de mettre une option pause dans le jeu.

Conclusions

title png

Bon, voilà, la première partie du tuto "Apprendre AS3 en développant un jeu" est finie. Si vous voulez passer le jeu complet à quelqu'un, vous n'avez qu'à zipper le dossier de votre jeu (le fichier Fla et le dossier Classes).
Je suis conscient que dans ce premier tuto, nous avons révisé un peu les questions de base d'Actionscript 3.0. Par la suite, nous allons voir plus de choses en moins d'étapes, dans la mesure où vous allez progresser et assimiler tout ce que nous allons faire. Dans le prochain didacticiel, nous allons ajouter de multiples ennemis et ensuite nous ajouterons un compteur, un écran de game over,des vies et un système de points.

J'espère que ça vous a plu et que ce travail vous a été utile. Vous pouvez faire les commentaires que vous souhaitez à la page Contact. Je peux répondre aux questions de base concernant la réalisation pratique de ce tuto, dans la mesure de mes connaissances.

2ª parte del tutorial