Exercice pratique : le PENDU

Utilisez le clavier pour saisir le texte.

Autres exercices AS3
Informations

Voici un petit exercice qui aborde la gestion du texte dans un jeu AS3, à l’attention des débutants. Ne vous attendez pas à un tutorial décrit pas à pas, le but d’un exercice étant que le lecteur fasse l’effort de la compréhension avec toutefois des explications de base.

- Les sources sont disponibles à la fin de l’exercice.
- Retrouvez ce tutoriel sur le Wiki de Mediabox

Partagez
Etude préliminaire

Tout d’abord le PENDU c’est quoi ? (merci Wikipedia)

Le pendu est un jeu consistant à trouver un mot en devinant quelles sont les lettres qui le composent. Le jeu se joue traditionnellement à deux, avec un papier et un crayon, selon un déroulement bien particulier.

Les deux joueurs dans cet exemple s’appellent A et B.

A pense à un mot et dessine une rangée de tirets, chacun correspondant à une lettre de ce mot.
B annonce une lettre.

- La lettre fait-elle partie du mot ?
- Oui : A l’inscrit à sa place autant de fois qu’elle se trouve dans le mot.
- Non : A dessine le premier trait du pendu.

Le jeu se poursuit jusqu’à ce que :

- B gagne la partie en trouvant toutes les lettres du mot ou en le devinant correctement.
- A gagne la partie en complétant le dessin du pendu.

Un jeu vraiment très simple à la fois dans sa version classique et dans sa version informatique. Cependant il va nous permettre d’aborder une notion parfois bien utile, la gestion du texte.

Les pré-requis

Pour ce programme vous devez connaître :

Variables et types : http://help.adobe.com/fr_FR/FlashPl...
Fonctions et paramètres : http://help.adobe.com/fr_FR/FlashPl...
Ecouteurs d’événements : http://help.adobe.com/fr_FR/FlashPl...
Gestion du texte : http://help.adobe.com/fr_FR/FlashPl...

Si vous souhaitez plus de précisions sur ces points, je vous encourage à parcourir le Wiki de Mediabox où vous trouverez de nombreux tutoriaux détaillés.

Le code

Voyons d’abord tout le code d’un coup.

var texte:TextField;
var phrase:String;
var erreur:int;
var infos:String;
var touche:String;
var marge:int = 40;
var lettre:Boolean;
var anim:Anim;
var longueur:int;

// interface
var panneaux:Panneaux = new Panneaux();
panneaux.addEventListener(MouseEvent.MOUSE_DOWN, init);
panneaux.buttonMode = true;
addChild(panneaux);

// initialisation
function init(e:Event):void{
        anim = new Anim();
        erreur = 1;
        phrase =         "Vous jouez au pendu sur le Wiki de Mediabox"
        infos = phrase.replace(/[A-Za-z]/g,"_");
        texte = new TextField();
        texte.defaultTextFormat = new TextFormat("Arial",30);
        texte.x =         marge;
        texte.y =         stage.stageWidth-texte.height-marge;
        texte.width = stage.stageWidth-marge;
        texte.wordWrap = true;
        texte.selectable = false;
        texte.text = infos;
        longueur = phrase.length;
       
        while(numChildren>0) removeChildAt(0);
       
        addChild(anim);
        addChild(texte);
        stage.addEventListener(KeyboardEvent.KEY_UP,appuie);
}

// gestion phrase
function appuie(e:KeyboardEvent){       
        touche = (String.fromCharCode(e.charCode));
        lettre = false;       
        for (var i:int=0; i<longueur; i++)        {
                if (phrase.charAt(i).toLowerCase() == touche){
                        infos = infos.substr(0,i)+phrase.substr(i,1)+infos.substr(i+1);
                        lettre = true;
                }
        }
        texte.text = infos;
        if (!lettre) anim.gotoAndStop(++erreur);
        if (erreur>6) finPartie(2);
        for (var j:int=0; j<longueur; j++)        {
                if (infos.charAt(j) == "_")        return;
        }
        finPartie(3);
}

// fin de partie
function finPartie(G:int):void{
        addChild(panneaux);
        panneaux.gotoAndStop(G);
        stage.removeEventListener(KeyboardEvent.KEY_UP,appuie);
}

Etude du programme

Comme d’habitude j’utilise la bibliothèque de Flash pour gérer les graphismes, ce qui me permet d’alléger le code et de ne conserver que ce qui est utile pour l’exercice, si vous n’utilisez pas Flash voici les modifications à faire dans le programme :

Panneaux : * un clip qui regroupe tous les panneaux d’interface * un panneau différent par frame

Anim : * un clip qui regroupe toutes phases du jeu * une phase sur chaque frame

Allez c’est parti pour l’étude pas à pas :

var texte:TextField;
var phrase:String;
var erreur:int;
var infos:String;
var touche:String;
var marge:int = 40;
var lettre:Boolean;
var anim:Anim;
var longueur:int;

// interface
var panneaux:Panneaux = new Panneaux();
panneaux.addEventListener(MouseEvent.MOUSE_DOWN, init);
panneaux.buttonMode = true;
addChild(panneaux);

Je commence par déclarer toutes les variables globales.

texte = le texte qui est affiché pour le joueur
phrase = la phrase que doit trouver le joueur
erreur = le nombre d’erreur commises par le joueur
infos = phrase de transition pour effectuer les manipulations
touche = la lettre choisie par le joueur
marge = la marge pour positionner le texte à l’affichage
lettre = validation de la lettre saisie par le joueur
anim = l’animation de pendaison
longueur = la longueur de la phrase à trouver

Puis je déclare et affiche le premier panneau d’interface qui propose de cliquer pour commencer à jouer, il lance la fonction "init()" que nous allons étudier de ce pas.

// initialisation
function init(e:Event):void{
        anim = new Anim();
        erreur = 1;
        phrase = "Vous jouez au pendu sur le Wiki de Mediabox"
        infos = phrase.replace(/[A-Za-z]/g,"_");
        texte = new TextField();
        texte.defaultTextFormat = new TextFormat("Arial",30);
        texte.x = marge;
        texte.y = stage.stageWidth-texte.height-marge;
        texte.width = stage.stageWidth-marge;
        texte.wordWrap = true;
        texte.selectable = false;
        texte.text = infos;
        longueur = phrase.length;
       
        while(numChildren>0) removeChildAt(0);
       
        addChild(anim);
        addChild(texte);
        stage.addEventListener(KeyboardEvent.KEY_UP,appuie);
}

Dans cette fonction je commence par initialiser toutes les valeurs des variables, notez que vous pouvez utiliser plusieurs phrases et en tirer une aléatoirement, il vous suffit d’utiliser un tableau regroupant toutes les phrases du jeu et d’en tirer une au hasard dans le tableau.

Le décompte des erreurs commence à 1 puisqu’il correspond à une frame de l’animation que nous allons afficher, comme nous commençons par afficher la frame 1 de l’animation le nombre d’erreurs de départ est de 1.

infos = phrase.replace(/[A-Za-z]/g,"_");

Première manipulation sérieuse du texte, ici j’utilise la méthode "replace" de la classe "String", elle permet de remplacer toutes les lettres spécifiées en paramètre 1 par celles spécifiées en paramètre 2, autrement dit ici je remplace tout l’alphabet en majuscule et en minuscule par un underscore pour chaque lettre de la phrase à trouver. La phrase n’est pas modifiée, c’est "info" qui prend les nouvelles valeurs.

Je crée ensuite le champ texte qui va servir à l’affichage (reportez vous à la doc sur la manipulation des textes dans Flash, c’est dans les pré-requis), et je lui donne la valeur de "infos".

Je supprime ensuite tout ce qui est affiché sur la scène, pour le cas où le joueur recommencerait une partie, puis j’ajoute à la liste d’affichage les éléments utiles (anim et texte), et enfin j’ajoute un nouvel écouteur pour savoir sur quelle touche le joueur appuie.

// gestion phrase
function appuie(e:KeyboardEvent){       
        touche = (String.fromCharCode(e.charCode));
        lettre = false;       
        for (var i:int=0; i<longueur; i++) {
                if (phrase.charAt(i).toLowerCase() == touche){
                        infos = infos.substr(0,i)+phrase.substr(i,1)+infos.substr(i+1);
                        lettre = true;
                }
        }
        texte.text = infos;
        if (!lettre) anim.gotoAndStop(++erreur);
        if (erreur>6) finPartie(2);
        for (var j:int=0; j<longueur; j++) {
                if (infos.charAt(j) == "_") return;
        }
        finPartie(3);
}

Lorsque le joueur appuie sur une touche, je commence par regarder quelle touche il a enfoncé et je la stocke dans la variable "touche" sous forme de String.

"charCode" renvoie la valeur du code de caractère associé à la touche enfoncée, attention les valeurs renvoyées sont celles du clavier anglais. Cette valeur étant numérique il nous faut la convertir en texte, j’utilise donc "fronCharCode" pour renvoyer une chaîne comprenant les caractères représentés par le code que je viens de trouver pour la touche.

J’indique ensuite que le joueur n’a pas trouvé la bonne lettre par défaut, je vais ensuite vérifier si en fait il a trouvé une lettre se trouvant dans la phrase, mais par défaut il n’en trouve pas.

Je fais une boucle sur tous les caractères de la phrase à trouver, par défaut je ne vais prendre en compte que les minuscules, j’impose donc au programme de transformer toutes les majuscules qu’il trouve dans la phrase en minuscule ("toLowerCase()") et je vérifie si une de ces lettres correspond à la valeur de la touche saisie. Si c’est le cas, je remplace l’underscore de "infos" par la lettre correspondante de "phrase", ce qui me permet de conserver les majuscules à l’affichage, et j’indique que le joueur à trouvé une lettre qui se trouve dans la phrase.

Lorsque j’ai terminé la vérification de toutes les lettres de la phrase, je modifie le texte d’affichage pour qu’il prenne la nouvelle valeur de "infos".

Si le joueur n’a pas trouvé de lettre correspond à la phrase, on comptabilise une erreur de plus et on affiche la frame de l’anim correspondante. Si le nombre d’erreurs est supérieur à 6 la joueur à perdu, sinon on refait une boucle sur la totalité de la phrase et on vérifie qu’il ne reste plus d’underscore dans "infos", auquel cas c’est que le joueur à trouvé toute la phrase et qu’il gagne la partie.

// fin de partie
function finPartie(G:int):void{
        addChild(panneaux);
        panneaux.gotoAndStop(G);
        stage.removeEventListener(KeyboardEvent.KEY_UP,appuie);
}

Quelle que soit l’issue de la partie, on affiche le panneau de fin à la bonne frame et on supprime l’écouteur du clavier.

Conclusion

Ce jeu est très simple à mettre en place mais aborde la gestion du texte, ce qui peut vous être très utile selon les jeux que vous souhaitez développer. Il existe de nombreuses manipulations possibles, je vous recommande de bien étudier toutes les options proposées par la classe String et les textField.

Sources

Version Flash CS5.5

Zip - 798 ko