Open menu

Préambule

 
  • Ce TP permet de transformer le TP 2 en une application vuejs.
  • Pour ce premier jet, tout le fonctionnel l'application sera contenu dans un unique composant nommé Town.
  • L'objectif est d'utiliser les notions abordées dans le TD n°3 : variables locales/calculées, fonctions, et directives basiques.

 

  • ATTENTION : faire un seul composant n'est pas une bonne pratique et le TP suivant aura pour objectif de rendre l'application multi-composants.


Mise en place

  • Dans un terminal, créez un projet vuejs nommé rpg : vue create rpg.
  • Télécharger les canevas de code [ ici ] et décompacter l'archive.
  • Cette archive contient 2 fichiers :
    • App.vue : copier ce fichier par-dessus celui qui a été généré par vue-cli (src/App.vue). Vous n'avez pas à modifier ce fichier.
    • Town.vue : copier ce fichier dans src/components. Vous devez compléter ce fichier.
  • Prendre votre fichier model.js du TP2 (ou bien celui proposé en solution) et :
    • copier le fichier dans src/
    • ajouter à la fin du fichier copié une instruction permettant d'exporter la ville et les personnage. Par exemple, si votre ville est dans la variable town et les perso dans la variable players, ajouter  : export { town, players } (NB : dans la solution proposée du TP 2, la ville est dans la variable town1 mais vous pouvez sans problème la renommer town)
  • Effacer le fichier src/components/HelloWorld.vue.
  • Editer Town.vue et dans la partie script :
    • vérifier que le import importe les mêmes noms de variables que ceux qui sont exportés dans model.js
    • vérifier que la variable currentTown observe la variable représentant la ville (par ex. town si town est le nom qui a été exporté/importé)

 

Remarques :

  • App.vue se contente d'importer le composant Town et de l'utiliser dans la partie <template>.
  • Dans Town.vue, le champ data est déjà rempli avec toutes les variables nécessaires à l'application. Il est fortement conseillé de la laisser telle quelle (sauf si le nom de la variable ville n'est pas correct)
  • Ces variables correspondent à toutes les informations qu'il va falloir afficher dynamiquement dans la page, et éventuellement récupérer leur valeur quand elles sont utilisées dans des champs de saisie.
  • Dans Town.vue, les emplacements où il faut compléter le code sont numérotés comme les exercices.
  • Dans certains exercices, il faudra utiliser une syntaxe vuejs qui n'a pas été abordée lors du TD 3. Dans ce cas, des conseils permettront de répondre à ce qui est demandé.

 

Exercice 1 : l'entête de la page.

1.1 - créer la liste déroulante pour sélectionner le personnage courant.

  • Le principe est le même que dans le TP 2, en utilisant <select> et <option>.
  • La différence est que l'on doit utiliser la directive v-for sur <option> pour éviter d'écrire une liste "en dur" et que l'on doit appeler la méthode selectPlayer() qui se trouve dans methods (cf. exo 1.3)

CONSEILS :

  • En HTML+JS, on peut appeler une fonction lorsque la sélection est modifiée et que l'événement change est émis, grâce à l'attribut onchange.
  • Par exemple : onchange="selectPlayer(event.target.value)" va permettre d'appeler la fonction selectPlayer avec comme paramètre la valeur de l'attribut value de l'item sélectionné.
  • En vuejs, il est possible de faire la même chose pour appeler une fonction définie dans methods.
  • Dans le cas présent, on écrit : @change="selectPlayer($event.target.value)"
  • La syntaxe est quasi identique à part :
    • pour capturer l'événement change, on écrit @change (ou bien v-on:change)
    • pour accéder à l'événement, on écrit $event (au lieu simplement event)

1.2 - afficher le nom de la ville

  • La ville courante est accessible grâce à la variable currentTown.
  • Utiliser les moustaches pour afficher en très gros titre le nom de la ville courante.

1.3 - affichage du titre de la partie personnage

  • Utiliser les moustaches pour afficher le nom du personnage courant, son niveau et ses points de vie.

1.4 - changement de personnage

  • écrire la fonction selectPlayer(id) qui met à jour currentPlayer avec players[id].

A ce stade, vous pouvez tester votre page, notamment si le changement de personnage dans la liste provoque bien un changement dans l'affichage du titre de la partie personnage.


Exercice 2 - la sélection de la rue et de la boutique courantes

2.1 - la liste des rues.

  • Problème : pour chaque ligne de la liste à puce, il faut utiliser 2 balises : <input> et <label>
  • Or, v-for ne fonctionne que sur 1 balise.
  • Comme indiqué dans le TD, il est possible d'appliquer v-for sur <div> et mettre plusieurs balises dans <div> pour les répéter X fois.
  • Dans le cas présent, il faut appliquer le v-for sur currentTown.streets et pour chaque rue, afficher un bouton radio et un label.

CONSEIL :

  • Chaque bouton radio créé avec <input> doit avoir la même valeur d'attribut name si on veut qu'un seul bouton soit sélectionnable à la fois.
  • En revanche, on doit donner une valeur différente à l'attribut value. La solution la plus simple est de donner des valeurs 0, 1, 2, ... à chaque bouton. Lors d'un clic sur un bouton, il suffit de récupérer sa valeur (avec $event.target.value) pour avoir le numéro du cliqué.
  • La différence avec la liste des personnage est qu'il faut capturer l'événement click (et non pas change) et appeler la fonction selectStreet() avec la valeur du bouton en paramètre.

2.2 - la liste des boutiques

Remarque : la liste des boutique ne doit apparaître que s'il y a une rue sélectionnée. C'est pourquoi cette partie est dans un <div> qui utilise v-if pour tester si currentStreet est différent de null.

  •  Mêmes principes que pour la listes des rues mais en itérant sur currentStreet.shops et en appelant selectShop().
2.3 - changement de rue
  • écrire la fonction selectStreet(id) qui met à jour currentStreet avec currentTown.streets[id] et qui met à jour currentShop avec currentStreet.shops[0].

2.4 - changement de boutique

  • écrire la fonction selectShop(id) qui met à jour currentShop avec currentStreet.shops[id].

 

Exercice 3 - le contenu de la boutique courante

Remarque : le contenu de la boutique ne doit apparaître que s'il y a une boutique sélectionnée. C'est pourquoi cette partie est dans un <div> qui utilise v-if pour tester si currentShop est différent de null.

3.1 - le nom de la boutique

  • Utiliser les oustaches pour afficher en gros titre le nom de la boutique courante

3.2 - la liste des items en stock

  • Utiliser une liste numérotée <ol>.
  • Utiliser <li> et v-for pour créer les lignes, chacune donnant le nom d'un item en stock et son prix.

3.3 - la liste des items sur commande

  • Même principe que ci-dessus mais avec les items sur commande.

A ce stade, vous pouvez de nouveau tester le résultat, en vérifiant que les changements de sélection provoquent un changement d'affichage.


 

Exercice 4 - le personnage

4.1 - les slots

  • L'affichage des slots se fait en construisant une table avec <table>
  • Utiliser <tr> et v-for pour créer les lignes correspondant à chaque slot.
  • Utiliser <td> pour créer les colonnes de chaque ligne :
    • La première colonne doit contenir le nom du slot
    • Les colonnes suivantes contiennent chacune un item assigné au slot. Chaque nom d'item doit être précédé par la chaîne "[ X ] -", sachant que X représente l'indice de l'item (1, 2, ...) dans le slot.

CONSEIL :

  • On peut très bien imbriquer des v-for.
  • Dans le cas présent, cela implique qu'un premier v-for parcourt les slots du personnage courant, par exemple avec un itérateur nommé slot : v-for=(slot, index) in currentPlayer.slots"
  • Ensuite, un v-for imbriqué peut parcourir le tableau slot.items, par exemple avec un itérateur nommé item.

4.2 - l'or

  • Utiliser un champ de texte <input> en lecture seule pour afficher l'or du personnage courant.

4.3 - affichage de la liste des items achetés

  • Utiliser un champ de texte <input> en lecture seule pour afficher le contenu de la variable calculée boughtItems (cf. ci-après)

4.4 - créer la liste des items achetés

  • Cette liste est affectée à une variable calculée boughtItems, ce qui nécessite de définir la fonction boughtItems() dans computed.
  • Cette fonction retourne une chaîne de caractères qui concatène le nom de chaque item acheté, précédé de "[ X ] -" où X est l'indice de l'item dans currentPlayer.boughtItems.

4.5 - assignation des items achetés

  •  Même principe que dans le TP 2, excepté que la valeur des champs de saisie provient des variables idxItemBought et idxSlotAssign.
  • Lors de l'appui sur le bouton "Assign", il faut appeler la fonction assign().

CONSEILS :

  • Pour qu'un changement dans le champ de saisie soit répercuté dans les variables mentionnées ci-dessus, il faut obligatoirement utiliser la directive v-model. Cette obligation vaut pour tous les champs de saisie utilisés dans les exercices suivants.
  • Pour faire quelque chose lors de l'appui sur un bouton, il faut caputrer l'événement click.

4.6 - fonction assign()

  • Code quasi identique à celui du TP 2, excepté :
    • la valeur des champs de saisie provient des variables idxItemBought et idxSlotAssign.
    • pas besoin de mettre à jour explicitement la liste des items achetés et des slots : si la fonction assign() de la classe Perso est bien écrite, les changements dans le personnage courant vont provoquer un rafraichissement de la page gérer par vuejs. Cette remarque vaut également pour les fonctions des exercices suivants.

4.7 - achat d'item

  •  Même principe que dans le TP 2, excepté que la valeur des champs de saisie provient des variables idxItemBuy
  • Lors de l'appui sur le bouton "Buy", il faut appeler la fonction buy().

4.8 - fonction buy()

  • Code quasi identique à celui du TP 2, excepté que la valeur des champs de saisie provient des variables idxItemBuy.

4.9 - commande d'item

  •  Même principe que dans le TP 2, excepté que la valeur des champs de saisie provient des variables idxItemOrder
  • Lors de l'appui sur le bouton "Order", il faut appeler la fonction order().

4.10 - fonction order()

  • Code quasi identique à celui du TP 2, excepté que la valeur des champs de saisie provient des variables idxItemOrder.

4.11 - vente des items assignés à un slot

  •  Même principe que dans le TP 2, excepté que la valeur des champs de saisie provient des variables idxItemSell et idxSlotSell.
  • Lors de l'appui sur le bouton "Sell", il faut appeler la fonction sell().
4.12 - fonction sell()
  • Code quasi identique à celui du TP 2, excepté que la valeur des champs de saisie provient des variables idxItemSell et idxSlotSell.

L'application est maintenant complète et vous pouvez tester toute la partie personnage en achetant, assignant, commandant, vendant auprès de différentes boutiques.