rapport projet java2 · 2016-06-07 · 3~! i.e)!scénariodétaillé!...
TRANSCRIPT
~ 1 ~
Rapport projet JAVA
Lien site web : http://perso.esiee.fr/~blondine/
I.A) Auteur Heir to the demon Eliott Blondin B) Thème Dans le Royaume de Parse, le jeune prince Arslan doit vaincre Hilmes et reprendre le trône qui lui a été volé. C) Résumé complet du scénario Au travers du royaume de Parse, Arslan, jeune prince âgé de quinze ans, va devoir convaincre ses alliés pour ainsi, les rallier à sa noble cause. La fin se déroulera dans la capitale de Parse où se trouve Hilmes et devra arriver à la salle du trône où il défiera finalement celui qui a capturé le roi.
~ 2 ~
I. D) Plan
Vue global du jeu:
Vue de la dernière pièce (Ectabana)
~ 3 ~
I. E) Scénario détaillé
Une grande guerre entre deux puissants royaumes se déroule: d'un côté la Lusitania, de l'autre le Parse. Dans les plaines d'Atropatènes, Andragoras V, roi de Parse, va affronter l'armée Lusitanienne. Arslan va dès lors participer à sa première bataille. Mais Atropatènes se révèle être un piège mortel : aidés par un traître et dirigés par un mystérieux général se dissimulant sous un masque d'argent, les Lusitaniens infligent une défaite aux Parses, capturent le roi et assiègent le château de Parse. Ayant réussi à échapper à des assassins, Arslan va désormais chercher des alliés avec son protecteur, Darhyl, afin de réorganiser les forces de Parse pour combattre Hilmes et ses sbires.
Sous-‐ensemble du scénario : Résonner Khallan au travers d’un long dialogue pour le rallier à votre cause et ainsi libérer le roi AndragorasIII. Si Arslan échouait dans sa tentative de le résonner, Khallan tuera le roi et se fera tuer à son tour par Darhyl.
I. F) Détails des personnages, items et lieux :
Les personnages :
Arslan (vous) :
Prince héritier du Royaume de Parse et personnage principal. Durant sa première bataille, son royaume, Parse, est conquit par les Lusitaniens à cause de la trahison de Kharlan. Il est d'apparence fragile et peu sûr de lui, contrairement à son père, et très gentil ; il est prêt à mettre sa vie en jeu pour celle de ses amis, sa famille et son royaume. Au début aveugle aux défauts de Parse, il devient plus conscient des méfaits de son pays, il désire apprendre les croyances des Lusitaniens.
Darhyl :
Darhyl est un des cinq meilleurs guerriers de Parse. Il très loyal envers le Roi Andragoras et le Prince Arslân et durant la bataille d'Atropathènes, la première bataille à laquelle Arslân participe, son oncle, l'Êrhan Valphreze lui demande de jurer fidélité à Arslân sur son épée, ce qu'il accepte. Suite a la défaite des Parses, il devient le protecteur du prince Arslân et se montre particulièrement protecteur envers son seigneur, c'est aussi lui qui permet au prince de rencontrer Narsus car il estime que son ami pourra leur être d'une aide précieuse dans la guerre contre les Lusitaniens. Même après qu'il a appris l'identité du général au masque d'argent, et après les accusations d'autres ennemis disant que Arslân n'a aucune légitimité pour régner sur Parse, il reste tout de même d'une loyauté sans faille envers son jeune protégé.
~ 4 ~
Andragoras III :
Roi de Parse et père d'Arslân. Il est connu pour son caractère têtu et sa tendance à utiliser la force brute plutôt que la stratégie. La trahison de Kahllan et la connaissance de Masque d'Argent des stratégies de Parse ont conduit à sa défaite écrasante. Il est en vie et maintenu prisonnier. Il est soupçonné pour la mort mystérieuse de son frère aîné, le roi Osloes V, motivée par son ambition d'obtenir le trône et Tahaminé.
Masque d'argent (personnage antagoniste) :
Il est à la tête de l'armée Lusitanienne et est le principal antagoniste. Il est en réalité Hilmes, cousin d'Arslân et fils d'Osloes V, le frère aîné d'Andragoras. Il mène l'invasion de Parse pour réclamer son titre légitime. Il haït son oncle d'une haine brûlante, car ce dernier l'a défiguré en tentant de l'assassiner après la mort du précédent roi, et il s'est associé aux Lusitaniens mais aussi a une étrange secte de magiciens. Il est pyrophobe et est donc effrayé en présence de flammes... depuis, il couvre le haut de son visage, notamment la zone entourant son œil droit, d'un masque d'argent qui lui vaut son surnom.
Narsus :
Stratège de génie, Narsus était autrefois un conseiller et stratège du Roi Andragoras, mais il a été banni après avoir contesté la décision du Roi de maintenir l'esclavage et parce qu'il estimait les membres du gouvernement incompétents et corrompus. Il est un excellent stratège, mais aussi une fine lame et un philosophe, même s'il est plus fier de ses médiocres talents de peintre que de ses qualités. Il avait prédit que le manque de stratégie du Roi et son refus de libérer les esclaves mènerait à la chute du royaume.
Kubard :
Faisant parti des Mazbharns, Kubard n’est presque jamais vu sobre. En tant que guerrier vétéran, il n'a pas peur des grandes batailles. Mais choqué et en colère quand il apprit que le roi avait fui , il cessa de combattre en déclarant qu’un roi qui ne protège pas son peuple n’en est pas un.
Bodin :
Bodin est un croyant sanguinaire de Yaldabaoth (croyance de la Lusitanie) , qui utilise sa position et le pouvoir de tuer indistinctement des esclaves. Il est impitoyable et sans pitié et a torturé des mazbharns de Pars pendant le siège de Ecbatana.
~ 5 ~
Kahllan : Un des Mazbharn de l'armée de Parse. Il trahit Parse, ce qui entraîne la chute du Royaume, et sert maintenant Lusitania.
Sam :
Fait parti des Mazbharns de Pars.
Hodir :
Un général Lusitanien.
Xandes :
Il est le fils de Mazbharn Khallan de Pars et un serviteur de Hilmes . Il est très haineux , se met en colère très rapidement et semble ne pas tolérer l'incompétence. Il est très fidèle à Hilmes.
Garshasph :
Garshasph est l’un des Mazbharn de Pars, il commande 10 000 cavaliers.
Baqhman :
Il est le plus vieux des Mazbharns de Pars.
~ 6 ~
Les lieux :
-‐Forest : Forêt près de la plaine d'Atropanes (lieu de départ du joueur principal : vous) -‐Baldad : première ville rencontrée et la plus florissante en terme de commerce.
-‐Sindora : une citée près des montagnes. -‐Peshawar : un village de pêcheurs. -‐Ectabana : Capitale de Parse, Château du royaume (composé de 7 pièces)
-‐Common Room -‐Armory -‐Castle courtyard -‐Secret tunnel -‐King’s apartements (étage "east upstairs" -‐Throne room (étage "north upstairs") -‐Dungeon
Les items : -‐Silver Mask -‐ Arslan’s sword
-‐Falcon
-‐Armor forged in Baldad
-‐Caravan (magic-‐cookie)
I. G) Situation(s) gagnante(s) et perdante(s)
Situation(s) gagnante(s) :
Vaincre Hilmes avec l’aide de 3 Mazbharns minimum.
~ 7 ~
Situation(s) perdante(s) : Avoir parmi ses alliés au plus de 2 Mazbharns (généraux) lors de l’affrontement final.
N’avoir pas pu vaincre votre ennemi dans le temps imparti.
I. I) Commentaires (ce qui manque, reste à faire) Exercie 7.49 (moving character) non fini.
~ 8 ~
Deuxième partie : Réponses aux exercices du projet
Ex 7.2.1 : Classe Scanner
Comprendre l'utilisation de la classe Scanner dans zuul-‐bad pour lire au clavier
D'après les informations données:
« Comprendre l'utilisation de la classe Scanner dans zuul-‐bad pour lire au clavier :
System.in désigne le clavier (comme System.out désigne l'écran)
Il faut créer un objet Scanner en lui passant le clavier en paramètre :
Scanner vScan = new Scanner( System.in );
Pour pouvoir compiler, il faut indiquer au compilateur où se trouve la classe
Scanner : import java.util.Scanner; .
Il faut créer une String pour contenir les caractères qui seront tapés au clavier :
String vLigne; .
Ensuite, à chaque fois qu'on écrira l'instruction vLigne = vScan.nextLine();
toute la ligne de caractères tapés au clavier sera stockée dans vLigne.
En attendant que des caractères soient tapés au clavier, le programme reste
bloqué. Il est donc indispensable de prévenir l'utilisateur de ce qu'on attend
de lui, en affichant quelque chose comme "Veuillez taper une commande : "
ou plus simplement "> " »
=> On comprend dès lors que la classe Scanner nous permet de rentrer des informations au clavier que la machine pourra récupérer et réutiliser.
Exercice 7.4 : création des pièces du jeu
Modification du code source préexistant de Zuul-‐bad dans un nouveau projet comme demandé :
-‐modification de la méthode CreateRooms() dans la classe Game pour créer les pièces de jeu en remplaçant le nom des pièces de Zuulbad par les notres :
outside = new Room("outside the main entrance of the university");
Est devenu ainsi par exemple
~ 9 ~
Room vForest ;
vForest = new Room("dans la forêt d'Atropatenes");
avec le nom de la avant avant « =new Room » et la description de celle-‐ci entre parenthèses. La room « Forest » a été déclarée juste avant.
7. 5. printLocationInfo
w Création d'une procédure printLocationInfo() dans la classe Game, reprenant le code
redondant des méthodes createRooms() et goRoom().
w Remplacement du code dupliqué des 2 méthodes citées par l'appel de la procédure
précédente.
7. 6. getExit
w Ajout de l'accesseur getExit() dans la classe Room afin de réduire le niveau de couplage.
w Utilisation de l'accesseur getExit() dans la classe Game (méthode goRoom()) afin de
n'utiliser que les retours de getExit().
7. 7. getExitString
wModification de printLocationInfo() :
private void printLocationInfo()
{
System.out.println("You are " + aCurrentRoom.getDescription());
System.out.print(aCurrentRoom.getExitString());
System.out.println();
}
~ 10 ~
Définition de getExitString() sur le modèle :
-‐ if (getExit("west") != null)
{vWest = "west ";}
-‐ else
{vWest = "";}
-‐ return ("Sorties : " + vNorth + vEast + vSouth + vWest);
7. 8. HashMap, setExit
w Ajout de l'outil HashMap et changements, expliqués dans le pdf, apportés.
7. 8. 1. Ajout d'un déplacement vertical
w Ajout de toutes les pièces du plan (ici, niveaux « Upstairs », « Downstairs », « EastUpstairs », « NorthUpstairs ») : incluant les déplacements haut, bas et escaliers nord et escaliers est.
On garde les directions nord ("North"), sud ("South"), est ("East"), ouest ("West").
7. 9. keySet
w La méthode keySet() de la classe HashMap permet d'accéder à la liste de toutes les clés
contenues dans une HashMap. 7.10. getExitString CCM
wLa méthode getExitString() renvoie une description des sorties possibles d’une pièce : -‐String returnString = « Exits : » ; //initialisation de la variable returnString (de type String) et stockage afin de commencer la chaîne de caractère « Exits : ». -‐Set<String> keys = exits.ketSet() ; //initialisation de la variable keys (de type Set<String>) et stockage de la liste des clés de la HashMap exits, exits étant un attribut de type HashMap de l’objet Room courant).
~ 11 ~
-‐for (String exit : keys) {returnString += " " + exit;} //déclaration d’une variable locale exit prenant comme valeur la prochaine clé de la HashMap. //à chaque tour de la boucle for, on concatène un espace et la valeur de exit à la chaîne de caractères returnString -‐return returnString ; //on finit par retourner une chaîne de caractère par exemple : « Exits : north east west »
7.11. getLongDescription
wSelon les indications expliqués dans le pdf : on ajoute la méthode getLongDescription() dans la classe Room, puis on modifie la méthode printLocationInfo(). 7.14. look
wOn ajoute la commande « look » dans la classe CommandWord. wOn ajoute également la méthode look() dans la classe Game ainsi que
else if (commandWord.equals(« look »)) {look() ;} dans la classe Game.
7.15. eat
wOn ajoute la commande « eat » dans la classe CommandWord.
wOn ajoute également la méhode eat() dans la classe Game ainsi que
Else if (commandWord.equals(« eat »)) {eat() ;} dans la méthode interpretCommand()
de la classe Game.
7.16. showAll, showCommands
wOn effectue les changements décrits dans le pdf.
~ 12 ~
7.18. getCommandsList
wOn effectue les changements suivants :
Dans la classe CommandWords :
-‐On transforme la méthode showAll() en getCommandsList() :
public String getCommandsList()
{
String vCommands = « » ;
For (String command : validCommands)
{
vCommands += command + « » ;
}
return vCommands ;
}
Dans la classe Parser :
-‐On modifie de la procédure void showCommands() en String showCommands():
public String showCommands()
{
return commands.getCommandsList() ;
}
Dans la classe Game :
-‐On modifie la méthode printHelp() :
parser.showCommands() è ;System.out.println(parser.showCommands() + « \n » ;
~ 13 ~
7.18.1. Comparer son jeu au projet zull-‐better
wDans la classe Game :
-‐Au niveau de la procédure void printLocationInfo() :
void printLocationInfo() è System.out.println(aCurrentRoom.getLongDescription()) ;
dans notre classe utilisé par zuul-‐better
wAucun changement n’a été effectué dans les autres classes en comparaison avec zuul-‐
better.
7.18.6 Etudier le projet zuul-‐with-‐images
wOn modifie le projet en fonction du modèle de zuul-‐with-‐images.
7.18.7. addActionListener() et actionPerformed()
wDans la classe UserInterface :
Dans la méthode createGUI() :
On initialise la variable entryField de type JtextField (un champ servant à recueillir du
texte) comme un champ de 34 caractères :
entryField = new JTextField(34);
On ajoute la classe UserInterface à la liste des auditeurs de entryField.
C'est-‐à-‐dire que lorsqu'un événement se produira sur l'objet entryField (lorsque l'on
validera un texte entré dans le champ), la méthode de signature public void
~ 14 ~
actionPerformed(ActionEvent e), située dans la classe UserInterface, va être invoquée
automatiquement.
entryField.addActionListener(this);
Dans la méthode actionPerformed() :
Elle est appelée automatiquement lorsque entryField est stimulé et consiste à appeler la
méthode processCommand() située en dessous.
7.18.8. Ajouter au mois un bouton
Ajout des boutons : Look, Help, Quit, North, South, East, West, Upstairs, Downstairs,
UpstairsNorth, UpstairsEast.
wDans la classe UserInterface :
-‐On ajoute d’attributs pour chaque bouton: exemple, private JButton aBoutHelp ;
Dans la méthode createGUI() :
-‐On initialise chaque bouton : this.aBoutHelp = new JButton("Help");
-‐On place le premier panel qui contient l’image et l’affichage dans la fenêtre
myFrame (première colonne) : `
JPanel vPanel1 = new JPanel();
this.aMyFrame.getContentPane().add(vPanel1, BorderLayout.CENTER);
this.aImage = new JLabel();
~ 15 ~
-‐On ajoute un deuxième panel pour y mettre les boutons Help, Quit, Look (1) ces
derniers sont ajoutés dans ce panel-‐ci (2) puis on place le panel dans la fenêtre
myFrame (3):
JPanel vPanel2 = new JPanel();
this.aMyFrame.getContentPane().add(vPanel2, BorderLayout.EAST);
this.aBoutRegarder = new JButton("look");
this.aBoutQuit = new JButton("quit");
this.aBoutHelp = new JButton("help");
vPanel2.setLayout(new GridLayout(2,2));
vPanel2.add(this.aBoutQuit);
vPanel2.add(this.aBoutRegarder);
vPanel2.add(this.aBoutHelp);
-‐On ajoute un troisième panel pour y mettre les boutons de directions (1), ces
derniers sont ajoutés dans ce panel-‐ci (2) puis on place le panel dans la fenêtre
myFrame (3) :
JPanel vPanel3 = new JPanel();
this.aMyFrame.getContentPane().add(vPanel3, BorderLayout.SOUTH);
this.aBoutNorth = new JButton("North");
this.aBoutSouth = new JButton("South");
this.aBoutEast = new JButton("East");
this.aBoutWest = new JButton("West");
this.aBoutUpstairs = new JButton("Upstairs");
this.aBoutDownstairs = new JButton("Downstairs");
this.aBoutEastUpstairs = new JButton("EastUpstairs");
~ 16 ~
this.aBoutNorthUpstairs = new JButton("NorthUpstairs");
vPanel3.setLayout(new GridLayout(2,8));
vPanel3.add(this.aBoutNorth);
vPanel3.add(this.aBoutSouth);
vPanel3.add(this.aBoutEast);
vPanel3.add(this.aBoutWest);
vPanel3.add(this.aBoutUpstairs);
vPanel3.add(this.aBoutDownstairs);
vPanel3.add(this.aBoutEastUpstairs);
vPanel3.add(this.aBoutNorthUpstairs);
-‐Puis on ajoute :
this.aBoutRegarder.addActionListener(this);
this.aBoutQuit.addActionListener(this);
this.aBoutHelp.addActionListener(this);
this.aBoutNorth.addActionListener(this);
this.aBoutSouth.addActionListener(this);
this.aBoutWest.addActionListener(this);
this.aBoutEast.addActionListener(this);
this.aBoutUpstairs.addActionListener(this);
this.aBoutDownstairs.addActionListener(this);
this.aBoutEastUpstairs.addActionListener(this);
this.aBoutNorthUpstairs.addActionListener(this);
~ 17 ~
Dans la méthode actionPerfomed() :
-‐On modifie la procédure afin de différencier les différentes sources qui
déclencheront l’événement actionPerformed selon le modèle suivant :
if (pE.getSource() == this.aBoutRegarder)
{
this.aEngine.interpretCommand("look");
}
/* idem pour les autres boutons */
7.19.2. Déplacer toutes les images
wOn crée le dossier Images à la racine du jeu.
wOn change le chemin des noms des images associées aux Rooms dans la HashMap sous
le modèle suivant : « Forest.gif » è « Images/Forest.gif »
7.20. Item
wOn crée la classe Item de la sorte :
public class Item
{
private double aWeightItem;
private String aDescriptionItem;
private String aImageItem ;
public Item(final double pWeight, final String pDescription, final String pImageItem)
{
this.aWeightItem= pWeight;
~ 18 ~
this.aDescriptionItem= pDescription;
this.aImageItem = pImageItem ;
} //Item()//
public String getItemDescription()
{
return aDescriptionItem;
}
public double getWeight()
{
return aWeightItem;
}
public String getImageItem()
{
return aImageItem ;
}
public double setWeight(final double pWeightItem)
{
return this.aWeightItem = pWeightItem;
}
}
~ 19 ~
wDans la classe GameEngine :
-‐On crée la méthode createItems() :
Création des items du jeu :
Item ArslanSword = new Item(4, ArslanSword) ;
Association des items du jeu à des salles :
this.allRooms.get(« take»).addItem(« Arslan’s sword »,
Arslan’s sword) ;
-‐Dans le constructeur GameEngine() :
On appelle la méthode createItems().
7.21. Item Description
wDans la classe Item :
public String getLongItemDescription()
{
return this.aDescriptionItem + "" + this.aWeightItem;
}
wDans la classe Room :
-‐On ajoute la méthode getItemString() pour indiquer au joueur les items qui sont
présents suivant la pièce dans laquelle il se trouve.
public String getItemString()
{
return this.aItem.getItemStrings ();
~ 20 ~
}
-‐On modifie la méthode getLongDescription() de la sorte :
public String getLongDescription ()
{
return "You are " + this.aDescription + ".\n" + getExitString () + ".\n" + getItemString() ;
}//getLongDescription
7.22. Items
wOn utilise une HashMap qui associe des clés String (c’est-‐à-‐dire le nom de l’item) à des
valeurs Item (l’objet). Par exemple, (« Arslan’s sword, Arslan’s sword).
7.22.1 Justifier le choix
wOn utilise cette HashMap car cela nous permettra de rechercher plus facilement un
Item en fonction de son nom, si besoin est.
7.22.2 Intégrer les objets (items)
wLes items suivants sont intégrés dans le jeu : Silver Mask Arslan’s Sword Falcon
~ 21 ~
7.23. back
wDans la classe GameEngine :
-‐On ajoute l’attribut Room aPreviousRoom.
-‐On ajoute dans la méthode createRooms() :
aPreviousRoom = aCurrentRoom ;
-‐On ajoute l’instruction aPrevious = aCurrentRoom ; dans la méthode goRoom().
-‐On modifie la méthode interpretCommand() pour prendre back en compte :
else if (commandWord.equals(« back »))
this.back(vCommand) ;
-‐On ajoute la méthode back() :
private void back()
{
Room vR = aCurrentRoom ;
aCurrentRoom = aPreviousRoom ;
aPreviousRoom = vR ;
this.aGui.println(« \n » + aCurrentRoom.getLongDescription() + « \n ») ;
if (aCurrentRoom.getImageName() != null)
{
this.aGui.showImage(aCurrentRoom.getImageName()) ;
}
}
wDans la classe CommandWords :
-‐On ajoute « back » dans le tableau de Strings aValidCommands.
~ 22 ~
7.26. Stack
wDans la classe GameEngine :
-‐On ajoute l’attribut Stack<Room> aPreviousRoom
-‐On initialise dans le constructeur : this.aPreviousRoom = new Stack<Room>();
-‐On ajoute dans la boucle if/else de la méthode goRoom() :
this.aPreviousRoom.push(aCurrentRoom);
-‐On modifie la méthode back() :
private void back()
{
if(this.aPreviousRoom.empty() == true)
{
aGui.println("You can't go back...");
}
else{
Room vLastRoom = this.aPreviousRoom.pop();
this.aCurrentRoom = vLastRoom;
this.aGui.println("\n" + aCurrentRoom.getLongDescription() + "\n");
if (aCurrentRoom.getImageName() !=null)
{
this.aGui.showImage(aCurrentRoom.getImageName());
}
}
}
~ 23 ~
7.28.1 Créer une nouvelle commande test
wDans la classe CommandWord :
-‐On ajoute le mot « test » dans le tableau de String.
wDans la classe GameEngine :
-‐On importe : -‐> java.io.* ;
-‐> java.util.Scanner ;
-‐On ajoute dans la méthode interpretCommand() :
else
if (vCmd.equals("test"))
{
this.test(vCommand);
}
-‐On ajoute la méthode test() :
private void test(final Command pCommand)
{
if(pCommand.hasSecondWord() == false)
{
this.aGui.println("Which file do you want to test my dear ?");
}
else { String vFile = pCommand.getSecondWord();
InputStream vIS =
this.getClass().getClassLoader().getResourceAsStream(vFile+".txt");
Scanner vSc = new Scanner ( vIS );
while (vSc.hasNextLine() )
{
String vLine = vSc.nextLine();
~ 24 ~
interpretCommand(vLine);
}
vSc.close();
}
}
7.29. Player
wOn déplace la pièce courante dans la classe Player. Pour l’instant, notre « player »
possède les caractéristiques suivantes : son nom, sa taille d’inventaire d’objets
récupérés et le lieu où il se trouve. Ces caractéristiques-‐ci sont par la suite gérées dans la
classe Player afin de ne pas surcharger la classe GameEngine. On crée un objet Player au
début du jeu pour stocker ces données.
wCréation de la classe Player :
public class Player
{
private String aName;
public Room aCurrentRoom;
private Stack <Room> aPreviousRooms;
private double aTotalWeight ;
public Player(final String pName, final double pMaxWeight)
{
this.aName = pName;
this.aPreviousRooms = new Stack <Room> ();
this.aTotalWeight= pMaxWeight;
~ 25 ~
} //Player
public Stack <Room> getBackRoom()
{
return this.aPreviousRooms;
}
public Room getCurrentRoom()
{
return this.aCurrentRoom;
}
public String getName()
{
return this.aName;
}
public void setCurrentRoom(final Room pCurrentRoom)
{
this.aCurrentRoom= pCurrentRoom;
}
public void setMaxWeight(final double pWeight)
{
aTotalWeight= pWeight;
}
public double getMaxWeight()
{
return aTotalWeight;
~ 26 ~
}
}// Player
wDans GameEngine :
-‐On crée l’attribut : private Player aPlayer ;
-‐On rajoute dans le contructeur la méthode createPlayer()
-‐On crée la méthode createPlayer() :
private void createPlayer()
{
aPlayer = new Player("Eliott", 50);
}
-‐On modifie dans la méthode createRooms() :
aPlayer.setCurrentRoom(vForest);
7.30. Take / Drop
wDans la classe CommandWords :
-‐On ajoute « take » et « drop » dans le tableau de Strings aValidCommands.
wDans la classe GameEngine :
-‐On modifie la méthode interpretCommand() pour prendre take et drop en
compte :
~ 27 ~
else if (commandWord.equals(« take »))
this.take(vCommand) ;
else if(commandWord.equals(« drop »))
this.drop() ;
-‐On ajoute les méthodes take() et drop() :
private void take(final Command pCommand)
{
String vCommand = pCommand.getSecondWord();
if (!pCommand.hasSecondWord()){
this.aGui.println("Take what?");
}
else
{
Item vItem =
this.aPlayer.getCurrentRoom().getItemList().getItem(vCommand);
double aCurrentWeight =+ vItem.getWeight();
if(this.aPlayer.getMaxWeight() -‐ aCurrentWeight <0)
this.aGui.println("This is too heavy !");
else if (vItem == null)
{
this.aGui.println("Item doesn't exist");
}
~ 28 ~
else if (this.aPlayer.getCurrentRoom().getItemList().hasItem(vCommand)
)
{
this.aPlayer.setMaxWeight(this.aPlayer.getMaxWeight()-‐
vItem.getWeight());
this.aPlayer.getItemInv().addItem(vCommand,vItem);
this.aPlayer.getCurrentRoom().getItemList().removeItem(vCommand);
this.aGui.println (this.aPlayer.getItemInv().getInventoryString() + ".\n"
+this.aPlayer.getCurrentRoom().getLongDescription());
}
}
}
private void drop(final Command pCommand){
String vCommand = pCommand.getSecondWord();
Item vItem = this.aPlayer.getItemInv().getItem(vCommand);
if (!pCommand.hasSecondWord())
{
aGui.println("Drop what ?");
return;
}
else if (this.aPlayer.getItemInv().hasItem(vCommand) )
{
this.aPlayer.setMaxWeight(this.aPlayer.getMaxWeight() +
vItem.getWeight());
this.aPlayer.getItemInv().removeItem(vCommand);
this.aPlayer.getCurrentRoom().getItemList().addItem(vCommand,vItem);
~ 29 ~
this.aGui.println (this.aPlayer.getItemInv().getInventoryString() + ".\n"
+this.aPlayer.getCurrentRoom().getLongDescription());
}
else
{
aGui.println("Item doesn't exist");
}
}
7.31.1. Classe ItemList
wCréation de la classe ItemList :
import java.util.ArrayList;
import java.util.HashMap;
public class ItemList
{
private HashMap <String, Item> aCollection;
private ArrayList <Item> aListe;
public ItemList()
{
this.aCollection = new HashMap <String, Item> ();
this.aListe = new ArrayList <Item> ();
} //ItemList()
public String getItemStrings ()
~ 30 ~
{
StringBuilder returnString = new StringBuilder( "Items:" );
for ( String vA : aCollection.keySet() )
returnString.append( " " + vA );
return returnString.toString();
}
public Item getItem (final String pName)
{
return aCollection.get(pName);
}
public void addItem (final String pName,final Item pItem)
{
aCollection.put(pName,pItem);
}
public void removeItem (final String pName)
{
aCollection.remove(pName);
}
} // ItemList
wDans la classe Player :
-‐On crée l’attribut : private ItemList aInventory;
-‐On ajoute la méthode getItemInv() :
public ItemList getItemInv()
{
~ 31 ~
return this.aInventory ;
}
-‐On modifie l’emplacement des objets dans les salles par :
vBaldad.getItemList().addItem("Falcon", vFalcon);
7.32. Poids Max
Déjà fait précédemment dans la classe Player et dans la classe GameEngine (méthode
take()).
7.33. Inventaire
wDans la classe CommandWords :
-‐ On ajoute « inventory» dans le tableau de Strings aValidCommands.
wDans la classe GameEngine :
-‐ On modifie la méthode interpretCommand() pour prendre inventory en
compte :
else if (commandWord.equals(« inventory »))
this.inventory() ;
wDans la classe ItemList :
-‐On ajoute la méthode getInventoryString pour retourner une description détaillée de
l’inventaire :
~ 32 ~
public String getInventoryString ()
{
StringBuilder returnString = new StringBuilder( "You've got" );
for ( String vA : aCollection.keySet() ){
returnString.append( " " + vA);
for(Item vB: aCollection.values())
returnString.append("" + vB);
}
return returnString.toString();
}
7.34. magic cookie
wDans la classe GameEngine :
-‐On crée dans la méthode createRooms() un nouvel item (cookie) :
Item Caravan = new Item(1, "Caravan");
magicCookie.setEdible(true);
-‐On le place ensuite dans une salle :
vBaldad.getItemList().addItem("Caravan", magicCookie);
-‐On modifie dans la méthode interpretCommand() la gestion du mot de
commande « eat » afin de gérer un second mot dans la méthode eat() :
else if (commandWord.equals(« inventory »))
this.eat(vCommand) ;
~ 33 ~
-‐On modifie la méthode eat() de la sorte :
private void eat()
{
if(! pCommand.hasSecondWord())
{
this.aGui.println("Eat what ?");
return;
}
String vName = pCommand.getSecondWord();
if(! aPlayer.getItemInv().hasItem(vName))
{
this.aGui.println("You have not any " + vName);
return;
}
Item vItem = aPlayer.getItemInv().getItem(vName);
if(! vItem.isEdible())
{
this.aGui.println("You can't eat " + vName);
}
this.aPlayer.getItemInv().removeItem(vName);
this.aGui.println("You have " + vName);
if( vName.equals("Caravan"))
{
this.aPlayer.setMaxWeight(aPlayer.getMaxWeight() + 1000);
this.aGui.println("You can now wear more items");
~ 34 ~
}
}
wDans la classe Item :
-‐On crée l’attribut suivant : private boolean aEdible ;
-‐On rajoute dans le constructeur :
this.aEdible= false;
-‐On ajoute deux nouvelles méthodes isEdible() et setEdible() ;
public boolean isEdible()
{
return aEdible;
}
public void setEdible(final boolean pEdible)
{
this.aEdible = pEdible;
}
wDans la classe ItemList :
-‐On ajoute la méthode hasItem() :
public boolean hasItem(final String pName)
{
~ 35 ~
return aCollection.containsKey(pName);
}
7.34.1. Mise à jour des fichiers de test
look take Caravan
eat eat Caravan
help back
inventory take ArslanSword
go North drop ArslanSword
7.35. zuul-‐with-‐enums-‐v1
wOn modifie le projet en fonction du modèle de zuul-‐with-‐enums-‐v1.
7.35.1. Switch
wDans la classe GameEngine :
-‐On implémente le switch pour remplacer la suite de if/else if :
switch (vCommandWord)
{
case HELP: printHelp();
~ 36 ~
break;
case GO: goRoom(vCommand);
break;
case QUIT: if (vCommand.hasSecondWord())
{
this.aGui.println("Quit what ?");
}//if
else
this.endGame();
break;
case LOOK: look();
break;
case EAT: eat(vCommand);
break;
case BACK: back();
break;
case TEST: test(vCommand);
break;
case TAKE: take(vCommand);
break;
case DROP: drop(vCommand);
break;
case INVENTORY: inventory();
break;
~ 37 ~
case TELEPORT: teleport(vCommand);
break;
case LOAD: load(vCommand);
break;
default: this.aGui.println("I don't know what you mean...");
break;
}
7.41.1. zuul-‐with-‐enums-‐v2
wDans l’enum CommandWords :
-‐On ajoute les valeurs de type String sur le modèle :
GO("go"), QUIT("quit"), HELP("help"), UNKNOWN("?"), LOOK("look"),
EAT("eat"), BACK("back"), TEST("test"), TAKE("take"), DROP("drop"),
INVENTORY("inventory") ;
-‐On ajoute le constructeur CommandWord() ainsi que la méthode toString()
explicités dans le projet zuul-‐with-‐enums-‐v2 :
CommandWord(final String pCommandString)
{
this.aCommandString = pCommandString;
}
~ 38 ~
public String toString()
{
return aCommandString;
}
wDans la classe CommandWords :
-‐On remplace dans le constructeur CommandWords() la suite de .put() par la
boucle for comme décrite dans le modèle.
7.42. Time Limit
wDans la classe GameEngine :
-‐On ajoute un attribut : private int aLimit ;
-‐On crée l’objet dans le constructeur :
this.aLimit = 100 ;
-‐On ajoute dans la méthode goRoom() :
aLimit -‐-‐;
this.aGui.setTimer("" + aLimit);
if(aLimit <= 0)
{
this.aGui.println("Your crusade is over, young prince.");
this.endGame();
aTimer.stop();
}
~ 39 ~
7.42.1. Time Limit with Timer
wDans la classe GameEngine :
-‐On ajoute : import java.awt.event.ActionEvent ;
import java.awt.event.ActionListener ;
import javax.swing.Timer ;
-‐On crée l’attribut : private Timer aTimer ;
-‐On ajoute dans le constructeur : this.aTimer = new Timer(1000, this) ;
this.aTimer.start() ;
-‐On ajoute également dans la méthode setGui(UserInterface pUserInterface) :
this.aGui.setTimer (« » + aLimit) ;
-‐On supprime de la méthode goRoom() :
aLimit -‐-‐;
this.aGui.setTimer("" + aLimit);
if(aLimit <= 0)
{
this.aGui.println("Your crusade is over, young prince.");
this.endGame();
aTimer.stop();
~ 40 ~
}
-‐On crée une nouvelle méthode :
@Override public void actionPerformed( ActionEvent pE)
{
aLimit -‐-‐;
this.aGui.setTimer("" + aLimit);
if(aLimit <= 0)
{
this.aGui.println("Your crusade is over, young prince.");
this.endGame();
aTimer.stop();
} }
wDans la classe UserInterface :
-‐On ajoute l’attribut suivant : private JtextArena log, aTimer ;
-‐On ajoute la méthode setTimer() :
public void setTimer(String pText)
{
aTimer.setText(pText);
}
-‐On ajoute dans la méthode createGUI() :
aTimer = new JtextArea() ;
aTimer.setEditable(false) ;
vPanel1.add(aTimer, BorderLayout.EAST)
~ 41 ~
7.43. Trap Door
wDans la classe GameEngine :
-‐On modifie le else de la méthode back() de la façon suivante :
else{
if(aPlayer.getCurrentRoom().getTrapRoom())
{
this.aGui.println("You can go back anymore... you must defeat Hilmes
before backup arrive");
}
else{
Room vLastRoom = this.aPreviousRoom.pop();
this.aPlayer.aCurrentRoom = vLastRoom;
this.aGui.println("\n" + aPlayer.aCurrentRoom.getLongDescription() + "\n");
if (aPlayer.aCurrentRoom.getImageName() !=null)
{
this.aGui.showImage(aPlayer.aCurrentRoom.getImageName());
}
}
}
wDans la classe Room :
~ 42 ~
-‐On ajoute : import java.util.Set;
private boolean aTrapRoom;
-‐On crée un accesseur getTrapRoom() et un modificateur setTrapRoom() :
public boolean getTrapRoom()
{
return aTrapRoom;
}
public void setTrapRoom(final boolean pTrapRoom)
{
this.aTrapRoom = pTrapRoom;
}
7.44. Beamer
wCréation d’une classe Beamer qui hérite de la classe Item :
public class Beamer extends Item
{
private Room aSavedRoom;
private boolean aLoaded;
public Beamer(final double pWeight, final String pDescription)
{
super(pWeight, pDescription);
aLoaded = false;
~ 43 ~
}
public Room getSavedRoom()
{
return aSavedRoom;
}
public void setSavedRoom(final Room pSavedRoom)
{
this.aSavedRoom = pSavedRoom;
}
public boolean isLoaded()
{
return aLoaded;
}
public void setLoaded(final boolean pLoaded)
{
this.aLoaded = pLoaded;
}
}
wDans la classe GameEngine :
-‐On ajoute une méthode load() et une méthode teleport() de la façon suivante :
public void load(final Command pCommand)
~ 44 ~
{
Room vRoomLoad = aPlayer.getCurrentRoom();
Item vItem = aPlayer.getItemInv().getItem("beamer");
if(! pCommand.hasSecondWord())
{
this.aGui.println("\n" + "What do you want to load ?");
}//if
else {
if( pCommand.getSecondWord().equals("beamer"))
{
if(vItem == null)
{
this.aGui.println("\n" + "You don't have the teleporter with you.");
}
else {
try{ vItem = (Beamer) vItem;}
catch (final Exception ClassCastException)
{this.aGui.println("\n" + "This isn't a teleporter");
return;
}//catch
Beamer vBeamer = (Beamer) vItem;
vBeamer.setSavedRoom(vRoomLoad);
vBeamer.setLoaded(true);
this.aGui.println("The item which is loaded in the teleporter is : " +
aPlayer.getCurrentRoom().getLongDescription());
}//else
}//if
~ 45 ~
else {
this.aGui.println("You don't have this on you.");
}//else
}//else
}//load
public void teleport(final Command pCommand)
{
Item vItem = aPlayer.getItemInv().getItem("beamer");
if(vItem == null)
{
this.aGui.println("You don't have a teleporter with you.");
}
else {
try{ vItem = (Beamer) vItem;
}
catch (final Exception ClassCastException)
{
this.aGui.println("This item isn't a teleporter.");
return;
}
Beamer vBeamer = (Beamer) vItem;
if(!vBeamer.isLoaded())
{
this.aGui.println("The teleporter wasn't loaded.");
}
~ 46 ~
else {
this.aPlayer.setCurrentRoom(vBeamer.getSavedRoom());
this.aPlayer.getCurrentRoom().getLongDescription();
this.aGui.showImage(this.aPlayer.getCurrentRoom().getImageName());
}
}
}
wDans enum CommandWords :
-‐On ajoute la valeur « teleport » et « load » de type String :
...TELEPORT("teleport"), LOAD("load") ;
7.45.1. Fichiers de Test
look take Caravan
eat eat Caravan
help back
inventory take ArslanSword
go North drop ArslanSword
load teleport
load beamer quit
~ 47 ~
7.46. TransporterRoom
wCréation de la classe TransporterRoom :
import java.util.HashMap;
import java.util.ArrayList;
public class TransporterRoom extends Room
{
private HashMap<String, Room> aRooms;
private ArrayList<Room> aArrayInRooms;
private RoomRandomizer aRandomRoom;
public TransporterRoom(final String pDescription, String pImage, final
HashMap<String, Room> pRooms)
{
super(pDescription, pImage);
this.aRooms = pRooms;
this.aArrayInRooms = new ArrayList<Room>();
for(Room vA : aRooms.values())
{
aArrayInRooms.add(vA);
}
}
@Override public Room getExit(final String pDirection)
{
this.aRandomRoom = new RoomRandomizer();
int vI = aRandomRoom.nextRoom(aRooms.size());
return this.aArrayInRooms.get(vI);
} }
~ 48 ~
wCréation de la classe RoomRandomizer :
import java.util.Random;
public class RoomRandomizer
{
private Random aRandom;
public RoomRandomizer()
{
this.aRandom = new Random();
}
public int nextRoom(final int pRoom)
{
return aRandom.nextInt(pRoom);
}
}
wDans la classe GameEngine :
-‐On modifie dans la méthode createRooms() la pièce qui va envoyer le joueur
dans une pièce aléatoire de la map :
TransporterRoom vThroneRoom= new TransporterRoom("in Ectabana, you're in
the throne room", "Images/Throne's room.jpg", aRooms);
-‐On ajoute une instruction telle que la pièce dans laquelle le joueur sera envoyé
par la pièce nouvellement renommée « TransporterRoom » :
aRooms.put("vEctabana1", vCastleCourtyard);
~ 49 ~
7.47. Abstract command
wDans la classe Command :
-‐On modifie la classe Command de telle sorte qu’elle soit une classe abstraite.
-‐On ajoute la méthode abstraite :
public abstract void execute(final Player pPlayer) ;
-‐On supprime l’attribut : private CommandWord aCommandWord ;
-‐On supprime les paramètres du constructeur :
public Command(){
}
-‐On modifie la méthode isUnknown() :
public void setSecondWord(final String pSecondWord)
{
this.aSecondWord = pSecondWord ;
}
wPour chaque commande, création d’une classe qui hérite de Command :
-‐Ainsi chaque classe sera de la forme :
public class QuitCommand extends Command
{
public QuitCommand(){
}
~ 50 ~
@Override public boolean execute(final Player pPlayer)
{
GameEngine.aGui.println("Thanks to play. See you soon.");
GameEngine.aGui.enable(false);
return true;
}
}
wLa méthode execute() remplace chaque méthode spécifique à sa commande :
GameEngine execute()
Au paramètre command this.
L’attribut aPlayer pPlayer
this.aGui.println() GameEngine.aGui.println
wDans la classe GameEngine :
-‐On a déplacé les méthodes goRoom(), help(), quit(), back(), look(), eat(), take(),
drop(), load(), teleport(), test(), inventory() dans les méthodes execute() de leurs
classes respectives (GoCommand, HelpCommand, QuitCommand etc...)
-‐On modifie la méthode interpretCommand() :
public static void interpretCommand(final String pCommandLine)
{
aGui.println(pCommandLine);
~ 51 ~
Command vCommand = aParser.getCommand(pCommandLine);
if(vCommand == null)
{
aGui.println("I don't know what you mean...");
}
else{
vCommand.execute(pPlayer);
}
aGui.print("\n");
}//processCommand
wDans l’enum CommandWord :
-‐On modifie les éléments de l’enum de la façon suivante :
GO("go", new GoCommand()),
-‐On modifie dès lors le constructeur :
CommandWord(final String pCommandString, final Command pCommand)
{
this.aCommandString = pCommandString;
this.aCommand = pCommand;
}
-‐On ajoute un accesseur getCommand() :
public Command getCommand()
{
~ 52 ~
return this.aCommand;
}
wDans la classe CommandWords :
-‐On ajoute un attribut : private HashMap<String, Command> aValidCommands;
-‐On modifie le contructeur : public CommandWords() { aValidCommands = new HashMap<String, Command>(); for(CommandWord vCommand : CommandWord.values()) { if(vCommand != CommandWord.UNKNOWN){ aValidCommands.put(vCommand.toString(), vCommand.getCommand()); } } } // CommandWords() -‐On ajoute la méthode get() décrite dans le zuul-‐even-‐better : public Command get(final String pCommandWord) { return (Command)aValidCommands.get(pCommandWord); } wDans la classe Parser : -‐On modifie la fin de la méthode getCommand() : public Command getCommand(String inputLine) {
~ 53 ~
String word1 = null; String word2 = null; Scanner tokenizer = new Scanner(inputLine); if(tokenizer.hasNext()){ word1 = tokenizer.next(); if(tokenizer.hasNext()){ word2 = tokenizer.next(); } } Command vCommand = aValidCommands.get(word1); if(vCommand != null) { vCommand.setSecondWord(word2); } return vCommand; }
7.47.1. Paquetages
wCréation de 5 paquetages :
-‐ pkg_mechanics qui contient les classes GameEngine et UserInterface ,
-‐ pkg_commands qui contient les classes CommandWord, CommandWords,
Command, Parser, GoCommand, HelpCommand...
-‐ pkg_items qui contient les classes Item, Beamer et ItemList,
-‐ pkg_characters qui contient la classe Player
-‐ pkg_rooms qui contient les classes RoomRandomizer, Room et
TransporterRoom.
~ 54 ~
7.48. Character
wCréation de la classe Characters :
public class Characters
{
private String aNameCharacters;
private String aTalk;
public Characters(final String pNameCharacters, final String pTalk) {
this.aNameCharacters = pNameCharacters;
this.aTalk = pTalk;
}
public String getNameCharacters()
{
return this.aNameCharacters;
}
public String getTalk()
{
return this.aTalk;
}
}
~ 55 ~
wDans la classe Room :
-‐On ajoute un attribut : private Characters aCharacters;
-‐On ajoute dans le constructeur : this.aCharacters = new Characters(null, null);
-‐On ajoute les méthodes addCharacters() et getCharacters()
public void addCharacters(final Characters pCharacters)
{
this.aCharacters = pCharacters;
}
public Characters getCharacters()
{
return aCharacters;
}
wDans la classe GameEngine :
-‐On crée tous les characters de la façon suivante :
Characters vHilmes = new Characters("Hilmes ", "Arslan...The humiltation and hardship
that I have suffered to this day...I will make sure that you suffer the same as I have!" );
-‐On les implémente dans leur pièce :
vThroneRoom.addCharacters(vHilmes);
~ 56 ~
IV. Déclaration obligatoire anti-‐plagiat
wA Axel Aboyeji pour l’emprunt de code aux exercices 7.32 (Poids Max) et 7.46 (classes
TransporterRoom et RoomRandomizer).
wA Nicolas hahn pour l’emprunt de code suivant au niveau de la boucle else if(mais avec
quelques modifications de ma part) :
...
else if (!vCharacters.getNameCharacters().equals(getSecondWord()))
{
GameEngine.aGui.println("There is no one who's named " + getSecondWord());
}
else{
GameEngine.aGui.println(vCharacters.getTalk());
}
}
return false;
}//else
}//TalkCommand