Let`s Destroy the Metal Gear!

Transcription

Let`s Destroy the Metal Gear!
Let’s Destroy the Metal
Gear!
http://www.esiee.fr/~dramed/
A3P 2014/2015 – Projet ZUUL
Auteur : DRAME Daouda
1
Thème : dans une base terroriste, Snake doit supprimer la menace terroriste en
détruisant/désactivant le Metal Gear.
Scénario résumé : Solid Snake est un soldat expert en infiltration envoyé par la
CIA, qui doit infiltrer une base terroriste menaçant les États Unis d'une frappe
nucléaire. Pour cela les terroristes se sont munis d'un char bipède capable de
lancer des ogives nucléaires: Le Metal Gear. Cette menace nucléaire peut
être désactivé uniquement à l'aide des 3 cartes d’annulation de mise à feu
et/ou des deux codes secrets détenus par 2 internes de la base terroriste qui
sont maintenant détenus en tant qu’otage au sein de celle-ci.
Scénario détaillé
Contexte : L’histoire se déroule en 2014. Un groupe de soldats génétiquement
modifiés dirigé par leur chef Liquid Snake et appelé « FoxHound », ont pris le
contrôle d’une installation nucléaire et menacent de lancer une attaque
nucléaire contre les États-Unis si ils n’obtiennent pas la dépouille de Naked
Snake (aka Big Boss) un soldat légendaire doté de capacités hors norme, ainsi
qu’un chèque de 1milliard de dollars. Solid Snake un ancien membre de cette
unité (qui entre temps est devenue une unité terroriste) est envoyé sur les lieux
pour empêcher son frère Liquid Snake de mettre son plan à exécution. Liquid
et Solid sont tous deux des soldats modifiés à partir des gênes de Big Boss.
Snake arrive dans la base par le quai munie d’une combinaison de plongée.
Ce dernier emprunte un ascenseur pour se rendre à l’héliport, d’où il devra
atteindre le hangar à tank sans se faire repérer. Une fois au hangar, il trouve le
premier otage qui détient le code de désactivation du Metal Gear. Ce dernier
décède d’une crise cardiaque peu après l’arrivée de Snake. Snake rencontre
à la sortie de cette cellule un soldat pas comme les autres, il s’avère qu’elle
soit une femme soldat dans ces débuts, cette femme n’est autre que Meryl la
nièce de Roy Campbell le chef de notre mission. A la recherche de Baker : le
second personnage possédant le code nous tombons nez à nez avec Revolver
Ocelot un maitre qui manie parfaitement les revolvers. Snake arrive à se défaire
de Revolver et rentre en contact par CODEC avec Meryl qui nous guidera vers
le créateur du Metal Gear : Hal Emmerich. Snake trouve Hal Emmerich (en
ayant battu Raven au passage), ce dernier affirme qu’il existe un 2eme moyen
de désactiver le Metal Gear , en usant des cartes de désactivations. Cela
tombe bien Meryl en a dérobé une. Snake récupère cette carte auprès de
Meryl aux toilettes des femmes de l’entrepôt à ogives, mais tombe peu après
sur Psycho Mantis le 3eme boss du jeu puis sur Sniper Wolf le 4eme boss du jeu
à la sortie de la grotte. Wolf blesse de manière grave Meryl afin que Snake se
rende. Snake récupére le Sniper PSG1 afin de battre Wolf. Snake bat cette
dernière mais tombe dans une embuscade plus loin et est fait prisonnier dans
la prison, tout ça sans avoir revu Meryl. Snake s’échappe de sa cellule direction
la zone ou est entreposé le Metal Gear. Snake insere la carte-PAL Mais cela
était un piège ! Snake a en fait activé le Metal Gear pour Liquid Snake, qui
s’empresse de prendre son contrôle ! Il reste tout de même une solution :
2
Détruire le Metal Gear « à mains nus » à coup de lance-missiles. Le combat final
contre Liquid et le Metal Gear commence. À la fin de celui-ci, Snake fini
vainqueur, sauve Meryl et quitte la base avec la fierté d’avoir sauvé le monde
d’une catastrophe irréparable. Cet incident sera appelé par la suite
« L’incident de Shadow Moses ».
FIN
Lieux :
Le Quai : Snake arrive au début du jeu avec une tenue de plongée sur un quai
situé dans une caverne. Un ascenseur au nord du quai mène à l'héliport de la
base. Des rations sont présentes sur ce quai.
L’héliport : L’héliport comme son nom l’indique accueille des hélicoptères. Il est
improbable d’y trouver denombreux objets : (Grenades flash, Grenades
electrique, Ration, Pistolet). Au nord de cet héliport se trouve le hangar à tank.
Il existe plusieurs moyens d’y accéder…
Le Hangar à tank : Le Hangar à tank a été construit pour accueillir des tanks
M1 Abrams au rez-de-chaussée, des caméras sont présentent et divers items
aussi, comme les lunettes infrarouges. Le 1er sous-sol de ce hangar sert
d’infirmerie mais aussi de prison pour les soldats désobéissants et de salle de
torture. Au 2nd sous-sol se trouve l’armurerie on y trouve du C4 et un PSG1 ainsi
qu’autre otage: Baker qui est à la merci de Revolver Ocelot le premier boss du
jeu.
Le Canyon : Le Canyon est une zone enneigée, piégée avec des Claymores.
Dans ce canyon un ennemi de taille nous attend : Raven, c’est le 2nd boss du
jeu.
L’Entrepôt à ogives : L’entrepôt à ogives a quasiment la même structure que
le hangar à tank. En effet il contient 3 niveaux, le rez-de-chaussée, et deux
sous-sols. Le 1er sous-sol contient le vestiaire des soldats terroristes, la
bibliothèque (On y affronte Psycho Mantis, c’est le 3eme boss du jeu) et des
toilettes, on y trouve du NIKITA, les lunettes de vision nocturne et du diazépam.
Meryl est déguisé en soldat ennemi à cet étage. Le 2nd sous-sol est le
laboratoire de recherche, aucun soldat n’y est présent car les laboratoires sont
protégés par un corridor rempli de gaz toxique. Snake est censé y retrouver Hal
Emmerich pour connaitre toutes les options de destruction du Metal Gear.
La grotte + Passage souterrain : La grotte se trouve au Nord de la bibliothèque.
À l’est de celle-ci se trouve le passage sous terrain où nous y retrouvons Sniper
Wolf (c’est le 4eme boss du jeu). Des diazépam sont sur place.
Les tours de communication : La 1ere tour de communication est un bâtiment
ou il y a une clé à molette. La 2nde tour est muni d’un ascenceur en panne.
3
Champ de neige : Le champ de neige se trouve au plus bas niveau de la tour
de communication B
Le Haut-Fournau : Zone ou est créé les composants du Metal Gear,
La Chambre froide : Zone dans laquelle les composants sont refroidis après être
passé par le Haut Fourneau.
La cabine de contrôle + la zone de maintenance du Metal Gear : La cabine
de contrôle et la zone de maintenance du Metal gear sont deux partis d’une
seule et unique salle. La zone de contrôle est le lieu d’où l’on peut activer le
Metal Gear ou le désactiver. Cette dernière zone du jeu est l’endroit ou le jeu
se termine. On y retrouve Liquid Snake dans le Metal Gear.
Les Personnages :
Solid Snake : Solid Snake est le personnage principal du jeu, il incarne un soldat
d'élite expert en infiltration et en combat rapproché. Surentraîné, il est apte à
remplir, en solitaire, des missions ultrasecrètes et dangereuses en territoire
ennemi. Il faisait partie du l’unité FOXHOUND.
Liquid Snake : est le commandant de FOXHOUND. Une organisation peuplé de
soldats surentrainés, il menace de lancer une attaque nucléaire sur les états
unis. Il est le frère génétique de Snake (tous deux crée à partir des cellules de
Big Boss).
Roy Campbell (Colonel) : Roy Campbell est l'ex-commandant de l'unité
de forces spéciales américaine Fox Hound. Il est l’oncle Meryl Silverburgh.
lui donnant des informations sur les armes qu’il trouve.
Meryl Silverburgh : Meryl se forme durant toute son enfance dans les « arts »
militaires. Elle admirait l'unité de forces spéciales Fox Hound lorsque son
oncle, Roy Campbell, et Solid Snake en faisaient partie.
Hal Emmerich : Aussi connu sous le nom de code Otacon, il est à l'origine du
projet Metal Gear, mais lutte aux côtés de Snake pour arrêter sa création.
Baker : est le Président d’ArmsTech, une des plus puissantes industries
d'armement. Sa compagnie participe au projet Metal Gear REX afin de pallier
d'importantes pertes financières. Il est co-Directeur du département de
sécurité au côté de Donald Andersson.
4
Les Boss :
Revolver Ocelot : Ocelot est le bras droit de Liquid, il manie parfaitement les
revolvers (d’où son prénom).
Raven : Vulcan Raven est un shaman géant doté de grands pouvoirs spirituels,
mais il possède également une force physique exceptionnelle. Il fait partie de
l’unité FOXHOUND.
Sniper Wolf : est un tireur d'élite de génie. Sa patience est telle qu'elle peut
rester en position de tir pendant presque une semaine sans boire ni manger. Elle
fait partie de l’unité FOXHOUND.
Psycho Mantis : est un des plus grands spécialistes de psychokinésie et
de
télépathie
du
monde.
Il est capable de lire les pensées d'autrui avec grande facilité, ainsi que de
bouger des objets (même lourds) par la force de son mental. Il fait partie de
l’unité FOXHOUND.
Les items et description d’objets :
Ration : Quantité de nourriture permettant à Snake de reprendre de la vie.
Grenades Flash : Grenade qui lorsqu’elle explose produit une lumière
éblouissante permettant d’étourdir les soldats ennemis
Grenades Electrique : Grenade qui permet de mettre hors de service des
dispositifs électriques comme une caméra de surveillance par exemple ou
encore le MG.
Pistolet : Arme de poing, de capacité de 5 balles.
Lunettes infrarouges : Lunettes permettant de voir des rayons invisibles à l’œil
nu
C4 : Explosif, permettant de détruire des murs, des tanks, des portes…
PSG1 : Sniper d’élite, permettant les combats à distance.
Nikita : Lanceur de missile autoguidé
Diazépam : Pilule permettant d’arrêter les tremblements pouvant gêner la
visée au sniper.
Clé à molette : Outil de réparation
Bouteille d’eau : Empêche Solid Snake de se déshydrater
Carte-PAL: Carte permettant de désactiver à jamais le Metal Gear.
Metal Gear : Char bipède capable d'effectuer une frappe nucléaire. Il est
équipé de mitrailleuses, d'un laser et de lance-missiles mais son arme principale
est son canon à rampe (qui permet le lancement d’ogives nucléaires).
Claymore : Explosif qui se place au sol, qui se déclenche lorsqu’on marche
dessus.
CODEC : Le CODEC est une radio de communication qui utilise les nano
machines implantées dans certains soldats génétiquement modifiés pour
pouvoir communiquer.
5
Situations gagnantes et perdantes :
Le joueur perd s’il perd la totalité de sa vie. Le joueur gagne s’il arrive à
désactiver et/ou détruire le Metal Gear.
Mini jeux, boss :
Il y aura 4 combats dans ce jeu
Commentaires :
Ce jeu est basé sur des combats à choix et à la quête d’objets.
6
Réponses aux exercices :
Exercice 7.2.1
Scanner est une classe qui permet de lire ce que l’on a tapé au clavier
(System.in) ou ce que l’on a à l’écran (System.out).
nextLine() est une méthode qui permet de stocké la ligne tapé au clavier dans
une variable par exemple
Exercice 7.5
Voici la méthode printLocationInfo() qui permet d'afficher au
description du lieu dans lequel il se trouve ainsi que ses sorties,
joueur la
private void printLocationInfo()
{
System.out,println(« Vous êtes « + this.aCurrentRoom,getDescription()) ;
System.out.println(« Sorties : ») ;
if(this.aCurrentRoom.aNorthExit != null)
System.out.println("Nord");
if(this.aCurrentRoom.aSouthExit != null)
System.out.println("Sud");
if(this.aCurrentRoom.aEastExit != null)
System.out.println("Est");
if(this.aCurrentRoom.aWestExit != null)
System.out.println("Ouest");
}
La méthode pourra afficher un message du type :«Vous êtes au Canyon
Sorties : Nord Sud
Exercice 7.6
Cet exercice consiste à la rédaction des méthodes setExit() et getExit(). La
première est un modificateur qui permet d'associer à une room des sorties et
la deuxieme un acceseur qui permet de retourner celles-ci.
On souhaite par la création de ces méthodes réduire le couplage, on modifie
donc en premier la méthode setExits() qui prend 4 paramètres Room, pour
7
qu'elle puisse associer une sortie à une room si et seulement si celle-ci est
differente de null .
On remplace ainsi les instructions :
vNextRoom = pGo.getSecondWord();
if(vNextRoom.equals("Sud"))
{
if(this.aCurrentRoom.aNorthExit != null)
this.aCurrentRoom= this.aCurrentRoom.aNorthExit;
else
System.out.println(«Il n'y a pas de sortie ») ;
}
Par Room vNextRoom = this.aCurrentRoom.getExit(vDirection);
Exercice 7.7
Dans cet exercice on crée la procédure getExitString() dans la classe Room
qui permet de renvoyer les sorties sous forme de String , voici cette méthode :
public String getExitString()
{
System.out.println("Sorties : ");
if(this.getExit("nord") != null)
System.out.println("Nord");
if(this.getExit("sud") != null)
System.out.println("Sud");
if(this.getExit("est") !=null)
System.out.println("Est");
if(this.getExit("ouest") !=null)
System.out.println("Ouest");
return "";
}
L'implantation de cette méthode implique la modification de la procédure
printLocationInfo() écrite à l'exercice 7.5 qui affiche maintenant le lieu dans
lequel on se trouve et les sorties en appelant les méthodes getDescription() et
getExitString() sur l'attribut aCurrentRoom.
8
Exercice 7.8
Dans la classe Room :
On supprime les attributs aNorthExit, aSouthExit, aWestExit et aSouthExit.
Puis on ajoute une HashMap :
private HashMap<String,Room> aExits;
this.aExits=new HashMap<String,Room>();
Ensuite j'ai modifié la procédure setExits() qui s'écrit maintenant :
public void setExit(final String pDirection, final Room pNeighbor)
{
this.aExits.put(pDirection, pNeighbor);
}
Cette méthode permet d'ajouter des sorties à une Room.
On modifie également la procédure getExit() qui s'écrit maintenant
public Room getExit(final String pDirection)
{
return this.aExits.get(pDirection);
}
qui permet de retourner une room de la HashMap en fonction de la String qui
lui a était donné en paramètre
On modifie la procédure getExitString() :
public String getExitString()
{
StringBuilder vReturnString = new StringBuilder( "Sorties :");
for(String vS : aExits.keySet())
vReturnString.append( " " + vS);
return vReturnString.toString();
}
9
Edit : La méthode s'écrit dorénavant comme ceci à l'aide de StringBuilder
On ajoute dans Room la méthode setExit()
public void setExit(String pDirection, Room pNeighbor)
{
this.aExits.put(pDirection, pNeighbor);
}
Qui permet d'associer une sortie ou des sorties à une room.
On modifie en conséquence la méthode createRooms() dans GameEngine,
on ajoutera les sorties à chaque Room de manière plus concise.
Exemple : vCanyon.setExit(« Nord », vHangarRdc) ;
Exercice 7.9.
La méthode keySet crée un ensemble dans lequel sera stocké l’ensemble
des touches (keys) de la HashMap.
Dans notre exemple :
Set<String> vKeys =this,aExits,keySet();
keySet crée un ensemble de clé de type String de la HashMap aExits
Exercice 7.10
Voici la méthode getExitString() à écrire :
public String getExitString()
{
String vReturnString = "Sorties :"; (1)
Set<String> vKeys = aExits.keySet(); (2)
for(String aExits : vKeys) (3)
{return vReturnString += " " + aExits;} (3)
return vReturnString; (5)
}
(1) La méthode getExitString commence par stocké dans la variable
vReturnString la String « Sorties : ».
(2) Comme expliqué pour l’exercice 7.9, keySet crée un ensemble clés
(keys) de type String de la HashMap aExits dans la variable vKeys.
10
(3) La boucle for permet de parcourir l’ensemble des String stocké dans
l’ensemble vKeys.
Elle change la variable vReturnString décrit au point (1) pour qu’elle
soit décrite comme dans ces exemples : « Sorties : Nord, Sud» « Sorties :
Est, Sud»….
(4) Retourne la nouvelle String décrite ci-dessus
(5)
Edit la méthode s’écrit maintenant :
public String getExitString()
{
Set<String> vSetNomRoom = this.aExits.keySet();
String vReturnString = "Sorties : ";
String vReturnString2 = "Vous pouvez : explorer | Tapez pour cela 'va explorer'
ou cliquez sur le bouton 'Explorer' |";
String vReturnString3 = "Vous pouvez : revenir | Tapez pour cela 'revenir' ou
cliquez sur le bouton 'Revenir' |";
if(vSetNomRoom.isEmpty())
return vReturnString3;
for(String vSortie : vSetNomRoom)
{
if(!vSortie.equals("explorer"))
vReturnString += " " + vSortie;
}
if (vSetNomRoom.contains("explorer"))
return vReturnString + "\n" + "\n" + vReturnString2;
else return vReturnString;
}
HashMap : est une implémentation de l’interface Map. Elle permet d’associer
à une clé n’importe quelles valeurs dans un tableau.
Set : est une interface (une collection), elle permet de créer des ensembles
keySet : méthode renvoie un ensemble contenant les clés d’une collection de
type Map comme HashMap par exemple
11
Exercice 7.14
Dans cet exercice pour obtenir nous réunissions en fait tout le travail effectuer
pour afficher la localisation dans une méthode look() qui permettra d’afficher
le lieu et les sorties disponibles. L’affichage sera amené à évoluer au cours des
exercices je pense.La méthode look s’ecrit de cette manière dans la classe
Game :
private void look()
{
System.out.println(this.aCurrentRoom.getLongDescription());
}
Exercice 7.15
Cet exercice permet d’afficher un message lorsque nous tapons la commande
« eat » Voici la démarche que j’ai suivi:

J’ai écrit la méthode eat() :
private void eat()
{
this.aGui.println("Vous avez consommé une ration, votre avez
gagné d'1/4 de vie");
}



J’ai ajouté la commande « manger »/ « eat » dans la classe
CommandWord.
J’ai ajouté la méthode eat() dans la classe Game.
J’ai ajouté l’instruction suivante dans la méthode interpretCommand()
de la classe Game.
else if (commandWord.equals("manger"))
{
eat();
}
Edit : Ajout d’une vrai fonctionnalité pour la méthode manger()
public void manger(final Command pManger)
{
String vString = pManger.getSecondWord();
if (pManger.hasSecondWord())
{
this.aGui.println("Je ne comprends pas ce que vous dites");
return; }
else this.aGui.println(this.aPlayer.eat()); }
12
Exercice 7.16
J’ai implémenté les changements liés aux méthodes
showCommands
Edit : avec le StringBuilder showCommands devient :
showAll
et
public StringBuilder showCommands()
{
return this.aValidCommands.getCommandList();
}
Une boucle for each n’est pas une boucle for “traditionnelle”, elle permet par
exemple de parcourir les clés d’un tableau ou d’un ensemble.
Exercice 7.18.8
Ajout des boutons : Manger, Regarder, Nord, Sud, Est, Ouest.
 Dans la classe UserInterface :
Ajout d'attributs pour chaque bouton, sur le modèle :
private Jbutton aBoutonManger;



Dans la méthode createGUI() :
Création de chaque bouton (exemple):
aBoutonManger = new Jbutton("Manger");

Changement de type Layout (BorderLayout => GridLayout [plus
agréable])
Edit : Changement en GridLayout
Edit2 : Changement en GridBagLayout


Création de panel dans la fenêtre myFrame
Ajout de la classe UserInterface à la liste des auditeurs de chaque bouton,
(exemple) :
aBoutonManger.addActionListener(this);
 Dans la méthode actionPerformed() :
Utilisation de getSource pour l’interpretation d’un clique sur bouton (exemple) :
if (e.getSource() == aBoutonManger)
{this.aEngine.interpretCommand("manger");}
13
Explication des méthodes :
 ActionListener : est une interface qui définit les traitements en réponse
aux clics de souris.
 addActionListener() : est la méthode abstraite de l’interface
ActionListener, elle permet de préciser entre ses parenthèses l’objet qui
gérera (« écoutera ») les clics de souris.
 actionPerformed() : est une méthode qui reçoit les évènements de
l’interface ActionListener.
 ActionEvent()
:
est
un
objet
contenant
la
méthode
getActionCommand().
 getActionCommand() : est une méthode qui identifie le composant (ici
le bouton) qui a généré l'événement, et renvoie une chaine de
caractère (ici il renvoie donc le texte du bouton).
 getSource() : est une méthode qui renvoie l’objet qui a généré
l’événement. Cette méthode marche avec tous les évènements.
Exercice 7.20 – Item
Création de la classe Item
 Création de deux attributs aDescriptionItem et aPoidsItem initialisé dans le
constructeur
 Création des méthodes retournant chaque attributs : getDescriptionItem()
et getPoidsItem()
Edit : Ajout d’un attribut aNomItem et de la méthode getNom()
 Dans la classe Room



Je modifie la méthode getLongDescription() pour afficher la liste d’Items
présents dans la Room
Dans la classe GameEngine

J’ai ajouté à la méthode createRooms() des instructions permettant de
créer un Item sans pour l’instant l’ajouter à une Room. (Pour cela voir
Exercice 7.22.2)
Item vRation = new Item("Ration russe qui redonne 1/4 de vie à Snake",1);
Edit :
Item vRation = new Item("ration", "Ration russe qui redonne 1/4 de vie à
Snake",1);
14
Exercice 7.21

Dans la classe Room
 J’ai ajouté la méthode getItemLongString() qui permet d’afficher les
Items présents dans une Room (avec leur poids), cette méthode
s’écrit:
private String getItemLongString()
{
String vReturnString = "Objets : ";
Set<String> vKeysString = this.aItem.getKeyString();
for(String vKeyItem : vKeysString ) {
double
vPoids
this.aItem.getItemFromKeyString(vKeyItem).getPoidsItem();
vReturnString += " | " + vKeyItem + " ("+ vPoids + "kg) | ";
}
=
if (vKeysString.isEmpty())
{
return "Cette salle ne contient aucun objet !" ;
}
return vReturnString ;
}

J’ai modifié la méthode getLongDescription() qui affiche maintenant
la liste d’Item d’une Room en ajoutant à son instruction un appelle de
la méthode getItemLongString()
Exercice 7.22 – 7.22.2 Items et leur intégration


Dans la classe Room

J’ai ajouté une HashMap<String, Item> aItem que j’initialise dans le
constructeur de Room

J’ai ajouté une méthode setItem() permettant d’ajouter à une Room
un Item
Dans la classe GameEngine

On ajoute un Item à une Room comme ceci dans la méthode
createRooms() :
vQuai.setItem("ration", vRation);
15
Exercice 7.23

Dans la classe GameEngine



J’ai ajouté un attribut aPreviousRoom que j’initialise dans le
constructeur de GameEngine
J’ai ajouté l’instruction this.aPreviousRoom = this.aCurrentRoom dans
la méthode goRoom() qui s’exécute après chaque déplacement qui
permet de « mémoriser » la dernière Room visité
J’ai ajouté la méthode back() dans Player qui s’écrit :
public void back()
{
this.aCurrentRoom = this.aPreviousRoom;
this.aGui.println(this.aCurrentRoom.getLongDescription());
if (this.aCurrentRoom.getImageName()!= null)
this.aGui.showImage(this.aCurrentRoom.getImageName());
}
 Dans la méthode interpretCommand() :
J’ai ajouté l’instruction nécessaire au bon fonctionnement du mot de
commande « back »

Dans la classe CommandWords
 J’ai ajouté le mot « back » au tableau des commandes
Exercice 7.26

Dans la classe GameEngine



J’ai ajouté une Stack<Room> aLastRooms que j’initialise dans le
constructeur
Ajout de l’instruction this.aLastRooms.push(this.aPreviousRoom) ; dans
la méthode goRoom() après chaque déplacement
Je modifie la méthode back() qui s’écrit maintenant :
public void back()
{
if( !this.aLastRooms.empty())
this.aCurrentRoom = this.aPreviousRoom;
this.aGui.println(this.aCurrentRoom.getLongDescription());
if (this.aCurrentRoom.getImageName()!= null)
this.aGui.showImage(this.aCurrentRoom.getImageName());
}
16





Stack : est une implémentation de type List (une collection) qui veut dire
« pile » en anglais. C’est un empilement qui est géré par le « bas » , c’està-dire que l’ajout de valeur dans cette pile se fait de « bas en haut ».
push() : est une méthode de la classe Stack qui permet d’empiler un
certain type d’objets en haut de la pile d’objets
pop() : permet de récupérer le dernier objet de la pile (sans le laisser sur
la pile)
empty() : permet de « vider » la pile
Exercice 7.28.1
 Lecture de fichiers de texte :
La lecture de fichiers se fait par le biais d’un objet Scanner qui peut être
crée de deux manières :
Scanner
vScan
=
new
Scanner(
this.getClass().getClassLoader().getResourceAsStream("chemin_relatif/
nom_de_fichier.extension") );
Si on ouvre le fichier avec cette première méthode, c'est
une NullPointerException qui surviendra lorsque le fichier ne sera pas
trouvé.
ou
vScan = new Scanner(new File(nom_de_fichier.extension));
En ayant au préalable définie nom_de_fichier.extension qui n’est autre
que le second mot de la commande test.
Si on ouvre le fichier avec cette deuxième méthode, c'est une
FileNotFoundException qui surviendra lorsque le fichier ne sera pas
trouvé.





File : Classe du package java.io qui permet d’instancier des
fichiers.
Scanner : lit une instance contrairement au 7.2.1 (ici le contenu d’un
fichier) et non directement une chaine de caractère comme pour
System.in.
hasNextLine() : est une méthode qui retourne un booléen en
fonction de la présence ou non d’une ligne suivante dans le Scanner
nextLine() : est une méthode qui permet de lire une ligne dans le
Scanner
Traitement d'une exception : Une exception est traitée en 3
parties : dans un bloc try on placera l’instruction qui provoquera
l’exception, dans catch le type d’exception attendu suite à
l’instruction, et entre { } ce que l’on doit faire face à cette
exception.
17
Exercice 7.30/ 7.31 – Take Drop
Dans la classe Player

J’ai ajouté d'une HashMap<String, Item> aInventaire que j’initialise dans
le constructeur de Player.
J’ai ajouté un accesseur pour la HashMap aInventaire.
J’ai ajouté la méthode ramasser() :



public String ramasser(final String pNomItem)
{
Item vItemRamasse = this.aCurrentRoom.takeItem(pNomItem);
if(vItemRamasse == null)
{
return "Cet item n'est pas (ou plus) présent dans cette salle...";
}
this.aInventaire.ajouterObjets(pNomItem,vItemRamasse);
}
J’ai ajouté la méthode deposer() qui permet de retirer l’Item de
l’inventaire :

public String deposer(final String pNomItem)
{
Set<String> vSetItemNom = this.aInventaire.getKeyString();
Iterator<String> vIteratorItemNom = vSetItemNom.iterator();
if (this.aInventaire.estVide())
return "Votre inventaire est vide !";
while(vIteratorItemNom.hasNext())
{
String vNomItem = vIteratorItemNom.next();
Item
vItemDepose
this.aInventaire.getItemFromKeyString(vNomItem);
this.aCurrentRoom.setItem(vNomItem, vItemDepose);
if (pNomItem.equals(vNomItem))
{
vIteratorItemNom.remove();
return "Vous avez déposé un(e) " + pNomItem;
}
}
return "Cet objet n'est pas sur vous (ou n'existe pas) !";
}
18
=
Dans la classe CommandWords


J’ai ajouté au tableau de commandes les commandes "prendre" et
"jeter".
Dans la classe Room


J’ai ajouté la méthode takeItem() qui permet de retirer l’Item de la
Room :
public Item takeItem(final String pNomItem)
{
Set<String> vSetItemDescription = this.aItem.getKeyString();
Iterator<String> vIteratorItemDescription = vSetItemDescription.iterator();
while(vIteratorItemDescription.hasNext())
{
String vNomItem = vIteratorItemDescription.next();
Item vItemRamasse = this.aItem.getItemFromKeyString(vNomItem);
if (pNomItem.equals(vNomItem))
{
vIteratorItemDescription.remove();
return vItemRamasse;
}
}
return null;
Dans la classe GameEngine


J’ai ajouté la méthode take() :
private void take(final Command pTake)
{
String vItemRamasse = pTake.getSecondWord();
if (!pTake.hasSecondWord())
{
this.aGui.println("Que voulez vous ramasser ?");
return;
}
this.aGui.println(this.aPlayer.ramasser(vItemRamasse));
}
19

J’ai ajouté la méthode drop() :
private void drop(final Command pDrop)
{
String vItemDepose = pDrop.getSecondWord();
if (!pDrop.hasSecondWord())
{
this.aGui.println("Que voulez vous déposer ?");
return;
}
this.aGui.println(this.aPlayer.deposer(vItemDepose));
}
 Dans la méthode interpretCommand() :
J’ai ajouté des instructions nécessaires au bon fonctionnement des mots de
commande "prendre" et "jeter".
Exercice 7.41.1
enum : type de classe qui hérite non pas de la classe Object mais de la classe
Enum (java.lang.Enum) ne comprends que des constantes des méthodes
(ou non) et un constructeur
values() : est une méthode statique qui retourne la liste des déclarations de
l’énumération
toString() : a était redéfinie dans enum pour afficher la String associé à sa
CommandWord
constructeur : est en fait un setter
Exercice 7.42
J’ai implémenté le système de temps, lorsque l’on ramasse un objet. Ce
dernier est une bombe qui explose au bout de 5 déplacements (au bout de
5 unités de temps). J’ai pour cela utilisé un attribut aTime que je décrémente
à chaque déplacement et retour dans une salle du jeu. Lorsque aTime
atteint 0 la méthode gameOver() (implémenté dans les methodes de
déplacements) arrête le jeu.
(Reprise de cet exercice, même principe mais utilisation d’un attribut static
dans GameEngine le 01/12/2014)
20
Exercice 7.42.2
J’avais amélioré mon interface graphique au fil des exercices, j’ai donc eu
quelques modifications à faire, mais l’interface ne reste toujours pas finalisée.
Exercice 7.43
J’ai réalisé cet exercice en supprimant le setExit (donc la sortie de la room)
pour lequel on veut bloquer l’accès. Pour la commande « va » la trapdoor
fonctionne mais pas pour la commande « revenir ». Pour remédier à cela je
vide la Stack de Rooms à chaque fois que je rentre dans une salle B. Pour
cela j’ai crée une méthode isOneOfExit dans la classe Room qui verifie si la
salle B dans laquelle je suis, compte parmi ses sorties la salle A que je viens
de quitter pour rejoindre la salle B. Si la salle A ne fait pas parti des sorties de
la salle B alors la salle B est une TrapRoom, « revenir » dans la salle A n’est plus
possible.
La toute première TrapRoom du jeu est « l’heliport ».
Exercice 7.45 (optionnel)
J'ai effectué l’exercice 7.43 sans créer de classe Door. Cependant en
arrivant à l'exercice optionnel (7.45) je me suis rendu compte grâce aux
questions du forum qu'il était "obligé" d'intégrer une classe Door, ce que j'ai
fait. Voici la classe Door :
public class Door
{
private boolean aEstOuverte;
private Item aCarteDeNiveauPorte;
private Player aPlayer;
public Door()
{
this.aEstOuverte = true;
this.aCarteDeNiveauPorte = null;
}
public void setEstOuverte(final boolean pBoolean)
{
this.aEstOuverte = pBoolean ;
}
public boolean estOuverte()
{
return this.aEstOuverte;
}
21
public Item getCarteDeNiveauPorte()
{
return this.aCarteDeNiveauPorte;
}
public void setKey(final String pNomItem, final String pDescriptionItem , final
double pPoidsItem, final boolean pTransportabilite)
{
this.aCarteDeNiveauPorte = new Item(pNomItem, pDescriptionItem,
pPoidsItem, pTransportabilite);
}
}
J’ai modifié la méthode setExit() de la classe Room pour qu’elle crée en
interne et ajoute une Door à chaque sorties. J’ai donc crée au préalable une
HashMap de Doors. Dans laquelle j’ajoute sa Direction en String et la Door
crée en locale. Dans changerDeSalle() de Player j’ajoute des conditions de
changement de Room qui sont :
- Si la porte que je veux passer est fermée et que je possède la
clé qui lui est associé, je change de salle.
- Si la porte que je veux passer est fermée et que je ne possède
pas la clé qui permet de l’ouvrir, je ne peux pas avancer.
Exercice 7.46

Ajout de la classe TransporterRoom qui hérite de Room :
public class TransporterRoom extends Room
{
private RoomRandomizer aRoomRandomizer;
private HashMap<String, Room> aRandomRooms;
public TransporterRoom(final String pNom, final String pDescription, final
String pImage, final HashMap<String, Room> pRandomRooms)
{
super(pNom, pDescription,pImage);
this.aRandomRooms = pRandomRooms;
this.aRoomRandomizer = new RoomRandomizer();
}
@Override public Room getExit(final String pDirection)
{
22
if(GameEngine.getMemorizeString()
==
null
||
GameEngine.getMemorizeString() == "")
return
this.aRoomRandomizer.getRandomRoom(this.aRandomRooms);
return this.aRandomRooms.get(GameEngine.getMemorizeString());
}
}
Ajout de la classe RoomRandomizer :

public class RoomRandomizer
{
public RoomRandomizer()
{
}
public
Room
getRandomRoom(final
HashMap<String,
Room>
pHashRooms)
{
Random vRandom = new Random();
List<String>
vListeNomRoom
=
new
ArrayList<String>(pHashRooms.keySet());
String
vNomRoomRandom
=
vListeNomRoom.get(vRandom.nextInt(vListeNomRoom.size()));
Room vFindRandomRoom = pHashRooms.get(vNomRoomRandom);
return vFindRandomRoom;
}
}// RoomRandomizer
Dans la classe CommandWords :


On ajoute dans createRooms() :
TransporterRoom vTransporterRoom = new TransporterRoom("salleteleportation",
"dans
la
salle
magique
de
teleportation",
"Images/TransporterRoom.jpg", vRandomRooms );
vGrotte.setExit("Est", vTransporterRoom);
vTransporterRoom.setExit("Ouest", vTransporterRoom.getExit("Ouest"));
23
Ces instructions permettent d’associer
TransporterRoom une room aléatoire.
à
la
sortie
Ouest
de
la
Exercice 7.46.1 – ALEA
Dans la classe GameEngine :








J’ai ajouté un attribut static de type String aMemorizeString (initialisé à « » )
J’ai ajouté un attribut static de type boolean aModeTest (initilaisé à false)
J’ai ajouté un accesseur et un modificateur pour l’attribut aMemorizeString
J’ai ajouté un accesseur et un modificateur pour l’attribut aModeTest
J’ai
ajouté
un
attribut
static
de
type
ArrayList<String>
aRandomRoomStrings;
Ajout de l’instruction suivante dans createRooms() qui permet d’’ajouter
les rooms dans lequel on peut se téléporter dans la HashMAp de
vTransporterRoom
La méthode test commence désormais par this.aModeTest =ture et
this.aModeTest =false
RoomList vRandomRooms = new RoomList();
vRandomRooms.put(vHeliport.getNom(), vHeliport);
vRandomRooms.put(vHangarRdc.getNom(), vHangarRdc);
vRandomRooms.put(vHangarS1.getNom(), vHangarS1);
vRandomRooms.put(vHangarS2.getNom(), vHangarS2);
vRandomRooms.put(vCanyon.getNom(), vCanyon);
vRandomRooms.put(vGrotte.getNom(), vGrotte);
vRandomRooms.put(vEntrepotRdc.getNom(), vEntrepotRdc);
vRandomRooms.put(vEntrepotS1.getNom(), vEntrepotS1);
vRandomRooms.put(vEntrepotS1Commandant.getNom(),
vEntrepotS1Commandant);
vRandomRooms.put(vEntrepotS2.getNom(), vEntrepotS2)
TransporterRoom vTransporterRoom = new TransporterRoom("salleteleportation",
"dans
la
salle
magique
de
teleportation",
"Images/TransporterRoom.jpg", vRandomRooms );

Dans la classe TransporterRoom :

Je modifie la méthode getRandomRoom() pour qu’elle retourne
une Room aléatoire seulement si aMemorizeString est vide ou vaut
null.
24
public Room getRandomRoom(final HashMap<String, Room> pHashRooms)
{
Random vRandom = new Random();
List<String>
vListeNomRoom
=
new
ArrayList<String>(pHashRooms.keySet());
String
vNomRoomRandom
=
vListeNomRoom.get(vRandom.nextInt(vListeNomRoom.size()));
Room vFindRandomRoom = pHashRooms.get(vNomRoomRandom);
return vFindRandomRoom;
}
Exercice 7.47
Dans la classe CommandWords :



J’ai ajouté une HashMap de type <String , CommandWord >
aValidCommands
J’ai ajouté une HashMap de type <CommandWord, Command>
aValidCommands2
Avec ce stratagème la String la récupération des commandes est moins
brutales, son cheminement est String – CommandWord – Command et non
String- Command

J’ai modifié le constructeur CommandWords de manière à remplir les 2
HashMap :
for(CommandWord vCommand : CommandWord.values())
{
if(vCommand != null)
{
this.aValidCommands.put(vCommand.toString(), vCommand);
}
}
this.aValidCommands2 = new HashMap<CommandWord, Command>();
this.aValidCommands2.put(CommandWord.VA, new GoCommand());
this.aValidCommands2.put(CommandWord.QUITTER,
new
QuitCommand());
this.aValidCommands2.put(CommandWord.AIDE,
new
HelpCommand());
this.aValidCommands2.put(CommandWord.REGARDER,
new
LookCommand());
this.aValidCommands2.put(CommandWord.MANGER,
new
EatCommand());
25
this.aValidCommands2.put(CommandWord.REVENIR,
BackCommand());
this.aValidCommands2.put(CommandWord.TESTER,
TestCommand());
this.aValidCommands2.put(CommandWord.PRENDRE,
TakeCommand());
this.aValidCommands2.put(CommandWord.JETER,
DropCommand());
this.aValidCommands2.put(CommandWord.INVENTAIRE,
InventoryCommand());
this.aValidCommands2.put(CommandWord.UNKNOWN, null);
this.aValidCommands2.put(CommandWord.CHARGER,
ChargeCommand());
this.aValidCommands2.put(CommandWord.UTILISER,
UseCommand());
this.aValidCommands2.put(CommandWord.ALEA,
AleaCommand());
this.aValidCommands2.put(CommandWord.PARLER,
TalkCommand());
this.aValidCommands2.put(CommandWord.CHOIX,
ChoiceCommand());
this.aValidCommands2.put(CommandWord.COMBATTRE,
FightCommand());
this.aValidCommands2.put(CommandWord.CODEC,
CodecCommand());
this.aValidCommands2.put(CommandWord.ALEACHOICE,
AleaChoiceCommand());

Dans la classe Parser :

new
new
new
new
new
new
new
new
new
new
new
new
J’ai ajouté de la méthode get () qui permet d’obtenir une Command à
partir d’une String qui s’écrit :
public Command get(final String pStringCommandWord)
{
CommandWord
vCommandWord
this.aValidCommands.get(pStringCommandWord);
return this.aValidCommands2.get(vCommandWord);
}

new
Modification de la méthode getCommand() qui s’écrit maintenant :
public Command getCommand(final String pInputLine)
{
String vWord1;
String vWord2;
26
=
StringTokenizer vTokenizer = new StringTokenizer(pInputLine);
if (vTokenizer.hasMoreTokens())
vWord1 = vTokenizer.nextToken(); // recupere le premier mot
else
vWord1 = null;
if (vTokenizer.hasMoreTokens())
vWord2 = vTokenizer.nextToken(); // recupere le deuxieme mot
else
vWord2 = null;
Command vCommand= this.aValidCommands.get(vWord1);
if(this.aValidCommands.isCommand(vWord1) && vCommand != null)
{
vCommand.setSecondWord(vWord2);
}
return vCommand;
}
Dans la classe Command :



La classe Command devient abstraite
J’ai ajouté 3 méthodes en lien avec l’attribut aSecondWord :
public String getSecondWord()
{
return this.aSecondWord;
}
public boolean hasSecondWord()
{
return this.aSecondWord != null;
}
public void setSecondWord(final String pSecondWord)
{
this.aSecondWord = pSecondWord;
}

J’ai la méthode abstraite execute() qui sera propre à chaque sous classe
c’est la mise en place du polymorphisme pour les commandes, cette
méthode s’écrit :
public abstract void execute(final Player pPlayer, final UserInterface pGui);
27
Les paramètres pPlayer et pGui suffisent à gérer les instructions qui étaient
présentent dans GameEngine. J’aurai pu faire d’ execute() une méthode qui
retourne une String que le GameEngine affichera mais je préfère rester ainsi
pour des raisons graphiques (voir IHM Graphique).
Dans la classe GameEngine:


J’ai modifié la méthode interpretCommand pour que cette instauration
du polymorphisme des commandes soit fonctionnelle :
public void interpretCommand(final String pCommandString)
{
Command
vCommand
aParser.getCommand(pCommandString);
if(vCommand == null)
{
aGui.println("Je ne comprends pas ce que vous dites");
return;
}
vCommand.execute(aPlayer, aGui);
}
Exercice 7.47.1

Création de paquetages sous le les noms pkg_******
Le pkg_GameController contient les classes :
GameEngine / UserInterface / Player / Parser /
Le pkg_Commands contient les classes :
Command / CommandWords / CommandWord / GoCommand /
BackCommand / EatCommand /…
Le pkg_Items contient les classes :
Item / ItemList / Beamer /
Le pkg_Room contient les classes :
Room / RoomList / RoomRandomizer / TransporterRoom / Door
Exercice 7.48
28
=


Création du paquetage sous le les noms pkg_Characters
Création de la classe Character qui est abstraite :
Ce choix s’explique par le fait qu’aucun personnage de mon jeu ne
ressemble à un autre. Un personnage pourra se battre, l’autre me
donner des objets et se battre parfois juste ce battre… Un Character
de base pourra avoir un inventaire , un nom, une room, une image.
La classe Character s’écrit :
public abstract class Character
{
private String aName;
private Room aCurrentRoom;
private String aImage;
private HashMap<Integer,String> aTalkTexts;
private ItemList aInventaire;
/**
* Constructeur
*/
public Character(final String pName, final Room pRoom, final String
pImage)
{
this.aCurrentRoom = pRoom;
this.aName = pName;
this.aImage = pImage;
this.aTalkTexts = new HashMap<Integer,String>();
this.aInventaire = new ItemList();
}
public String getName()
{
return this.aName;
}
public String getImage()
{
return this.aImage;
}
public Room getCurrentRoom()
{
return this.aCurrentRoom;
}
public void setCurrentRoom(final Room pRoom)
{
29
this.aCurrentRoom = pRoom;
}
public void addTalkText(final Integer pInt, final String pTalkText)
{
this.aTalkTexts.put(pInt, pTalkText);
}
public String getTalkText(final Integer pInt)
{
return this.aTalkTexts.get(pInt);
}
public ItemList getInventaire()
{
return this.aInventaire;
}
public void addItem(final String pNameItem, final Item pItem)
{
this.aInventaire.put(pNameItem, pItem);
}
public void give(final Player pPlayer, final Item pItem, final
UserInterface pGui)
{
this.aInventaire.remove(pItem.getNomItem());
pPlayer.getInventaire().put(pItem.getNomItem(), pItem);
pGui.println("\n" + "/ " + this.getName() + " vous a donné une/un
" + pItem.getNomItem() + " /");
}
public abstract void fillInventory();
public abstract void fillTalkTextList();
public abstract void talk(final Player pPlayer, final UserInterface
pGui);
Cette classe a pour sous classe :
Baker / Meryl / LiquidSnake / SoldatJohnny

Je crée les classes associées aux personnages :
Pour cela j’ai d’abord crée une sous-classe de Character :
CharacterEnemy, qui définit un personnage ennemi de base, cette
classe s’écrit :
public abstract class CharacterEnemy extends Character
30
{
private boolean aIsBeaten;
private static int aHealth;
private HashMap<Integer,String> aAttacks;
static
{
aHealth = 600;
}
/**
* Constructeur CharacterEnemy
*/
public CharacterEnemy(final String pName, final Room pRoom,
final String pImage)
{
super(pName, pRoom, pImage);
this.aIsBeaten = false;
this.aAttacks = new HashMap<Integer,String>();
}
public void clearAllAttacks()
{
this.aAttacks.clear();
}
public abstract void fillAttackList();
public abstract void fight(final String pChoixABC, final Player
pPlayer, final UserInterface pGui);
public abstract void displayFightChoice(final Player pPlayer, final
UserInterface pGui);
public void beaten(final boolean pBeaten)
{
this.aIsBeaten = true;
}
public boolean isBeaten()
{
return aIsBeaten;
}
public static int getHealth()
{
return aHealth;
31
}
public void hurt(final int pInt)
{
aHealth += - pInt;
if(aHealth<=0)
this.setBossHealth(0);
UserInterface.refreshBossBarLife(this.getName());
return;
}
public static void setBossHealth(final int pInt)
{
aHealth = pInt;
}
public void addAttack(final int pInt, final String pAttack)
{
this.aAttacks.put(pInt, pAttack);
}
public String getAttack(final int pInt)
{
return this.aAttacks.get(pInt);
}
public HashMap<Integer,String> getHashAttack()
{
return this.aAttacks;
}
Cette classe a pour sous classes :
PsychoMantis / MetalGear / VulcanRaven / Ocelot / SniperWolf /

J’ai ajouté une classe CharacterList qui s’ecrit:
public class CharacterList
{
private HashMap<String, Character> aCharacterList;
public CharacterList()
{
this.aCharacterList = new HashMap<String, Character>();
}
/**
* Accesseur de la HashMap<String,Character>
32
*/
public HashMap<String, Character> getHashMapCharacter()
{
return this.aCharacterList;
}
/**
* Méthode qui permet d'ajouter des Characters dans la HashMap
*/
public void put(final String pCharacterName, final Character
pCharacter)
{
this.aCharacterList.put(pCharacterName, pCharacter);
}
/**
* Méthode qui permet de supprimer des Characters dans la
HashMap
*/
public void remove(final String pCharacterNAme)
{
this.aCharacterList.remove(pCharacterNAme);
}
/**
* Méthode qui permet crée une liste à partir des clés de la
HashMap
*/
public Set<String> getKeyString()
{
return this.aCharacterList.keySet();
}
/**
* Méthode qui permet d'obtenir un Character de la HashMap en
fonction de son som en String
*/
public Character getCharacter(final String pCharacterNAme)
{
return this.aCharacterList.get(pCharacterNAme);
}
/**
* Méthode qui retourne un boolean en fonction de la précense ou
non d'un Character dans la HashMap
*/
33
public boolean containsValue(final Character pCharacter)
{
return this.aCharacterList.containsValue(pCharacter);
}
/**
* Méthode qui retourne un boolean en fonction de la précense ou
non d'un nom d'un Character dans la HashMap
*/
public boolean containsKey(final String pCharacterNAme)
{
return this.aCharacterList.containsKey(pCharacterNAme);
}
/**
* Méthode qui verifie si la HashMap est vide
*/
public boolean isEmpty()
{
return this.aCharacterList.isEmpty();
}
/**
* Méthode qui retoune la taille de la HashMap
*/
public int size()
{
return this.aCharacterList.size();
}
}
Dans la classe Room:


J’ai ajouté un attribut aCharacters de type CharacterList et une
méthode setCharacter() qui permet de mettre un Character, une
méthode getCharacterList() qui retourne aCharacters , une méthode
getCharacterListString() qui permet d’afficher les Characters présents
dans la salle. Ces méthodes s’écrivent :
public void setCharacter(final String pNomCharacter,
pkg_Characters.Character pCharacter)
{
this.aCharacters.put(pNomCharacter, pCharacter);
}
public CharacterList getCharacterList()
{
34
final
return this.aCharacters;
}
public String getCharacterListString()
{
String vReturnString = "\n" + "Info personnages présents en ce lieu
:";
Set<String> vKeysString = this.aCharacters.getKeyString();
for(String vKeyCharacter : vKeysString ) {
vReturnString += " / " + vKeyCharacter + " / ";
}
if (vKeysString.isEmpty())
{
return "\n" + "Info : Personne ne se trouve ici" ;
}
return vReturnString ;
}
Dans la classe GameEngine:



J’ajoute l’attribut CharacterList aAllCharacters qui contiendra tous les
characters du jeu
Je crée la méthode createCharacters() qui crée les Characters et les
ajoute dans aAllCharacters et la méthode putRoomCharacter () qui
ajoute chaque Character dans sa room initiale :
private void createCharacter()
{
// Creation de soldats
pkg_Characters.Character vSoldat = new SoldatJohnny("Soldat",
aAllRooms.getRoom("prison"), "Images/Soldat1.jpg");
//Création de personnages
pkg_Characters.Character vOtacon = new Otacon("Otacon",
aAllRooms.getRoom("laboratoire"), "Images/Otacon.jpg");
pkg_Characters.Character
vMeryl
=
new
Meryl("Meryl",
aAllRooms.getRoom("toilettes-femmes"), "Images/Meryl.jpg");
pkg_Characters.Character
vBaker
=
new
Baker("Baker",
aAllRooms.getRoom("zone-abandonnee"), "Images/Baker.jpg");
35
//Création de boss
pkg_Characters.Character vRaven = new VulcanRaven("Raven",
aAllRooms.getRoom("canyon"), "Images/Raven.jpg");
pkg_Characters.Character
vOcelot
=
new
Ocelot("Ocelot",
aAllRooms.getRoom("zone-abandonnee"), "Images/Ocelot.jpg");
pkg_Characters.Character
vWolf
=
new
SniperWolf("Wolf",
aAllRooms.getRoom("passage-souterrain"), "Images/Wolf.jpg");
pkg_Characters.Character vMantis = new PsychoMantis("Mantis",
aAllRooms.getRoom("cabine-commandant"), "Images/Mantis.jpg");
pkg_Characters.Character vMetalGear = new MetalGear("Metal-GearRex", aAllRooms.getRoom("maintenance-MG"), "Images/MetalGear.jpg");
pkg_Characters.Character vLiquid = new LiquidSnake("Liquid",
aAllRooms.getRoom("maintenance-MG"), "Images/Liquid.jpg");
//Creation de personnages pouvant changer de salle
aAllCharacters.put(vSoldat.getName(), vSoldat);
aAllCharacters.put(vOtacon.getName(), vOtacon);
aAllCharacters.put(vMeryl.getName(), vMeryl);
aAllCharacters.put(vRaven.getName(), vRaven);
aAllCharacters.put(vOcelot.getName(), vOcelot);
aAllCharacters.put(vBaker.getName(), vBaker);
aAllCharacters.put(vWolf.getName(), vWolf);
aAllCharacters.put(vMantis.getName(), vMantis);
aAllCharacters.put(vMetalGear.getName(), vMetalGear);
aAllCharacters.put(vLiquid.getName(), vLiquid);
}
public static void putRoomCharacter()
{
for(String vCharacterName : aAllCharacters.getKeyString())
{
pkg_Characters.Character
vCharacter
aAllCharacters.getCharacter(vCharacterName);
Room vCharacterRoom = vCharacter.getCurrentRoom();
vCharacterRoom.setCharacter(vCharacterName, vCharacter);
}
}
=
putCharacterRoom() est appelé dans createRooms() et createCharacter()
dans le constructeur de GameEngine.
Exercice 7.49
36

Pour moi un MovingCharacter est une classe abstraite qui a pour attribut
une RoomList, une méthode de déplacement move(), une méthode
abstraite de remplissage de la RoomList addRoom() et une méthode
qui retourne cette RoomList getRoomList().
public abstract class MovingCharacter extends Character
{
private RoomList aRoomList;
/**
* Constructeur MovingCharacter
*/
public MovingCharacter(final String pName, final Room pRoom, final String
pImage)
{
super(pName, pRoom, pImage);
this.aRoomList = new RoomList();
}
public void move(final Room pRoom)
{
this.setCurrentRoom(pRoom);
Player.getCurrentRoom().getCharacterList().remove(this.getName());
GameEngine.println("\n"+ this.getName() + " a quitté la salle et se trouve
maintenant " + pRoom.getDescription());
}
public RoomList getRoomList()
{
return this.aRoomList;
}
public void addRoom(final String pString, final Room pRoom)
{
this.aRoomList.put(pString, pRoom);
}
public abstract void fillRoomList();
}
Cette classe a deux Sous classe :
Meryl et Otacon. Otacon se déplace en fonction de l’avancé du jeu. Et Meryl
nous suit pendant un moment, avant de se retrouver dans la dernière salle du
jeu.
Exercice 7.49.1
L’héritage a était ajouté spontanément lors des exercices précédents
37
Exercice 7.49.2
Le jeu est terminé. J’ai créé au passage de nombreuses Commandes, crée
un système de dialogue, crée des combats…. Cette partie étant très longue
à écrire. Je vous propose de jeter directement un œil au fichier .jar du jeu
(quasiment tout est commenter) ainsi qu’aux javadocs.
Exercice 7.50
La méthode de la classe Math qui calcule le maximum entre 2 entiers a pour
signature :
public static int max(int a,int b)
Exercice 7.51
Ces méthodes sont statiques car elles sont propres à la classe Math. Elles évitent
ainsi de créer un objet de type Math est d’appelée les méthodes dessus.
Exercice 7.53
Ajout de la méthode main dans la classe Game :
public static void main(final String[] pArgs)
{
new Game();
}
Exercice 7.54
Le jeu se lance et se compile sur Windows et Linux grâce au terminal,
Exercice 7.58
Le jeu se lance sans souci
Exercice 7.58.3
L'IHM graphique est opérationnel
Exercice 7.60.4
Javadoc générées
38
Exercice 7.63
Les trois scénarios de test sont opérationnel un seul fichier s’occupe des trois
scénarios c’est le fichier finir.txt
Exercice 7.63.1
Aucun Warning
Exercice 7.63.3
Tous les éléments ont été incorporés
Exercice 7.63.4
Javadoc à jour
Declaration Anti-Plagiat

J'ai recopié ce bout de code qui permet de faire trembler la fenêtre :
public class FrameUtils {
private final static int VIBRATION_LENGTH = 10;
private final static int VIBRATION_VELOCITY = 3;
private FrameUtils() { }
public static void vibrate(Frame frame) {
try {
final int originalX = frame.getLocationOnScreen().x;
final int originalY = frame.getLocationOnScreen().y;
for(int i = 0; i < VIBRATION_LENGTH; i++) {
Thread.sleep(10);
frame.setLocation(originalX, originalY + VIBRATION_VELOCITY);
Thread.sleep(10);
frame.setLocation(originalX, originalY - VIBRATION_VELOCITY);
Thread.sleep(10);
frame.setLocation(originalX + VIBRATION_VELOCITY, originalY);
Thread.sleep(10);
frame.setLocation(originalX, originalY);
}
}
catch (Exception err) {
err.printStackTrace();
}
}
}
Mode d'emploi
39
Pour lancer le jeu ouvrez un terminal, placez-vous dans le dossier qui
contient LDTMG.jar et tapez :

java –jar LDTMG.jar sous Linux et Windows
Toutes les commandes peuvent être exécutées grâce aux boutons sauf «
charger » pour le Téléporteur
Le seuls objets que vous pouvez « utiliser » sont la bouteille-eau , clémolette et c4.


Conseil

Utiliser le codec autant de fois possible et ramasser un maximum
d’Items c’est utile. N’oubliez pas la grande-ration
40