Médiaforma

posts

Etape 7 – Interdiction de retourner plus de deux cartes

Pour donner un peu de piment au jeu, nous allons maintenant interdire de retourner plus de deux cartes en même temps, en ne tenant bien sûr pas compte des cartes appariées. Pour cela, nous allons comptabiliser le nombre de cartes visibles dans la variable nombre_retourne. Ajoutez cette variable dans l’en-tête du document :

<script>

var i, j, k;  // Compteurs de boucles

var nombre_retourne = 0; // Nombre de cartes retournées

Lorsque l’utilisateur clique sur une carte, le clic n’est pris en compte que dans le cas où deux cartes ne sont pas déjà retournées. Dans ce cas, le nombre de cartes retournées est incrémenté d’un :

img.onclick = function() {

if (nombre_retourne !=2) {

nombre_retourne++;

Lorsque deux cartes identiques sont identifiées, elles restent retournées jusqu’à la fin du jeu. Elles ne doivent donc plus entrer en compte dans le calcul du nombre de cartes retournées. La variable nombre_retourne est donc mise à zéro :

if (memo_carte == name) {  // Deux cartes identiques retournées

nombre_retourne=0;

Enfin, le premier paramètre de la fonction setTimeout() est ajusté pour prendre en compte la gestion de la variable nombre_retourne.

Lorsque le délai d’affichage de 1000 millisecondes est atteint, un premier test if regarde la valeur de l’élément visible de la carte concernée. Si cet élément vaut 0, il faut retourner la carte. Cela se fait en affectant la valeur dos.jpg à l’attribut src de la carte. Comme la carte est retournée, il faut aussi décrémenter d’un le nombre de cartes retournées.

Enfin, lorsque le nombre de cartes retournées est égal à zéro, il faut « oublier » la dernière carte qui a été mémorisée. Vous vous demandez peut-être pourquoi cela est nécessaire. Si c’est le cas, imaginez cette situation :

La dernière carte rendue visible représente disons … un lapin. L’utilisateur marque alors une petite pause et toutes les cartes qui étaient visibles et non appariées sont retournées. Supposons maintenant que le joueur clique sur la carte qui représente un lapin. Etant donné que la carte précédente représentait également un lapin, elle reste visible … sans pour autant être appariée. C’est un bug de jeu facilement évitable en mettant à zéro la variable memo_carte lorsqu’aucune carte non appariée n’est visible :

setTimeout(function() {if (visible[id-1]==0) {document.getElementById(id).src = ‘dos.jpg’; nombre_retourne–;} if (nombre_retourne==0) memo_carte= »;}, 1000);

Exécutons cette version du jeu.

Comme vous pouvez le voir, il est maintenant impossible d’afficher plus de deux cartes simultanément.

Etape 6 – Détection des cartes appariées

Dans cette étape, nous allons ajouter du code pour que les cartes appariées restent visibles. Pour cela, vous aurez besoin de plusieurs variables. Définissez-les dans l’en-tête du document :

<script>

var i, j, k;  // Compteurs de boucles

var memo_carte =  »; // Mémorisation du nom de la carte précédente

var memo_position = 0; // Mémorisation de la position de la carte précédente

var visible = new Array(0,0,0,0,0,0,0,0,0,0,0,0); // Indique si les cartes sont visibles (1) ou retournées (0, valeur par défaut)

Lorsque le joueur clique sur une carte il est nécessaire de la comparer à la carte qui a été retournée précédemment. Pour cela, il faut mémoriser le coup précédent. C’est la raison d’être des variables memo_carte et memo_position qui mémorisent (respectivement) le nom de la carte précédente et sa position dans le jeu.

Le tableau visible contient 12 valeurs qui représentent l’état retourné (0) ou visible (1) des cartes.

Nous allons maintenant agir sur la partie img.onclick du code :

img.onclick = function() {

document.getElementById(id).src = name; // On montre la carte

if (memo_carte == name) {  // Deux cartes identiques retournées

visible[memo_position-1] = 1;

visible[id-1] = 1;

}

else {

memo_carte = name;

memo_position = id;

setTimeout(function() {if (visible[id-1]==0) {document.getElementById(id).src = ‘dos.jpg’; }}, 1000); // On la cache après un délai de une seconde

}

}

Lors du premier clic sur une carte, memo_carte a la valeur qui lui a été affectée dans l’en-tête du document, à savoir une chaîne vide. Le test if (memo_carte == memo) n’est donc pas vérifié, et la partie else du code s’exécute. Ici, on mémorise la carte cliquée dans la variable memo_carte et sa position dans la variable memo_position :

else {

memo_carte = name;

memo_position = id;

Comme vous pouvez le voir, le premier paramètre de la fonction setTimeout() a été modifié. Lorsque les 1000 millisecondes sont écoulées, un test if s’intéresse au tableau visible, et plus particulièrement à la valeur qui correspond à la carte cliquée. Si cette valeur est égale à zéro, la carte est retournée :

if (visible[id-1]==0) {document.getElementById(id).src = ‘dos.jpg’; }

Lorsque l’utilisateur clique sur une deuxième carte, on teste si la carte cliquée est identique à celle qui avait été cliquée au tour précédent :

if (memo_carte == name) {

Dans l’affirmative, les éléments qui correspondent aux deux cartes sont mis à 1 dans le tableau visible afin que ces cartes restent visibles :

visible[memo_position-1] = 1;

visible[id-1] = 1;

Nous allons tester le code. Comme vous le voyez, les cartes appariées restent visibles :

Etape 5 – Mise en forme de la page

Dans cette étape, nous allons ajouter :

1)      Un gradient en arrière-plan de la page ;

2)      Un espace à droite de chaque carte pour obtenir un écartement régulier, horizontalement et verticalement ;

3)      Un titre au-dessus des cartes.

Le gradient est défini avec la propriété CSS3 linear-gradient. Cette propriété n’étant pas encore finalisée, il est nécessaire d’utiliser les préfixes –ms (pour Internet Explorer), -moz (pour Firefox), -o (pour Opera) et –webkit (pour Chrome et les autres navigateurs WebKit).

La propriété linear-gradient admet trois arguments :

  • Le point de départ du gradient ;
  • La couleur de départ ;
  • La couleur de fin.

Pour que l’arrière-plan utilise la propriété linear-gradient, il suffit de l’affecter à la propriété background-image de l’élément body :

body {

background-image: -ms-linear-gradient(left, #FFFFFF, #00A3EF);

background-image: -moz-linear-gradient(left, #FFFFFF, #00A3EF);

background-image: -o-linear-gradient(left, #FFFFFF, #00A3EF);

background-image: -webkit-linear-gradient(left, #FFFFFF, #00A3EF);

}

Voyons maintenant comment ajouter un espace à droite de chaque image. Pour cela, il suffit de définir la propriété margin-right des éléments img :

img {

margin-right: 5px;

}

Enfin, pour ajouter un titre au-dessus des cartes, vous insèrerez une balise <h1> juste après la balise <body> :

<body>

<h1>Memory – Evaluez votre mémoire</h1>

</body>

Etape 4 – Ajout de l’interactivité

Dans cette étape, nous allons permettre à l’utilisateur de retourner les cartes en cliquant dessus.

Pour cela, nous allons ajouter la prise en compte de l’événement onclick dans la fonction affiche_image() :

img.onclick = function() {

document.getElementById(id).src = name;

setTimeout(function() {document.getElementById(id).src = ‘dos.jpg’; } , 1000);

}

Lorsqu’une image est cliquée, la fonction affectée à img.onclick est exécutée.

La première instruction affecte le contenu de l’attribut name à l’attribut src de l’image. Rappelez-vous, l’attribut name contient une chaîne du type 1.jpg, 2.jpg, etc. qui donne le nom de la figure représentée sur la carte. En affectant cette valeur à l’attribut source de la carte, la carte apparaît sur l’écran.

La deuxième instruction retourne la carte au bout d’une seconde. Pour cela, un timer est mis en place avec la fonction setTimeout(). Cette fonction admet deux paramètres :

  • Les instructions à exécuter ;
  • Le délai en millisecondes au bout duquel ces instructions sont exécutées.

Comme vous le voyez, l’instruction exécutée au bout de 1000 millisecondes, c’est-à-dire au bout d’une seconde, cache la carte qui a été cliquée en affichant son dos.

Troisième étape : Affichage des cartes

Les six cartes utilisées dans le jeu sont des images JPG de 170 pixels sur 170. Elles sont nommées 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg et 6.jpg :

Le dos des cartes est également une image JPG de 170 pixels sur 170 et a pour nom dos.jpg.

Les cartes vont apparaître retournées par défaut. Elles seront réparties sur trois lignes pour obtenir quelque chose comme ceci.

Pour arriver à ce résultat, nous allons utiliser :

  • deux boucles for imbriquées d’indices i et j ;
  • la fonction affiche_image() pour afficher une image.

Commencez par définir les variables i, j et k dans l’en-tête du document :

<script>

var i, j, k;

Puis insérez le code suivant dans le corps du document :

for (i=1;i<4;i++) {

for (j=1;j<5;j++) {

k = (i-1)*4 + j – 1;

affiche_image(‘dos.jpg’, k + 1, cartes.charAt(k) + ‘.jpg’);

}

document.write(‘<br>’);

}

La première boucle for permet d’afficher les trois lignes de cartes. Quant à la deuxième, elle est responsable de l’affichage des quatre cartes sur chaque ligne.

Pendant le parcours des deux boucles, la variable k prend tour à tour les valeurs 0, 1, 2, … 11. C’est cette variable qui va permettre à la fonction affiche_image() d’associer une figure à chaque carte.

La fonction affiche_image() admet trois arguments :

  • le nom de l’image à afficher ;
  • l’identifiant de l’image (entre 0 et 11) ;
  • le numéro de l’image, extrait de la chaîne cartes, qui a été mélangée à l’étape précédente. Pour extraire le caractère qui se trouve à la position k, nous appliquons la fonction charAt(k) à la chaine cartes. La chaîne « .jpg » est concaténée au résultat de la fonction charAt(). Nous obtenons donc des chaînes du type 1.jpg à 12.jpg.

Remarquez l’instruction document.write(‘<br>’);, à l’extérieur de la boucle la plus interne. Cette instruction est exécutée chaque fois que la boucle interne est terminée, et donc toutes les 4 cartes. Elle provoque l’affichage des cartes suivantes sur une autre ligne.

Voyons ce qui se cache derrière la fonction affiche_image() :

function affiche_image(src, id, name) {

var img = document.createElement(« img »);

img.src = src;

img.id = id;

img.name = name;

document.body.appendChild(img);

}

La première instruction crée un élément img et l’affecte à la variable img.

Les trois lignes suivantes initialisent les attributs src (le nom de l’image), id (l’identifiant de l’image) et name (le nom de l’image) avec les trois paramètres passés à la fonction.

Enfin, la dernière instruction ajoute l’image au DOM, et donc, fait apparaître une carte retournée.

Deuxième étape : Tirage aléatoire des cartes

Le but du jeu est d’apparier douze cartes. Pour représenter ces cartes, nous allons leur affecter un chiffre compris entre 1 et 6. La position initiale des cartes est définie dans le corps du document, via la variable JavaScript init :

var init=’123456654321′;

Pour mélanger les cartes, nous allons utiliser plusieurs fonctions JavaScript :

  • split() pour diviser la chaîne init en un tableau de douze éléments : un pour chaque caractère ;
  • sort() pour trier les caractères isolés par la fonction split() ;
  • Math.random() pour obtenir un nombre pseudo aléatoire compris entre 0 et 1. Les valeurs retournées par cette fonction sont générées à partir de l’horloge de l’ordinateur.
  • join() pour rassembler les caractères afin d’en faire une chaîne unique.

Voici la syntaxe utilisée :

var cartes = init.split( »).sort(function(){return 0.5-Math.random()}).join( »);

Cette méthode n’est pas optimale, car elle est influencée par la position de départ des éléments à trier. Cependant, dans notre jeu, elle sera bien suffisante !

Les fonctions split(), sort() et join() s’enchaînent. Ainsi, le résultat de la fonction split() sert d’entrée à la fonction sort() et le résultat de la fonction sort() sert d’entrée à la fonction join().

S’il est facile de comprendre l’utilité des fonctions split() et join(), la fonction sort() vous semble peut-être obscure. Voyons comment elle fonctionne.

Sans argument, cette méthode classe par ordre croissant (s’il s’agit de nombres) ou alphabétique (s’il s’agit de texte) les éléments sur lesquels elle travaille.

Lorsqu’une fonction est passée en argument, c’est-à-dire entre les parenthèses de la fonction, les éléments du tableau sont classés en fonction des valeurs retournées par la fonction. Supposons que les éléments a et b doivent être comparés :

  • Si la fonction retourne une valeur négative ou nulle, les éléments a et b sont laissés tels quels ;
  • Si la fonction retourne une valeur positive, les éléments a et b sont inversés.

Dans notre exemple, la fonction retourne la valeur 0.5 – Math .random(). Etant donné que Math.random() retourne des valeurs pseudo-aléatoires comprises entre 0 et 1, l’expression 0.5 – Math.random() retournera des valeurs pseudo-aléatoires comprises entre -0.5 et 0.5. Les éléments du tableau seront donc mélangés, ce qui est exactement l’effet recherché.

Première étape : Création du squelette HTML5

Le jeu repose sur un squelette HTML5 standard.

La première ligne représente la DTD ou déclaration de type de document. Elle indique aux navigateurs les règles d’écriture utilisées dans le langage. Ici, cet en-tête correspond au langage HTML5.

Le document HTML est délimité par les balises <html> et </html>.

L’en-tête est délimité par les balises <head> et </head>. Il va nous permettre de définir :

  1. L’encodage des caractères dans le document avec la balise <meta charset>. L’encodage retenu est le plus utilisé sur le Web : UTF-8. Il permet de faire cohabiter dans un même document des caractères issus de plusieurs langues : le français et le japonais par exemple.
  2. Le titre du document avec la balise <title>. Ce titre apparaîtra dans la barre de titre ou dans l’onglet du navigateur.
  3. Les styles CSS utilisés dans le jeu entre les balises <style> et </style>.

Le corps du document se trouve entre les balises <body> et </body>. C’est à cet endroit que seront insérées les instructions responsables de l’affichage dans le navigateur.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Jeu de Memory</title>
    <style>
    </style>
  </head>
  <body>
  </body>
</html>