From f9e1580da50a664328605b9078428b949fb067bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Mon, 10 Nov 2025 14:54:51 +0100 Subject: [PATCH] feat: enlever gameview observer et ajout dans l'observer de base --- src/Car.java | 5 +--- src/Dashboard.java | 22 ++++++-------- src/Game.java | 74 +++++++++++++++++++++++++++------------------- src/GameView.java | 71 +++++++++++++------------------------------- src/Main.java | 6 ++-- src/Rankboard.java | 16 +++++----- src/Track.java | 15 ++++++---- 7 files changed, 95 insertions(+), 114 deletions(-) diff --git a/src/Car.java b/src/Car.java index 2d7c191..3ecce44 100644 --- a/src/Car.java +++ b/src/Car.java @@ -177,12 +177,9 @@ public class Car } /** - * Représentation textuelle de la voiture (son nom) - * * @return nom de la voiture */ - @Override - public String toString() + public String getName() { return this.name; } diff --git a/src/Dashboard.java b/src/Dashboard.java index d23b57c..8fdb112 100644 --- a/src/Dashboard.java +++ b/src/Dashboard.java @@ -1,7 +1,6 @@ import java.awt.BorderLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.function.Supplier; import javax.swing.JButton; import javax.swing.JLabel; @@ -27,23 +26,19 @@ public class Dashboard extends GameView /** Voiture associée à ce dashboard */ private final Car car; - /** État de pause global partagé par tous les dashboards */ - private static boolean isPaused = false; - /** * Construit un dashboard pour une voiture donnée. * * @param car la voiture suivie par ce dashboard * @param title titre du dashboard - * @param fn fonction appelée pour activer/désactiver la pause * @param width largeur de la fenêtre * @param height hauteur de la fenêtre * @param x position horizontale de la fenêtre * @param y position verticale de la fenêtre */ - public Dashboard(Car car, String title, Supplier fn, int width, int height, int x, int y) + public Dashboard(Game game, Car car, String title, int width, int height, int x, int y) { - super("Dashboard: " + title, width, height, x, y); + super(game, "Dashboard: " + title, width, height, x, y); this.car = car; this.label = new JLabel(); @@ -51,7 +46,7 @@ public class Dashboard extends GameView frame.setBackground(car.getColor()); - init(fn); + init(); this.add(label, BorderLayout.CENTER); this.add(button, BorderLayout.SOUTH); @@ -62,7 +57,7 @@ public class Dashboard extends GameView */ private void updateButtonText() { - button.setText(isPaused ? "En Pause" : "En Cours"); + button.setText(game.getPause() ? "En Pause" : "En Cours"); } /** @@ -70,7 +65,7 @@ public class Dashboard extends GameView * * @param fn fonction appelée lorsque l'on clique sur le bouton pour inverser l'état de pause */ - private void init(Supplier fn) + private void init() { updateButtonText(); @@ -79,9 +74,9 @@ public class Dashboard extends GameView @Override public void mouseClicked(MouseEvent e) { - isPaused = fn.get(); + game.togglePause(); updateButtonText(); - GameView.update(); + game.notifyObservers(); } }; @@ -94,7 +89,7 @@ public class Dashboard extends GameView * Cette méthode est appelée périodiquement par le moteur de jeu. */ @Override - public void run() + public boolean apply() { label.setText( "
Carburant Restant: " + car.getFuel() @@ -103,5 +98,6 @@ public class Dashboard extends GameView ); updateButtonText(); + return true; } } \ No newline at end of file diff --git a/src/Game.java b/src/Game.java index 6584b9e..3833f3c 100644 --- a/src/Game.java +++ b/src/Game.java @@ -1,5 +1,4 @@ import java.awt.Color; -import java.awt.GraphicsEnvironment; import java.util.ArrayList; /** @@ -22,11 +21,14 @@ public class Game public final String name; /** Couleur de la voiture */ public final Color color; + /** Visuel de la voiture */ + private final boolean visual; - public CarInfo(String name, Color color) + public CarInfo(String name, Color color, boolean visual) { this.name = name; this.color = color; + this.visual = visual; } } @@ -43,7 +45,7 @@ public class Game private ArrayList cars = new ArrayList<>(); /** État initial du jeu */ private State state = new State(); - /** Temps entre chaque "step" du jeu (en millisecondes) */ + /** Temps entre chaque step du jeu */ private int time = 1000; /** Carte sur laquelle se déroule le jeu */ private Map map = null; @@ -115,18 +117,6 @@ public class Game /** Indique si le jeu est en pause */ private boolean isPaused = false; - /** - * Bloc statique exécuté au chargement de la classe pour vérifier - * si le programme dispose d'un environnement graphique. - */ - static { - if (GraphicsEnvironment.isHeadless()) - { - System.err.println("Aucun serveur d'affichage trouvé"); - System.exit(1); - } - } - /** * Constructeur principal. * @@ -157,8 +147,8 @@ public class Game private Game init(ArrayList carInfos) { // Création des vues principales - new Track(map, cars, "Piste Formule 1", 1000, 500, 1, 1); - new Rankboard("Score", cars, 200, 200, 0, 510); + new Track(this, "Piste Formule 1", 1000, 500, 1, 1); + new Rankboard(this, "Score", 200, 200, 0, 510); final int loop = map.getPathSize(); @@ -167,12 +157,12 @@ public class Game for (CarInfo ci : carInfos) { Car car = new Car(ci.name, ci.color, loop, state); - new Dashboard(car, car.toString(), this::togglePause, 300, 200, 1000, 200*i); + String name = car.getName(); + new Dashboard(this, car, name, 300, 200, 1000, 200*i); cars.add(car); i++; } - GameView.update(); return this; } @@ -230,10 +220,23 @@ public class Game { if (isPaused) notifyAll(); isPaused = !isPaused; - GameView.update(); return isPaused; } + public void notifyObservers() + { + for (GObserver o : obs) + { + boolean isSuccess = o.apply(); + System.out.println(o.getClass()); + if (!isSuccess) + { + System.err.println("Une erreur s'est produite pendant le jeu."); + System.exit(1); + } + } + } + /** * Exécute un cycle du jeu *

@@ -254,15 +257,7 @@ public class Game } car.run(); - - for (GObserver o : obs) - { - if (!o.apply()) - { - System.err.println("Une erreur s'est produite pendant le jeu."); - System.exit(1); - } - } + notifyObservers(); } } @@ -280,7 +275,6 @@ public class Game try { step(); - GameView.update(); Thread.sleep(time); } catch (InterruptedException e) @@ -289,4 +283,24 @@ public class Game } } } + + public ArrayList getCars() + { + return cars; + } + + public Map getMap() + { + return map; + } + + public State getState() + { + return state; + } + + public boolean getPause() + { + return isPaused; + } } \ No newline at end of file diff --git a/src/GameView.java b/src/GameView.java index 5e3a17d..63dbf5a 100644 --- a/src/GameView.java +++ b/src/GameView.java @@ -1,5 +1,5 @@ import java.awt.BorderLayout; -import java.util.ArrayList; +import java.awt.GraphicsEnvironment; import javax.swing.JComponent; import javax.swing.JFrame; @@ -9,16 +9,23 @@ import javax.swing.JFrame; * Chaque GameView est associée à une fenêtre JFrame et s'inscrit dans * la liste globale des vues pour permettre des mises à jour centralisées. */ -public abstract class GameView extends JComponent +public abstract class GameView extends JComponent implements GObserver { - /** - * Liste statique contenant toutes les instances actives de GameView. - * Permet d'itérer sur toutes les vues pour les mettre à jour simultanément. - */ - private static ArrayList vobs = new ArrayList<>(); - /** Fenêtre associée à cette vue */ protected final JFrame frame; + protected final Game game; + + /** + * Bloc statique exécuté au chargement de la classe pour vérifier + * si le programme dispose d'un environnement graphique. + */ + static { + if (GraphicsEnvironment.isHeadless()) + { + System.err.println("Aucun serveur d'affichage trouvé"); + System.exit(1); + } + } /** * Construit une nouvelle GameView avec une fenêtre JFrame. @@ -29,8 +36,10 @@ public abstract class GameView extends JComponent * @param x Position horizontale de la fenêtre à l'écran * @param y Position verticale de la fenêtre à l'écran */ - protected GameView(String title, int width, int height, int x, int y) + protected GameView(Game game, String title, int width, int height, int x, int y) { + this.game = game; + // la fenetre this.frame = new JFrame(title); // position fenetre @@ -47,47 +56,7 @@ public abstract class GameView extends JComponent frame.setVisible(true); // mettre un layout frame.setLayout(new BorderLayout()); - register(); + + game.addObserver(this); } - - /** - * Enregistre cette GameView dans la liste statique des vues. - * - * @return l'instance courante (permet le chainage) - */ - protected GameView register() - { - vobs.add(this); - return this; - } - - /** - * Désenregistre cette GameView de la liste statique des vues. - * - * @return l'instance courante (permet le chainage) - */ - protected GameView unregister() - { - vobs.remove(this); - return this; - } - - /** - * Met à jour toutes les GameView enregistrées. - * Cette méthode itère sur la liste globale et appelle run() sur chaque instance. - * Utile pour rafraichir l'affichage de toutes les vues en même temps. - */ - public static void update() - { - for (GameView o : vobs) - { - o.run(); - } - } - - /** - * Méthode abstraite à implémenter par les classes filles. - * Elle est appelée par GameView.update() pour mettre à jour le contenu de la vue. - */ - protected abstract void run(); } \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index b0985f5..bb10fa3 100644 --- a/src/Main.java +++ b/src/Main.java @@ -20,9 +20,9 @@ public class Main { Map m = Map.fromInts(map); Game game = new Game.Builder() - .addCar(new Game.CarInfo("Voiture 1", Color.BLUE)) - .addCar(new Game.CarInfo("Voiture 2", Color.PINK)) - .addCar(new Game.CarInfo("Voiture 3", Color.RED)) + .addCar(new Game.CarInfo("Voiture 1", Color.BLUE, true)) + .addCar(new Game.CarInfo("Voiture 2", Color.PINK, true)) + .addCar(new Game.CarInfo("Voiture 3", Color.RED, true)) .setMap(m) .build(); game.run(); diff --git a/src/Rankboard.java b/src/Rankboard.java index 0f81e1f..03541f0 100644 --- a/src/Rankboard.java +++ b/src/Rankboard.java @@ -30,10 +30,10 @@ public class Rankboard extends GameView * @param x Position horizontale de la fenêtre * @param y Position verticale de la fenêtre */ - public Rankboard(String title, ArrayList cars, int width, int height, int x, int y) + public Rankboard(Game game, String title, int width, int height, int x, int y) { - super(title, width, height, x, y); - this.cars = cars; + super(game, title, width, height, x, y); + this.cars = game.getCars(); this.label = new JLabel(); this.add(label, BorderLayout.CENTER); } @@ -47,17 +47,19 @@ public class Rankboard extends GameView */ private void updateRankText() { + // cloner pour de modifier la classe principale ArrayList cars_clone = new ArrayList<>(cars); cars_clone.sort(Comparator.comparingInt(Car::getScore).reversed()); StringBuilder s = new StringBuilder(); s.append(""); - for (Car c : cars_clone) + for (Car c : cars) { - s.append(""); + s.append(""); } s.append("
" + c + ": " + c.getScore() + "%
" + c.getName() + ": " + c.getScore() + "%
"); + System.out.println(s); label.setText(s.toString()); } @@ -66,9 +68,9 @@ public class Rankboard extends GameView * Méthode appelée par GameView.update(). * Elle met à jour le classement affiché. */ - protected void run() + public boolean apply() { updateRankText(); + return true; } - } diff --git a/src/Track.java b/src/Track.java index 71f5b2d..bad5816 100644 --- a/src/Track.java +++ b/src/Track.java @@ -33,10 +33,11 @@ public class Track extends GameView { * @param x Position X de la fenêtre * @param y Position Y de la fenêtre */ - protected Track(Map map, ArrayList cars, String title, int width, int height, int x, int y) { - super(title, width, height, x, y); - this.map = map; - this.cars = cars; + protected Track(Game game, String title, int width, int height, int x, int y) + { + super(game, title, width, height, x, y); + map = game.getMap(); + cars = game.getCars(); } /** @@ -201,7 +202,9 @@ public class Track extends GameView { * Méthode appelée automatiquement pour mettre à jour l'affichage. */ @Override - protected void run() { - repaint(); + public boolean apply() + { + repaint(); + return true; } }