Open menu

Préambule

  • L'objectif principal de ce TP est de reprendre le TP n°3 en utilisant le store afin de mettre en place des fonctionnalités d'achat/revente/assignation d'items pour l'aventurier.

 

 ATTENTION !

Les exercices ci-dessous nécessite souvent d'ajouter/supprimer des objets dans des tableaux qui sont observés par vuejs. Pour que vuejs s'aperçoive du changement du contenu du tableau, il faut obligatoirement utiliser les fonctions de manipulation des tableaux et JAMAIS la notation avec  [ ] (sauf quand on veut simplement lire un élément.

Par exemple, pour un tableau nommé tab :

  • tab.push(ojb) permet d'ajouter obj à la fin du tableau
  • tab.splice(index, 0, obj) permet d'insérer obj à l'indice index.
  • tab.splice(index, 1, obj) permet de remplacer l'élement à l'indice index par obj
  • tab.splice(index, 3) permet de supprimer 3 éléments à partir de l'indice index.

  

1°/ Acheter des items

1.1°/ objectifs et contraintes

  • Dans le TP 3, quand on sélectionne une boutique, les boutons se trouvant à droite de chaque item vendu/sur commande ne font rien.
  • L'objectif est que chaque item acheté soit ajouté à la liste des items achetés (cf. attribut itemsAchetes) par l'aventurier courant, s'il existe.
  • De base, le composant ShopDetails affichant la boutique courante n'a pas accès à une variable représentant le personnage courant.
  • La façon la plus simple de régler ce problème est d'ajouter une variable dans le store, par exemple currentPerso.
  • Cela implique d'ajouter une mutation permettant de mettre à jour cette variable, par exemple nommée setCurrentPerso(state, perso)
  • D'autre part, il faut que ShopDetails puisse modifier la liste des items achetés par le personnage courant, ainsi que la liste des items à vendre.
  • Pour cela, il suffit d'ajouter une mutation dans le store, par exemple nommée sell(state, item)
  • Le clic sur le bouton d'un item devra donc appeler cette mutation.

 

  • Une contrainte complique la mise en place de ce mécanisme : si un personnage ne possède pas suffisamment d'or pour acheter un item, un message d'alerte doit apparaître.
  • Or, une mutation ne renvoie aucune valeur.
  • Quand on clique sur le bouton d'un item, il faut donc faire la vérification de l'or possédé par le personnage courant, et si c'est suffisant, appeler la mutation, sinon mettre une alerte (cf. fonction alert() de JS)
  • Cela se fait au niveau de ShopDetails, par exemple dans une fonction de methods.
  • Pour récupérer l'or du personnage, la logique vuex conduit à écrire un getter.

 

 1.2°/ Mise en place

  • Ajoutez au state du store la variable currentPerso.
  • La valeur initiale de cette variable dépend de ce qu'elle représente. Il y a globalement 2 choix possibles :
    • elle référence un objet dans le tableau persos du store, et vaut initialement null
    • elle est un index dans ce tableau, et vaut initialement -1
  • Dans les deux cas, la valeur initiale représente
  • A vous de choisir une de ces 2 solutions, sachant que cela influe la façon de coder les 2 mutations mentionnées ci-dessus.

 

  • Modifiez PersosView pour que lors de la sélection d'un personnage, on appelle la mutation setCurrentPerso(state, perso) afin de mettre à jour le personnage courant.
  • Le second paramètre sera soit un objet Perso, soit un index, selon la solution choisie.
 
  • Ajoutez au store le getter renvoyant la quantité d'or du personnage courant, ou bien 0 s'il n'y a pas de personnage courant.

 

  • Ajouter au store les 2 mutations mentionnées, sachant que sell(...) :
    • ne fait rien s'il n'y a pas de personnage courant,
    • ne vérifie pas l'or possédé par le personnage courant,
    • ajouter l'item passé en paramètre à la liste itemAchetes du personnage courant,
    • supprime l'item passé en paramètre à la liste des items vendus par la boutique courante
  • Oups ! mais comment le store connait la boutique courante ? A vous de modifier le store et TownsView pour cela.

 

  • Modifiez ShopDetails pour :
    • ajouter une méthode vérifiant si le personnage peut acheter l'item choisi et si oui, appeler la mutation sell().
    • que le clic sur un bouton d'item appelle cette méthode, avec en paramètre l'item.
    • que le clic sur le bouton de fin de liste permette d'acheter tous les items sélectionnés.

 

1.3°/ Tests

  • Lancez l'application,
  • Sélectionnez directement une boutique, donc sans avoir sélectionné de personnage.
  • Essayez d'acheter un item. Normalement, il ne devrait pas disparaître de la liste.
  • Sélectionnez un personnage, puis retournez dans la boutique pour acheter des items et vérifier que :
    • les items disparaissent de la liste,
    • au bout d'un certain temps, le personnage n'a plus assez d'or.

 

2°/ Commander des items

2.1°/ Objectifs et contraintes

  • Lorsqu'une boutique est choisie, on peut cliquer sur les boutons des items à commander.
  • Dans ce cas, un message d'alerte indique dans combien de secondes l'item sera disponible à la vente, ce temps étant tiré aléatoirement entre 2 et 10 secondes.
  • Cette opération ne devant pas bloquer le navigateur, il faut qu'elle soit implémentée sous la forme d'une action + mutation dans le store. 

2.2°/ Mise en place

  • Ajoutez au store une mutation stock(state, item) qui permet d'ajouter item à la liste des items à vendre.
  • Ajoutez au store une action order(context, data), qui permet d'attendre data.time millisecondes puis d'appeler la mutation stock avec en paramètre data.item.
 
  • Modifiez ShopDetails afin que l'appui sur un bouton d'item sur commande :
    • tire un temps en millisecondes entre 2000 et 10000,
    • affiche une boite de dialogue indiquant cette durée, avec la possibilité d'accepter ou refuser.
    • en cas d'acceptation, on appelle l'action order() avec en paramètre un objet au format { time: ..., item: ... }, contenant le temps d'attente ainsi que l'item à commander.

 

2.3°/ Test

  • Essayez de commander un item pour vérifier le bon fonctionnement de la boîte de dialogue et si un nouvel item apparaît bien dans la liste des items à vendre par la boutique courante.

 

3°/ Revente d'items

3.1°/ Objectifs et contraintes

  • L'objectif est simplement de revendre un des items achetés par le personnage courant.
  • Cela nécessite simplement une mutation par exemple nommée resell(...).

 

3.2°/ Mise en place

  • Ajouter au store une mutation resell(state, data), permettant d'enlever data.item de la liste itemsAchetes du personnage courant, de l'ajouter à la liste des items à vendre de la boutique courante, si elle existe, et enfin de créditer le personnage avec data.gold pièces d'or.

 

  • Modifier PersosView pour qu'il soit possible de sélectionner un des items achetés.
  • La solution est libre : liste déroulante, bouton radio, saisie d'un indice, ...
  • Un clic sur un bouton permet de :
    • tirer aléatoirement un prix de revente entre 0.4 et 0.9 fois le prix d'achat d'origine,
    • d'afficher une boîte de dialogue pour indiquer ce prix et 2 boutons pour refuser ou accepter,
    • en cas d'acceptation, appeler la mutation resell(...), avec en paramètre un objet au format { item: ..., gold: ... }., permettant de spécifier quel item revendre et à quel prix.

3.3°/ Test

  • Essayez de revendre un item pour vérifier le bon fonctionnement de la boîte de dialogue, et de la mutation

 

4°/ (Dés)Assignation d'items à un slot

4.1°/ Objectifs et contraintes

  • L'objectif est double :
    • pouvoir sélectionner un item de la liste des items achetés et l'assigner à un slot, si c'est possible (cf. limitations de nombre et de type définies dans le tableau itemLimits de data.service.js)
    • Pouvoir sélectionner un item assigné à un slot et le remettre dans la liste des items achetés.

4.2°/ Mise en place

  • Les solutions pour sélectionner un item assigné ou non sont laissée libres. Il est cependant conseillé de réutiliser le principe de l'exercice 3 pour la sélection d'un item acheté.
  • La solution permettant d'assigner ou désassigner un objet peut se faire simplement grâce à un clic sur un bouton, mais vous pouvez également essayer de le faire en drag & drop.
  • Dans tous les cas, il faut ajouter les mutations nécessaires dans le store et modifier PersosView pour appeler ces mutations.
  • Il faut également tenir compte du fait qu'une assignation peut échouer à cause des limitations. Dans ce cas, un message d'alerte doit apparaître.