feat: enlever gameview observer et ajout dans l'observer de base

This commit is contained in:
2025-11-10 14:54:51 +01:00
parent 72eccbf721
commit f9e1580da5
7 changed files with 95 additions and 114 deletions

View File

@@ -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;
}

View File

@@ -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<Boolean> 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<Boolean> 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(
"<html><table><tr><td>Carburant Restant: " + car.getFuel()
@@ -103,5 +98,6 @@ public class Dashboard extends GameView
);
updateButtonText();
return true;
}
}

View File

@@ -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<CarInfo> 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<CarInfo> 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
* <p>
@@ -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<Car> getCars()
{
return cars;
}
public Map getMap()
{
return map;
}
public State getState()
{
return state;
}
public boolean getPause()
{
return isPaused;
}
}

View File

@@ -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<GameView> 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();
}

View File

@@ -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();

View File

@@ -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<Car> 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<Car> cars_clone = new ArrayList<>(cars);
cars_clone.sort(Comparator.comparingInt(Car::getScore).reversed());
StringBuilder s = new StringBuilder();
s.append("<html><table>");
for (Car c : cars_clone)
for (Car c : cars)
{
s.append("<tr><td>" + c + ": " + c.getScore() + "%</td></tr>");
s.append("<tr><td>" + c.getName() + ": " + c.getScore() + "%</td></tr>");
}
s.append("</table></html>");
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;
}
}

View File

@@ -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<Car> 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;
}
}