Open menu

Préambule

 
  • Ce TP vient en complément du premier pour ajouter les notions de boutique, rue et ville.
  • L'objectif est de mettre en place un premier prototype de page web permettant de :
    • sélectionner un aventurier, une rue et une boutique dans celle-ci,
    • d'acheter des items dans cette boutique,
    • de commander des items s'ils ne sont pas encore en stock,
    • de vendre dans la boutique un item affecté à un slot,
    • d'affecter des items achetés à un slot (NB : déjà codé dans le TP 1)

 

  • ATTENTION ! Comme il est particulièrement fastidieux de modifier dynamiquement une page HTML complexe, ce TP (sauf pour ceux qui feront l'exercice 7) ne demande pas de créer toutes les fonctions qui vont modifier le DOM par rapport aux choix de l'utilisateur. Seules quelques fonctionnalités supplémentaires vont être codées dans controller.js
  • En revanche, toute la partie HTML va être écrite ainsi que la partie modèle de données (dans model.js)

 

  • On verra par la suite que l'on peut facilement partir de ce prototype pour créer une application SPA (single page application) vuejs.

Exercice 1 - la boutique

  • En s'inspirant de ce qui a déjà été codé dans le fichier model.js, modifier ce dernier pour ajouter la classe Shop.
  • La classe Shop contient comme attributs :
    • id : l'identifiant de la boutique. Doit être initialisé avec le même principe que la classe Perso, c.a.d. en utilisant une variable statique counter, qui est incrémentée à chaque appel du constructeur de Shop.
    • name : le nom de la boutique,
    • itemCat : un tableau contenant les catégories d'items que vend cette boutique,
    • itemStock : un tableau d'items en stock,
    • itemOrder : un tableau d'items sur commande.
  • La classe Shop contient comme méthode :
    • le constructeur permettant d'initialiser id, name, itemCat, puis d'appeler les 2 méthodes fillStock() et fillOrder() décrites ci-dessous.
    • fillStock() : tire aléatoirement 10 items (NB : dans le tableau global items) dont la catégorie doit être présente dans itemCat. Ces 10 items servent à remplir itemStock.
    • fillOdrer() : tire aléatoirement au maximum 5 items dont la catégorie doit être présente dans itemCat ET qui ne sont pas présents dans itemStock. Il peut donc y en avoir moins que 5. Ces items servent à remplir itemOdrer. 
    • sell(item_id) : représente la vente de l'item à l'aventurier. item_id est l'indice de l'item dans itemStock. Cet item doit être supprimé de itemStock.
    • estimate(item) : représente l'estimation du prix de revente d'un item de l'aventurier à la boutique. Si la catégorie de l'item n'est pas compatible avec celles de la boutique, la méthode renvoie -1. Sinon elle renvoie le prix normal de l'item moins un nombre aléatoire tiré entre 0 et 0.9*prix normal (NB : cela veut donc dire que l'aventurier peut revendre pour le prix normal ou bien pour le dixième de ce prix).
    • buy(item) : représente la vente d'un item de l'aventurier à la boutique. L'item est simplement ajouté à itemStock.
    • order(item_id) : représente la commande d'un item par l'aventurier. item_id est l'indice de l'item dans itemOrder. Cela revient simplement à mettre l'item dans itemStock. NB : cette fonction sera appelée grâce à un timer (cf. exercice 6)
    • fromJSON(obj) : méthode statique renvoyant un objet Shop initialisé avec le JSON obj donné en paramètre.

 

Exercice 2 - la rue

  • Modifier model.js pour ajouter la classe Street
  • La classe Street contient comme attributs :
    • id : l'identifiant de la rue. Doit être initialisé avec le même principe que la classe Perso, c.a.d. en utilisant une variable statique counter, qui est incrémentée à chaque appel du constructeur de Street.
    • name : le nom de la rue,
    • shops : un tableau content des objets Shop
  • La classe Street contient comme méthodes :
    • le constructeur permettant d'initialiser id, name
    • addShop(shop) : ajoute shop au tableau shops.
    • fromJSON(obj) : méthode statique renvoyant un objet Street, initialisé avec le JSON obj donné en paramètre.

 

Exercice 3 - la ville

  • Modifier model.js pour ajouter la classe Town
  • La classe Town contient comme attributs :
    • id : l'identifiant de la ville. Doit être initialisé avec le même principe que la classe Perso, c.a.d. en utilisant une variable statique counter, qui est incrémentée à chaque appel du constructeur de Town.
    • name : le nom de la ville,
    • streets : un tableau content des objets Street
  • La classe Street contient comme méthodes :
    • le constructeur permettant d'initialiser id, name
    • addStreet(street) : ajoute street au tableau streets.
    • fromJSON(obj) : méthode statique renvoyant un objet Town, initialisé avec le JSON obj donné en paramètre.

 

Exercice 4 - initialisations

  • Modifier model.js pour :
    • créer 9 boutiques, dont 3 vendent des items de catégorie helmet, armor, weapon, 3 autres les catégories clothes, purse, food, lighter, et les 3 dernières crown, spell, potion,
    • créer 3 rues, nommées par exemple "Smith Street", "Baker Street" et "Magic Street". Elles contiennent respectivement les groupes de 3 boutiques donnés ci-dessus.
    • créer une ville contenant les 3 rues données ci-dessus.
  • Modifier controller.js pour : 
    • ajouter des variables currentStreet et currentShop, représentant respectivement la rue "active" et la boutique "active" dans cette rue (cf. ci-dessous)
    • afin de faire des tests, initialiser ces 2 variables avec une des instances de rue et de boutique créées dans model.js

 

Exercice 5 - la page HTML - mise en place

  • En reprenant le code de shop.html, créer un fichier index.html permettant d'afficher une page avec les contraintes suivantes :
    • en haut à gauche de la page, une liste déroulante permet de sélectionner un aventurier.
    • à droite de cette liste et à peu près au centre doit être affiché en très gros le nom de la ville,
    • juste en dessous du nom, il y a deux colonnes de petite hauteur.
    • la colonne de gauche contient les noms des rues, sous la forme d'une liste verticale avec des boutons radio. Cela permet de sélectionner la rue active.
    • la colonne de droite contient les noms des boutiques de la rue active, sous la forme d'une liste verticale avec des boutons radio. Cela permet de sélectionner la boutique active.
    • le bas de la page est également découpé en 2 colonnes.
    • la colonne de gauche contient le descriptif de l'aventurier sélectionné. Dans un premier temps Il suffit de reprendre ce qui a été fait dans le TP 1 puis d'ajouter :
      • un champ de saisie et un bouton, permettant de sélectionner un numéro d'item à commander.
      • deux champs de saisie et un bouton, permettant de sélectionner un numéro de slot et un numéro d'item que l'aventurier souhaite revendre à la boutique.
    • la colonne de droite est elle-même découpée en 2 sous-colonnes : celle de gauche contient un paragraphe (nommé stocklist dans la suite) avec liste numérotée des items en stock de la boutique courante, celle de droite un paragraphe (nommé orderlist dans la suite) contenant ceux qui sont sur commande.

ATTENTION : ne pas oublier de mettre des attributs id aux balises pour lesquelles il faudra récupérer des informations ou modifier leur contenu.

 

Exercice 6 - ajout de fonctionnalités

NB : comme indiqué en préambule, on ne va pas rendre la page entièrement fonctionnelle. Par exemple, il ne se passe rien s'il y a un changement de sélection dans la liste des rues, boutiques. 

  • Ces fonctionnalités nécessitent de modifier ou d'ajouter des méthodes à controller.js et à model.js

 

  • Quand un rue+boutique est sélectionnée, les listes d'item en stock et sur commande doivent apparaître :
    • ajouter une méthode updateStockList() qui construit une chaîne de caractère formant la liste numérotée des items en stock de la boutique courante. Cette chaîne est ensuite affectée à l'élément paragraphe stocklist.
    • ajouter une méthode updateOrderList() qui construit une chaîne de caractère formant la liste numérotée des items sur commande de la boutique courante. Cette chaîne est ensuite affectée à l'élément paragraphe orderlist.
    • à la fin de controller.js, appeler ces 2 méthodes.

 

  • Quand un aventurier achète un item, c'est dans la boutique courante : modifier la fonction buy()
    • pour qu'elle utilise le tableau currentShop.itemStock plutôt que la liste générale items.
    • si la vente est possible, appeler la fonction sell() de currentShop
    • mettre à jour sur la page la liste des items en stock (cf. updateStockList)

 

  • Pour qu'un aventurier puisse commander un item à la boutique courante, ajouter une méthode order() qui sera appelé lorsque l'on clique sur le bouton "Order". Cette méthode vérifie que le numéro d'item à commander est valide puis crée un timer de 2 secondes (cf. fonction setTimeout() de JS). Quand le timer est terminé, la fonction on appelle la fonction order() de currentShop et on met à jour la liste des items en stock
  • NB : il n'est pas correct de mettre le timer directement dans la méthode order() de la boutique. En effet, cette méthode n'a normalement pas accès aux fonction de controller.js. De plus, le timer fait partie du contrôle de l'application, pas du modèle de données.

 

  • Pour qu'un aventurier puisse vendre un item à la boutique courante,
    • dans la classe Perso de model.js, ajouter une méthode sell(slotIndex, itemIndex, price) qui supprime l'item indiqué du slot indiqué, et qui crédite le solde d'or de price.
    • dans controller.js, ajouter une méthode sell() qui sera appelé lorsque l'on clique sur le bouton "Sell". Cette méthode vérifie que le numéro de slot et d'item à vendre sont valides. Ensuite, elle utilise estimate() pour estimer le prix de revente et affiche une pop-up pour demander une confirmation. Si c'est d'accord, l'item est vendu à la boutique (appel à buy() de currentShop + sell() de player). Enfin, la page doit être mise à jour en appelant les méthodes associées aux différents changements (or, item en stock, slots)

 

Exercice 7 - où l'on fait ce qui ne devait pas être fait.

  • Pour ceux qui sont à l'aise en JS, vous pouvez rendre l'application totalement fonctionnelle :
    • changer le contenu de la colonne aventurier en fonction de celui qui est sélectionné dans la liste en haut à gauche.
    • changer la liste des boutiques lorsque l'on sélectionne une rue,
    • changer la liste des items en stock et sur commande lorsque l'on sélectionne une boutique.