TP1 2020-2021 L3 Miage JavaScript

De $1

Version de 17:39, 18 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

 

Dans ce TP vous allez coder le squelette d'un jeu de type Mach-3 (à la Candy Crush). Nous verrons deux implémentations:

  1. une utilisant le DOM, des <div> et des <img> pour afficher les différentes pièces du jeu et interagir avec elles. C'est celle que je recommande aux débutants en JavaScript. On pourra déplacer les pièces (les "swapper") à l'aide de clicks souris ou du drag'n'drop.

     
  2. une utilisant le <canvas> de HTML5 et de l'animation à 60 images secondes. C'est cette méthode que je recommande à ceux qui connaissent déjà JavaScript, elle est un peu plus challengeante :-) Mais permettra de faire des animations plus fluides, au pixel près, notamment lors des chutes de pièces, des animations d'explosions etc.

1 - TP pour ceux qui ne connaissent pas très bien JavaScript, à l'aide de l'API du DOM

1.1 Installation d'un squelette du jeu, analyse du code

Travail à faire :

  1. Récupérer cette archive, la dezipper,
  2. Ouvrir Visual Studio code sur le projet,
  3. Ouvrir le fichier index.html et click droit "Ouvrir avec Live Server", cela doit lancer le projet dans un onglet de votre navigateur.
  4. Etudier le code, notamment le code CSS, pour comprendre comment on a codé en CSS le dessin de la grille, et les effets de surlignage et zoom sur les deux images codées en dur dans le fichier index.html
  5. Regarder le contenu des fichiers JavaScript, notamment de script.js, qui contient le programme principal (fonction init)
  6. Regardez où se trouvent les images (dossier assets/images), et regardez les images ! On trouve parmi elles six types de cookies ! Et pour chaque Cookie on a trois versions : un petite image, un grosse @2x et une surlignée ("highlighted").

1.2 Coder une classe pour décrire les Cookies (les objets affichés dans chaque case)

On a six types de cookies (croissant, cupcake, danish, donut, macaroon, sugarCookie), chaque cookie a une position dans la grille (ligne, colonne), et deux images associées (une version normale et une version "surlignée" ("highlighted" en anglais).

Vous modifierez la classe Cookie pour que le constructeur prenne en paramètre : type (entre 0 et 5), ligne, colonne. Dans la classe Cookie, on a mis deux tableaux statiques pour décrire les URLs des images (normales, surlignees).

Un tableau statique n'est pas accédé à travers une instance mais à travers le nom de la classe. Par exemple : Cookie.urlsImagesNormales[this.type]; renverra l'url de l'image "normale" correspondant au type this.type.

Pour this.type = 0 ça donnera l'image d'un croissant.

Travail à faire :

  1. Ecrire un constructeur qui prend en paramètre type, ligne, colonne,
  2. Dans ce constructeur, initialiser les propriétés :
    • Vous mettrez les paramètres type, ligne, colonne dans des propriétés (rappel : propriété/attributs c'est pareil) du même nom
    • Vous créerez une propriété this.htmlImage qui sera crée à l'aide de l'API du DOM comme un élément HTML de type "img". Cette image aura comme source l'url de l'image correspondant au type de la cookie.
    • Vous modifierez les attributs width et height de l'image pour indiquer une taille de 80x80 pixels,
    • Vous ajouterez deux attributs via la dataset API. On veut stocker la ligne et la colonne dans l'objet DOM this.htmlImage

1.3 Coder dans la classe Grille de quoi remplir la grille

Regardez la classe Grille (dans grille.js). Elle sert à décrire la grille affichée à l'écran. 

Travail à faire :

  1. Déclarer un tableau de Cookie dans cette classe. Par exemple, appelez-le tabCookies,
  2. Ajoutez un constructeur qui prend en paramètres le nombre de lignes et de colonnes de la Grille. Pour le moment on a codé en dur dans index.html les <div> qui composent la grille. Il y en a 9x9. 
  3. Dans ce constructeur vous stockerez les paramètres passés dans des propriétés du même nom (nbLignes et nbColonnes)
  4. A la fin du constructeur vous appellerez la méthode this.remplirTableauDeCookies(6); // 6 = nombre de couleurs...5 ou 4 pour des difficultés moindres.
  5. Coder la méthode this.remplirTableauDeCookie(nbTypes) qui va remplir le tableau tabCookies par lignes et par colonnes:
    • En JavaScript on ne sait pas déclarer et allouer un tableau à n dimensions. En effet, la déclaration let tab[9][9] n'est pas valide par exemple. Dans le fichier utils.js on vous fournit une fonction create2DArray(nbLignes) qui prend en paramètre le nombre de lignes d'un tableau à deux dimensions. Utilisez-là pour allouer le tableau.
       
    • Ensuite à l'aide de deux boucles for imbriquées (sur le nombre de lignes et sur le nombre de colonnes de la grille), pour chaque case (ligne, colonne) :
      • générer un type au hasard, qui aura une valeur entre 0 et 5
      • créer un objet de type Cookie(type, ligne, colonne)
      • le rajouter dans le tableau tabCookies à la case [ligne][colonne]

 1.4 Coder dans la classe Grille la méthode showCookies() qui afficher les images dans la grille

Vous écrirez une méthode showCookies() dans la classe Grille, qui va :

  • Parcourir les <div> de la grille HTML à l'aide de document.querySelectorAll("#grille div"); Voir module 2 du MOOC sur le DOM et querySelector/querySelectorAll 
     
  • La liste des <div> obtenue est à une dimension, on utilisera l'itérateur forEach sur cette collection pour parcourir chaque élément avec son index : listeDivs.forEach((elem, index) => {.....});

  • Dans cet itérateur, utiliser des opérateurs mathématiques (/ et %) pour calculer la ligne et la colonne correspondant à l'index de l'itérateur (par ex, si index vaut 29, pour le 30ème div (on démarre l'index à zéro), quelle est la ligne/colonne de la cookie dans le 30ème div si on a 9 lignes et 9 colonnes ?)
     
  • Une fois qu'on a la ligne et la colonne, récupérer la cookie correspondante dans le tableau tabCookies
     
  • Récupérer l'image qui est une propriété de la cookie, et l'ajouter dans le DOM comme fils du <div> courant. Vous regarderez le MOOC sur "comment ajouter un élément au DOM". Vous utiliserez la méthode append(elem) ou appendChild(elem) sur le div.
     
  • Si tout va bien, on doit voir les cookies s'afficher à l'écran.

1.5 Detecter le click souris sur les images

Regardez là où les images sont crées. Cela se passe dans quelle classe ? Mais dans quelle classe est le tableau des cookies ? Bon, on va devoir commencer à réfléchir à la logique du jeu... On va d'abord voir comment détecter qu'on a cliqué sur un cookie, puis sur un autre. Si les deux sont à 1 case de distance, horizontalement ou verticalement, on les swappe (on les échange). Donc, où pensez-vous qu'il est plus judicieux de placer l'écouteur de click ?

Et oui, c'est bien dans la classe Grille que ça va se passer, car c'est là qu'on pourra facilement tester (en cas de click) si on peut swapper deux cookies...

Travail à faire :

  1. Ajouter un écouteur de click sur les images avant de les afficher (par ex dans la méthode showCookies)
  2. Dans cet écouteur, on veut afficher la ligne et la colonne cliquée, et le type de cookie, comment faire ?
  3. Quand une cookie est cliquée, on veut changer sa classe CSS pour la mettre en évidence (classe "cookie-selected"), et changer son image pour son image highlightée
  4. Vous rajouterez pour cela deux méthodes : "selectionnee() et "deselectionnee()" dans la classe Cookie, qui vont changer les classes CSS. Voir la documentation de l'interface classList des objets html.

1.6 Implémenter le swap que s'il est autorisé

Quand on clique une image/cookie, on va stroker la cookie cliquée dans un tableau cookiesCliquees. Si le tableau a déjà un cookie dedans c'est qu'on a déjà clické sur la cookie "de départ". 

Quand on clique une seconde cookie, on va devoir :

  • Vérifier que la cookie est à une distance 1, si c'est le cas, on la sélectionne, et on swappe les deux images (et les types). Après le swap le tableau est remis à zéro et les deux cookies désélectionnées.
  • Si la cookie est à une distance > 1, alors on désélectionne la cookie 2 et on la supprime du tableau cookiesCliquees
  • Pour supprimer un élément du tableau vous utiliserez la méthode splice(pos, nbElements) à supprimer, sur le tableau.
  • A la fin de cette étape, lorsqu'on clique sur une cookie, puis sur une autre, alors les cookies sont swappées. Attention, seule l'image et le type sont swappés, les lignes et colonnes associées ne doivent pas changer. Un click sur une image doit toujours donner la ligne et la colonne correctes.

1.7 Essayer d'implémenter le drag'n'drop en plus du swap par click

On veut pouvoir aussi drag'n'dropper une image sur une autre et faire en sorte que les deux cookie soient swappés si ils sont à une distance de 1. Pendant le drag on veut voir un feedback visuel sur les cases survolées.

Support de cours pour le Drag'n'Drop : le module 3.3 du Mooc "HTML5 Apps and Games".

Vous devrez pour cela essayer de ré-utiliser au maximum le code écrit dans les étapes suivantes. On ré-utilisera par exemple le tableau cookiesCliquees pour stocker la cookie source (celle qu'on dragge) et la cookie destination (celle sur laquelle on droppe), et les algorithmes pour tester si on peut swapper et ceux qui implémentent le swap sont les mêmes.

Travail à faire :

  1. Ajouter un écouteur ondragstart sur les images. Vous copierez dans le clipboard du drag'n'drop (voir cours) un objet contenant la ligne et la colonne de l'image cliquée, en l'encodant en JSON à l'aide de la méthode JSON.stringify.
  2. Ajouter des écouteurs ondragenter et ondragleave qui ajouteront ou enlèveront la classe CSS "grilleDragOver" aux images survolées...
  3. Ajouter un écouteur ondrop qui récupèrera la cookie sur laquelle on a droppé (event.target), la cookie source (dans le clipboard, à partir de la ligne et la colonne) et qui swappera si possible (en appelant des méthodes existantes).

2 - TP pour ceux qui connaissent JavaScript, à l'aide du canvas HTML

Vous allez devoir reprendre pas mal d'idées proposées dans l'implémentation de la méthode 1.

1 - Apprendre à utiliser un canvas HTML5 pour dessiner des images dedans

  1. Vous allez regarder le MOOC "HTML5 Coding essential and best practices", module 2 et 3 sur le dessin et l'animation, en particulier la partie consacrée au dessin d'images.
  2. Avant de dessiner des images, il faut être sûr qu'elles ont toutes été bien chargées. Comme l'initialisation d'une image est une opération asynchrone, on fera appel à un bout de code assez pratique qui va faire le chargement des images à notre place, et nous prévenir quand il aura fini. Voir cet exemple d'asset loader et essayer de l'intégrer dans votre code.