Open menu

Préambule

 
  • L'objectif des TPs est de réaliser de façon progressive une application web de type SPA (Single Page Application), modélisant une ville avec des rues contenant plusieurs boutiques (simplifiée) pour équiper un aventurier,
  • La boutique propose différents types d'articles (armes, nourriture, potions, ...) avec pour chaque article un prix et éventuellement une influence sur les caractéristiques de l'aventurier (force, défense, vie, ...). L'aventurier peut acheter les articles dans la limite des stocks disponibles et de son argent, puis ensuite s'équiper avec ces articles.
  • L'aventurier peut également vendre ce qu'il possède, en marchandant le prix.
  • L'interface de l'application sera entièrement réalisée grâce à VueJs, exceptée pour les deux premiers TP ou ce sera "à l'ancienne"
  • A terme, nous verrons également comment récupérer les données dans un BdD et accessibles via une API.

Première étape : Interface en HTML+Javascript (à l'ancienne)
 
  • Pour ce premier TP, vous devez télécharger une archive avec les canevas de code [ ici ]
  • Cette archive contient 3 fichiers :
    • shop.html : le fichier qui permet de gérer une boutique et pour l'aventurier, d'acheter des articles. Vous n'avez pas à la modifier (sauf pour tester des trucs si ça vous amuse).
    • model.js : le fichier JS qui contient le code permettant de créer les articles, les aventuriers et de gérer les achats. Vous devez remplir ce fichier avec les indications données ci-dessous.
    • controller.js : le fichier JS qui contient le code permettant de mettre à jour l'affichage quand les données (de model.js) changent. Vous n'avez qu'une fonction à écrire vous-même.


Exercice 1 - model.js

 

1.1°/ tableau itemLimits

  • Vous devez remplir le tableau itemLimits avec 5 objets (en syntaxe JSON) permettant de décrire le nombre maximum d'objets que peut porter un aventurier à un emplacement donné, ainsi que la catégorie de ces objets (cf. tableau itemCats).
  • chacun des 5 objets possède 3 attributs nommés slot (type chaîne de car.), limit (type entier) et types (tableau chaîne de car.). Leurs valeurs sont résumées dans le tableau suivant :
slot limit types
head 1 helmet, crown
body 1 armor, clothes
hands 2 weapon, lighter
belt 3 weapon, purse
bag 10 helmet, crown, clothes, ligther, potion, spell, food, purse

 

1.2°/ classe Item

  • Vous devez écrire le constructeur de la classe.
  • la classe Item a 5 attributs : id, name, type, price, effect. mais le constructeur ne prend que 4 paramètres permettant d'initialiser les 4 derniers.
  • En effet, id doit être initialisé avec la valeur de counter+1. Juste après cette initialisation, counter doit être incrémenté (NB : c'est le même principe que l'auto-indexation dans les BdD).
  • ATTENTION : le constructeur doit également vérifier que :
    • le type fourni en paramètre correspond à un élément du tableau itemCats. Sinon, type prend comme valeur chaîne vide.
    • le prix est > 0. Sinon, le prix est fixé à 0.

Rq : la méthode fromJSON() permet de renvoyer une instance d'Item, initialisée à partir d'un objet JSON contenant (à priori) les mêmes champs qu'un objet de la classe Item. Cette méthode sera utile plus tard lorsque l'on recevra des données JSON en provenance de l'API et que l'on voudra transformer ces données en objets à part entière.

 

1.3°/ classe Slot

  • Vous devez écrire le constructeur de Slot sachant que :
    • il reçoit 2 paramètres : id et name,
    • la classe à 3 attributs : id, name, items,
    • items est un tableau qui doit être vide lors de la construction.

 

  • Vous devez écrire la méthode fromJSON(), sachant que :
    • l'objet obj reçu en paramètre contient 3 champs : id, name, items.
    • id et name servent à créer une instance s de Slot,
    • items est un tableau d'objets, qui va servir à créer des instances d'Item, chacune étant ajoutée au tableau s.items (Il faut donc utiliser fromJSON() de la classe Item)

1.4°/ classe Perso

  • Vous devez écrire le constructeur de Perso, sachant que :
    • il reçoit 2 paramètres : name et level,
    • la classe a 10 attributs : id, name, level, vitality, life, strength, armor, gold, slots, boughtItems.
    • id doit être initialisé grâce à counter (même principe que pour la classe Item)
    • vitality doit être égal à 50 * level (NB : représente le nb. de points de vie max.)
    • life doit être égal à vitality (NB : représente le nb. de points de vie courant)
    • strength doit être égal à 20 * level
    • armor doit être égal à 0
    • gold = 450 (ou un autre valeur peut importe)
    • slots est un tableau contenant 5 instances de Slot :
      • instance 1 : id = 1, name = head
      • instance 2 : id = 2, name = body
      • instance 3 : id = 3, name = hands
      • instance 4 : id = 4, name = belt
      • instance 5 : id = 5, name = bag
    • boughtItems est un tableau vide.

 

  • Vous devez écrire la méthode buy(), sachant que :
    • elle prend en paramètre une instance d'Item,
    • si le prix de l'item est supérieur au solde disponible en or, la méthode renvoie la chaîne de caractère "not enough gold"
    • sinon, l'item est ajouté au tableau boughtItems et le solde d'or est réduit en conséquence, et enfin, la méthode retourne chaîne vide.

 

  • Vous devez écrire la méthode assign(), sachant que :
    • elle prend en paramètre l'indice d'un item dans le tableau boughtItems, et l'indice d'un slot dans le tableau slots.
    • elle doit vérifier si pour le slot considéré, la limite du nombre d'items est déjà atteinte (cf. itemLimits). Si c'est le cas, la méthode renvoie un message indiquant que le slot est plein (NB : indiquer le nom du slot).
    • elle doit également vérifier si le type de l'item fait partie de ceux qui peuvent être affecté au slot (cf. itemLimits). Si ce n'est pas le cas, la méthode renvoie un message indiquant que le type de l'item est invalide (NB : indiquer le type + le nom du slot).
    • Si tout est valide, l'item est supprimé de boughtItems et ajouté au slot. Enfin, la méthode retourne chaîne vide.

 

  • Vous devez écrire la méthode fromJSON(), sachant que :
    • la paramètre obj contient les 10 champs nécessaires pour initialiser une instance de Perso.
    • name et level permettent de créer une nouvelle instance p de Perso,
    • les autres champs permettent d'initialiser les 8 autres attributs,
    • pour boughtItems et slots, ne pas oublier qu'ils contiennent des objets qui vont servir à créer des instances d'Item et de Slot

1.5°/ Test

  • Une fois tout le code écrit, vous pouvez essayez de visualiser shop.html dans votre navigateur.
  • Normalement,  le contenu des tableau itemCats et items devrait s'afficher.
  • Essayez d'acheter des items en indiquant leur n°.
  • Pour l'assignation, il faut faire l'exercice suivant.
 
Exercice 2 - controller.js

 

  • Ce fichier contient le code nécessaire pour modifier l'affichage quand les données changent.
  • Il contient également du code permettant d'assigner quelques items aux 2 personnages qui sont instanciés dans model.js
  • Enfin, il initialise une variable player, qui représente le "joueur courant", donc celui donc les caractéristiques s'affichent.

 

  • Vous devez écrire la fonction assign(), sachant que :
    • si le tableau boughtItems du joueur courant ne contient rien, la fonction affiche un pop-up avec "no bought items"
    • elle récupère la valeur des champs de formulaire boughtnum et slotnum.
    • elle vérifie si ces champs sont bien des entiers et ont des valeurs valides :
      • pour boughtnum : entre 0 et la taille de boughtItems -1
      • pour slotnum : entre 0 et 4
    • si ce n'est pas le cas, la fonction affiche une pop-up avec un message décrivant le problème.
    • sinon, elle appelle la fonction assign() du joueur courant. Si celle-ci ne renvoie pas chaîne vide, l'assignation a échoué et il faut afficher dans un pop-up la chaîne.
    • sinon, tout est correct et la fonction appelle updateItems() et updateBought() pour rafraîchir la page.

 

  • Vous pouvez maintenant tester l'assignation et constater qu'il faut écrire 1 tonne de JS pour pouvoir rafraîchir la page. Fort heureusement, vuejs va nous permettre d'automatiser presque entièrement ces rafraîchissements.