Licence Science-Technologie-Santé - mention Informatique - 3e année module Programmation Objet Avancée
Examen – 08/01/2008 – 2h
Les polycopiés de cours et notes de TD et de TP sont autorisés première partie (cours de F. Fürst)
Problème A
Un développeur a créé un jeu vidéo auquel on peut jouer avec une « manette de la joie » (joystick). Vous êtes chargé de faire évoluer le jeu pour qu'il puisse aussi se jouer avec les touches du clavier, mais sans modifier le code existant, pour faciliter la mise à jour. Voici ci-dessous des extraits de code source pour les classes principales du jeu :
public interface Manette { /* interface pour tous les types de manettes */
public boolean isLeft();
public boolean isRight();
public boolean isPush();
}
public class Clavier {
public enum Key { SPACEBAR, ARROW_LEFT, ARROW_RIGHT };
public Clavier() { /* constructeur */ }
public Key keyPressed() { /* retourne le type de la touche */ } }
public class Jeu {
private Manette manette;
public Jeu(Manette manette) { this.manette = manette; } public void mainLoop() { /* boucle principale du jeu */
if(manette.isLeft() { /* déplacement à gauche */ }
else if(manette.isRight() { /* déplacement à droite */ } else if(manette.isPush()) { /* appui sur le bouton *}
} }
public class JeuMain {
public static void main(String[] args) {
// SuperStick est une classe qui implémente Manette Manette manette = new SuperStick();
Jeu jeu = new Jeu(manette);
jeu.mainLoop();
} }
Question 1 :
En utilisant un pattern vu en cours, et sans modifier le code existant (sauf la classe JeuMain), écrire une classe supplémentaire pour répondre au problème.
Question 2 :
Réécrire la classe JeuMain pour que le jeu se joue au clavier.
Correction
Question 1 : on veut utiliser une instance de Clavier dans la classe Jeu, mais Jeu utilise une instance de l'interface Manette. Le pattern à utiliser ici est donc le pattern Adapter, qui permet d'adapter une classe à une interface. La classe supplémentaire ClavierAdapter implémente l'interface Manette et permet de manipuler un Clavier. Première solution : le pattern Adapter d'objet, ClavierAdapter accède à une instance de Clavier par composition.
public class ClavierAdapter implements Manette{
private Clavier c;
public ClavierAdapter(){c = new Clavier();}
public boolean isLeft(){
return c.keyPressed()== Clavier.Key.ARROW_LEFT;
}
public boolean isRight(){
return c.keyPressed()== Clavier.Key.ARROW_RIGHT;
}
public boolean isPush(){
return c.keyPressed()== Clavier.Key.SPACEBAR;
} }
Deuxième solution : le pattern Adapter de classe, ClavierAdapter accède à une instance de Clavier par héritage.
public class ClavierAdapter extends Clavier implements Manette{
public boolean isLeft(){
return this.keyPressed() == Clavier.Key.ARROW_LEFT;
}
public boolean isRight(){
return this.keyPressed() == Clavier.Key.ARROW_RIGHT;
}
public boolean isPush(){
return this.keyPressed() == Clavier.Key.SPACEBAR;
} }
Question 2 : dans la méthode main, le Jeu sera lancé sur un ClavierAdapter et non sur un SuperStick.
public static void main(String[] args) {
Manette manette = new ClavierAdapter();
Jeu jeu = new Jeu(manette);
jeu.mainLoop();
}