mirror of
https://github.com/guezoloic/L3-racing-game.git
synced 2026-03-28 19:13:41 +00:00
feat!: refonte du projet, bug niveau initialisation
This commit is contained in:
@@ -1,12 +1,34 @@
|
|||||||
|
import java.awt.Color;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import model.Game;
|
import model.Game;
|
||||||
|
import model.car.BasicCar;
|
||||||
|
import model.car.DrunkCar;
|
||||||
import model.map.Map;
|
import model.map.Map;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
Map map = Game.GameFactory.defaultMap();
|
Map map = Map.fromInts(new Integer[][] {
|
||||||
Game game = Game.GameFactory.defaultGame(map);
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 },
|
||||||
|
{ 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 },
|
||||||
|
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
|
||||||
|
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
|
||||||
|
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 },
|
||||||
|
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
|
||||||
|
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
|
||||||
|
{ 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
Game game = new Game.Builder()
|
||||||
|
.car(new BasicCar("Luwik", Color.RED))
|
||||||
|
.car(new DrunkCar(new BasicCar("Charazade", Color.PINK)))
|
||||||
|
.track("Piste Formule 1", 1000, 500, 1, 1)
|
||||||
|
.rankboard("Score", 200, 200, 0, 510)
|
||||||
|
.dashboards(300, 200, 1000, 0)
|
||||||
|
.map(map)
|
||||||
|
.build();
|
||||||
game.run();
|
game.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,285 +1,160 @@
|
|||||||
package model;
|
package model;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import model.car.Car;
|
import model.car.Car;
|
||||||
import model.map.Map;
|
import model.map.Map;
|
||||||
|
import visual.*;
|
||||||
|
|
||||||
/**
|
|
||||||
* La classe {@link Game} représente le moteur principal du jeu.
|
|
||||||
* <p>
|
|
||||||
* Elle contient le modèle (les voitures, l'état du jeu, la carte),
|
|
||||||
* la vue (Track, Dashboard, Rankboard) et la logique de contrôle
|
|
||||||
* (pause, boucle de jeu, observateurs).
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class Game {
|
public class Game {
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
/**
|
|
||||||
* L'interface utilisée pour Game.
|
|
||||||
*/
|
|
||||||
public static interface Observer {
|
public static interface Observer {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return true si la fonction s'est bien passé sinon false (le programme va se
|
* @return si False le programme s'arrete, sinon il continue
|
||||||
* stopper)
|
|
||||||
*/
|
*/
|
||||||
public boolean apply();
|
public boolean apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link VisualInfo} est un enregistrement (record) qui décrit une vue
|
|
||||||
* graphique
|
|
||||||
* à afficher dans le jeu (par exemple un tableau de bord, une piste ou un
|
|
||||||
* classement).
|
|
||||||
* <p>
|
|
||||||
* Chaque instance contient toutes les informations nécessaires pour créer et
|
|
||||||
* positionner
|
|
||||||
* cette vue à l’écran.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param type le type concret de la vue (classe héritant de {@link Game})
|
|
||||||
* @param title le titre de la fenêtre ou du panneau associé
|
|
||||||
* @param width la largeur en pixels de la vue
|
|
||||||
* @param height la hauteur en pixels de la vue
|
|
||||||
* @param x la position horizontale (en pixels) de la vue sur l’écran
|
|
||||||
* @param y la position verticale (en pixels) de la vue sur l’écran
|
|
||||||
*/
|
|
||||||
private record VisualInfo(Class<? extends Game> type,
|
|
||||||
String title, int width, int height, int x, int y) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GameFactory {
|
|
||||||
public static Map defaultMap() {
|
|
||||||
return Map.fromInts(new Integer[][] {
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 },
|
|
||||||
{ 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 },
|
|
||||||
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
|
|
||||||
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 },
|
|
||||||
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 },
|
|
||||||
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
|
|
||||||
{ 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 },
|
|
||||||
{ 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 },
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Game defaultGame(Map map) {
|
|
||||||
return new Game.Builder()
|
|
||||||
.addCar("Voiture à LUWIK", Color.BLUE)
|
|
||||||
.addCar("Voiture à CHARAZADE", Color.PINK)
|
|
||||||
.addCar("Voiture de UPEC", Color.RED)
|
|
||||||
.addVisual(Dashboard.class, "Voiture à LUWIK", 300, 200, 1000, 0)
|
|
||||||
.addVisual(Dashboard.class, "Voiture à CHARAZADE", 300, 200, 1000, 200)
|
|
||||||
.addVisual(Dashboard.class, "Voiture de UPEC", 300, 200, 1000, 400)
|
|
||||||
.addVisual(Track.class, "Piste Formule 1", 1000, 500, 1, 1)
|
|
||||||
.addVisual(Rankboard.class, "Score", 200, 200, 0, 510)
|
|
||||||
.setTime(1000)
|
|
||||||
.setMap(map)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builder pour créer une instance de {@link Game} de façon fluide.
|
|
||||||
* <p>
|
|
||||||
* Permet d'ajouter des voitures, de définir la carte, l'état initial et
|
|
||||||
* le temps entre les étapes du jeu avant de construire l'objet final.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
/** Liste des voitures à créer pour le jeu */
|
private final List<Game.Observer> OBSERVERS = new ArrayList<>();
|
||||||
private ArrayList<CarInfo> cars = new ArrayList<>();
|
private int time = 500;
|
||||||
/** Liste des voitures à créer pour le jeu */
|
|
||||||
private ArrayList<VisualInfo> visuals = new ArrayList<>();
|
|
||||||
/** État initial du jeu */
|
|
||||||
private Car.State state = Car.State.NORMAL;
|
|
||||||
/** Temps entre chaque step du jeu */
|
|
||||||
private int time = 1000;
|
|
||||||
/** Carte sur laquelle se déroule le jeu */
|
|
||||||
private Map map = null;
|
private Map map = null;
|
||||||
|
|
||||||
/** Ajoute une voiture à la liste */
|
public Builder car(Car car) {
|
||||||
public Builder addCar(String name, Color color) {
|
this.OBSERVERS.add(car);
|
||||||
cars.add(new CarInfo(name, color));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Supprime une voiture de la liste */
|
public Builder map(Map map) {
|
||||||
public Builder removeCar(String name, Color color) {
|
|
||||||
cars.forEach((car) -> {
|
|
||||||
if (car.name == name && car.color == color)
|
|
||||||
cars.remove(car);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Définit la carte du jeu */
|
|
||||||
public Builder setMap(Map map) {
|
|
||||||
this.map = map;
|
this.map = map;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Définit l'état initial du jeu */
|
public Builder time(int time) {
|
||||||
public Builder setState(Car.State s) {
|
|
||||||
this.state = s;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Définit le temps entre chaque étape du jeu */
|
|
||||||
public Builder setTime(int time) {
|
|
||||||
this.time = time;
|
this.time = time;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addVisual(Class<? extends Game> type, String title,
|
public Builder rankboard(String title, int width,
|
||||||
int width, int height, int x, int y) {
|
int height, int x, int y) {
|
||||||
visuals.add(new VisualInfo(type, title, width, height, x, y));
|
this.OBSERVERS.add(new Rankboard(null, title, width, height, x, y));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildVisual(Game game) {
|
public Builder track(String title, int width,
|
||||||
for (VisualInfo visual : visuals) {
|
int height, int x, int y) {
|
||||||
Game view = null;
|
this.OBSERVERS.add(new Track(null, title, width, height, x, y));
|
||||||
|
return this;
|
||||||
if (visual.type == Rankboard.class) {
|
}
|
||||||
view = new Rankboard(game, visual.title, visual.width,
|
|
||||||
visual.height, visual.x, visual.y);
|
public Builder dashboard(Car car, String title, int width,
|
||||||
} else if (visual.type == Track.class) {
|
int height, int x, int y) {
|
||||||
view = new Track(game, visual.title, visual.width,
|
this.OBSERVERS.add(new Dashboard(null, car, title, width, height, x, y));
|
||||||
visual.height, visual.x, visual.y);
|
return this;
|
||||||
} else if (visual.type == Dashboard.class) {
|
}
|
||||||
Car car = game.getCars().stream()
|
|
||||||
.filter((e) -> visual.title.equals(e.getName()))
|
public Builder dashboards(int width, int height, int x, int y) {
|
||||||
.findFirst()
|
List<Car> cars = OBSERVERS.stream()
|
||||||
.orElseThrow();
|
.filter(o -> o instanceof Car)
|
||||||
|
.map(o -> (Car) o)
|
||||||
view = new Dashboard(game,
|
.toList();
|
||||||
car,
|
|
||||||
visual.title, visual.width,
|
int index = 0;
|
||||||
visual.height, visual.x, visual.y);
|
for (Car car : cars) {
|
||||||
}
|
dashboard(car, car.getName(), width, height, x, y + (height * index++));
|
||||||
if (view != null)
|
}
|
||||||
game.addObserver(view);
|
return this;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construit l'instance de {@link Game} avec les paramètres définis.
|
|
||||||
* <p>
|
|
||||||
* Si la carte n'a pas été définie, le programme s'arrête.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public Game build() {
|
public Game build() {
|
||||||
if (map == null) {
|
Game game = new Game();
|
||||||
System.err.println("Vous devez définir une carte avant de construire le jeu !");
|
|
||||||
System.exit(1);
|
for (Game.Observer observer : this.OBSERVERS) {
|
||||||
|
switch (observer) {
|
||||||
|
case GameView gameView -> {
|
||||||
|
gameView.setGame(game);
|
||||||
|
}
|
||||||
|
case Car car -> {
|
||||||
|
car.setMap(map);
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game game = new Game(map, cars, state, time);
|
game.map = this.map;
|
||||||
buildVisual(game);
|
game.time = this.time;
|
||||||
|
game.observers = this.OBSERVERS;
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map map;
|
private Map map;
|
||||||
/** État du jeu (par exemple, positions, carburant) */
|
private int time;
|
||||||
private final Car.State state;
|
private List<Game.Observer> observers;
|
||||||
/** Temps entre chaque étape du jeu en millisecondes */
|
|
||||||
private final int time;
|
|
||||||
|
|
||||||
/** Liste des voitures du jeu */
|
private boolean isPaused;
|
||||||
private final ArrayList<Car> cars = new ArrayList<>();
|
|
||||||
/** Liste des observateurs pour la mise à jour des vues */
|
|
||||||
private final ArrayList<Observer> obs = new ArrayList<>();
|
|
||||||
|
|
||||||
/** Indique si le jeu est en pause */
|
private Game() {
|
||||||
private boolean isPaused = false;
|
}
|
||||||
|
|
||||||
/**
|
private Game(Map map, int time, List<Game.Observer> observer) {
|
||||||
* Constructeur principal.
|
|
||||||
*
|
|
||||||
* @param map carte du jeu
|
|
||||||
* @param carInfos liste des informations des voitures à créer
|
|
||||||
* @param state état initial du jeu
|
|
||||||
* @param time temps entre chaque étape du jeu
|
|
||||||
*/
|
|
||||||
public Game(Map map, ArrayList<CarInfo> carInfos, Car.State state, int time) {
|
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.state = state;
|
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
this.observers = observer;
|
||||||
init(carInfos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise le jeu en créant les vues et les objets {@link Car}.
|
|
||||||
* <p>
|
|
||||||
* Chaque voiture obtient un Dashboard, la piste est affichée avec Track,
|
|
||||||
* et le Rankboard est créé pour afficher le classement.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param carInfos liste des informations des voitures
|
|
||||||
* @return l'instance de Game
|
|
||||||
*/
|
|
||||||
private Game init(ArrayList<CarInfo> carInfos) {
|
|
||||||
// Création de chaque voiture avec son Dashboard
|
|
||||||
for (CarInfo ci : carInfos)
|
|
||||||
cars.add(new Car(ci.name, ci.color, map)
|
|
||||||
.setState(state));
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vérifie si le jeu est terminé.
|
|
||||||
* <p>
|
|
||||||
* Le jeu est fini si au moins une voiture a épuisé son carburant.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return true si le jeu est terminé
|
|
||||||
*/
|
|
||||||
private boolean isFinish() {
|
|
||||||
for (Car car : cars) {
|
|
||||||
if (car.getFuel() == 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ajoute un observateur pour recevoir les mises à jour du jeu.
|
|
||||||
*
|
|
||||||
* @param o observateur
|
|
||||||
* @return instance de Game pour chaîner
|
|
||||||
*/
|
|
||||||
public Game addObserver(Observer o) {
|
public Game addObserver(Observer o) {
|
||||||
obs.add(o);
|
observers.add(o);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Game removeObserver(Observer o) {
|
||||||
* Supprime un observateur.
|
observers.remove(o);
|
||||||
*
|
|
||||||
* @param o observateur
|
|
||||||
* @return instance de Game pour chaîner
|
|
||||||
*/
|
|
||||||
public Game remObserver(Observer o) {
|
|
||||||
obs.remove(o);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean isFinish() {
|
||||||
* Bascule l'état de pause du jeu.
|
for (Game.Observer observer : observers) {
|
||||||
* <p>
|
switch (observer) {
|
||||||
* Si le jeu était en pause, il est relancé et les threads en attente sont
|
case Car car -> {
|
||||||
* notifiés.
|
if (car.getFuel() > 0)
|
||||||
* </p>
|
return false;
|
||||||
*
|
}
|
||||||
* @return true si le jeu est maintenant en pause
|
default -> {
|
||||||
*/
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyObservers() {
|
||||||
|
for (Observer o : observers) {
|
||||||
|
if (!o.apply()) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (!isFinish()) {
|
||||||
|
synchronized (this) {
|
||||||
|
while (isPaused)
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
notifyObservers();
|
||||||
|
Thread.sleep(time);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized boolean togglePause() {
|
public synchronized boolean togglePause() {
|
||||||
if (isPaused)
|
if (isPaused)
|
||||||
notifyAll();
|
notifyAll();
|
||||||
@@ -287,73 +162,17 @@ public class Game {
|
|||||||
return isPaused;
|
return isPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyObservers() {
|
public List<Car> getCars() {
|
||||||
for (Observer o : obs) {
|
return observers.stream()
|
||||||
boolean isSuccess = o.apply();
|
.filter(o -> o instanceof Car)
|
||||||
if (!isSuccess) {
|
.map(o -> (Car) o)
|
||||||
System.err.println("Une erreur s'est produite pendant le jeu.");
|
.toList();
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exécute un cycle du jeu
|
|
||||||
* <p>
|
|
||||||
* Chaque voiture effectue son action, puis les observateurs sont notifiés.
|
|
||||||
* La boucle attend si le jeu est en pause.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @throws InterruptedException si le thread est interrompu pendant wait()
|
|
||||||
*/
|
|
||||||
private void step() throws InterruptedException {
|
|
||||||
for (Car car : cars) {
|
|
||||||
synchronized (this) {
|
|
||||||
while (isPaused)
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
car.run();
|
|
||||||
notifyObservers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Boucle principale du jeu.
|
|
||||||
* <p>
|
|
||||||
* Tant que le jeu n'est pas terminé, on exécute les étapes et on met à jour
|
|
||||||
* les vues toutes les 'time' millisecondes.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public void run() {
|
|
||||||
while (!isFinish()) {
|
|
||||||
try {
|
|
||||||
step();
|
|
||||||
Thread.sleep(time);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Fini!\nVoici le score :");
|
|
||||||
for (Car c : cars) {
|
|
||||||
System.out.println(c.getName() + "\t" + c.getScore());
|
|
||||||
}
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<Car> getCars() {
|
|
||||||
return cars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map getMap() {
|
public Map getMap() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Car.State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getPause() {
|
public boolean getPause() {
|
||||||
return isPaused;
|
return isPaused;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class BasicCar implements Car {
|
|||||||
/** Nombre de tours complétés */
|
/** Nombre de tours complétés */
|
||||||
private int round = 0;
|
private int round = 0;
|
||||||
/** Nombre de cases dans une boucle (doit être > 0) */
|
/** Nombre de cases dans une boucle (doit être > 0) */
|
||||||
private final Map MAP;
|
private Map map;
|
||||||
/** Carburant restant */
|
/** Carburant restant */
|
||||||
private int fuel = 60;
|
private int fuel = 60;
|
||||||
|
|
||||||
@@ -46,7 +46,12 @@ public class BasicCar implements Car {
|
|||||||
public BasicCar(String name, Color color, Map map) {
|
public BasicCar(String name, Color color, Map map) {
|
||||||
this.NAME = name;
|
this.NAME = name;
|
||||||
this.COLOR = color;
|
this.COLOR = color;
|
||||||
this.MAP = map;
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BasicCar(String name, Color color) {
|
||||||
|
this.NAME = name;
|
||||||
|
this.COLOR = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,40 +82,6 @@ public class BasicCar implements Car {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return la position actuelle dans la boucle
|
|
||||||
*/
|
|
||||||
public int getPosition() {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return le score de la voiture, calculé comme :
|
|
||||||
* (nombre de tours + progression du tour) × 100
|
|
||||||
*/
|
|
||||||
public int getScore() {
|
|
||||||
return (int) ((round + (float) pos / MAP.getPathSize()) * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return le nombre de tours complétés
|
|
||||||
*/
|
|
||||||
public int getRound() {
|
|
||||||
return round;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return le carburant restant
|
|
||||||
*/
|
|
||||||
public int getFuel() {
|
|
||||||
return fuel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retourne l'état courant de la voiture. */
|
|
||||||
public State getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clique sur "Accelerer" : change d'état et retourne un message (si
|
* Clique sur "Accelerer" : change d'état et retourne un message (si
|
||||||
* nécessaire).
|
* nécessaire).
|
||||||
@@ -175,15 +146,15 @@ public class BasicCar implements Car {
|
|||||||
for (int i = 0; i < jump; i++) {
|
for (int i = 0; i < jump; i++) {
|
||||||
pos = state.move(pos, movement);
|
pos = state.move(pos, movement);
|
||||||
|
|
||||||
Point point = MAP.getPath(pos);
|
Point point = map.getPath(pos);
|
||||||
Circuit element = MAP.getElement(point.x, point.y);
|
Circuit element = map.getElement(point.x, point.y);
|
||||||
|
|
||||||
if (hasAccident(element, jump)) {
|
if (hasAccident(element, jump)) {
|
||||||
System.out.println(NAME + " a un\taccident");
|
System.out.println(NAME + " a un\taccident");
|
||||||
setDamage();
|
setDamage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
round = pos / MAP.getPathSize();
|
round = pos / map.getPathSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +174,10 @@ public class BasicCar implements Car {
|
|||||||
fuel = 0; // sécurité
|
fuel = 0; // sécurité
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasFinished() {
|
||||||
|
return 3 < round;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exécute une "étape" de la voiture : avance d'une position aléatoire et
|
* Exécute une "étape" de la voiture : avance d'une position aléatoire et
|
||||||
* consomme du carburant.
|
* consomme du carburant.
|
||||||
@@ -212,11 +187,11 @@ public class BasicCar implements Car {
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public boolean apply() {
|
||||||
if (fuel > 0) {
|
if (fuel > 0) {
|
||||||
move();
|
move();
|
||||||
consumeFuel();
|
|
||||||
}
|
}
|
||||||
|
return !hasFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -225,12 +200,39 @@ public class BasicCar implements Car {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return la position actuelle (synonyme de getPosition)
|
* @return la position actuelle dans la boucle
|
||||||
*/
|
*/
|
||||||
public int getPos() {
|
public int getPosition() {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return le score de la voiture, calculé comme :
|
||||||
|
* (nombre de tours + progression du tour) × 100
|
||||||
|
*/
|
||||||
|
public int getScore() {
|
||||||
|
return (int) ((round + (float) pos / map.getPathSize()) * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return le nombre de tours complétés
|
||||||
|
*/
|
||||||
|
public int getRound() {
|
||||||
|
return round;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return le carburant restant
|
||||||
|
*/
|
||||||
|
public int getFuel() {
|
||||||
|
return fuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Retourne l'état courant de la voiture. */
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return la couleur de la voiture
|
* @return la couleur de la voiture
|
||||||
*/
|
*/
|
||||||
@@ -244,4 +246,9 @@ public class BasicCar implements Car {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMap(Map map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package model.car;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
public interface Car {
|
import model.Game.Observer;
|
||||||
|
import model.map.Map;
|
||||||
|
|
||||||
|
public interface Car extends Observer {
|
||||||
public String accelerate();
|
public String accelerate();
|
||||||
|
|
||||||
public String decelerate();
|
public String decelerate();
|
||||||
@@ -11,13 +14,21 @@ public interface Car {
|
|||||||
|
|
||||||
public void consumeFuel();
|
public void consumeFuel();
|
||||||
|
|
||||||
public void run();
|
|
||||||
|
|
||||||
public void reverse(boolean active);
|
public void reverse(boolean active);
|
||||||
|
|
||||||
public int getPos();
|
|
||||||
|
|
||||||
public Color getColor();
|
public Color getColor();
|
||||||
|
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
public int getPosition();
|
||||||
|
|
||||||
|
public int getScore();
|
||||||
|
|
||||||
|
public int getRound();
|
||||||
|
|
||||||
|
public int getFuel();
|
||||||
|
|
||||||
|
public State getState();
|
||||||
|
|
||||||
|
public void setMap(Map map);
|
||||||
}
|
}
|
||||||
|
|||||||
85
src/model/car/CarDecorator.java
Normal file
85
src/model/car/CarDecorator.java
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package model.car;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import model.map.Map;
|
||||||
|
|
||||||
|
public abstract class CarDecorator implements Car {
|
||||||
|
protected final Car car;
|
||||||
|
|
||||||
|
public CarDecorator(Car car) {
|
||||||
|
this.car = car;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String accelerate() {
|
||||||
|
return car.accelerate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String decelerate() {
|
||||||
|
return car.decelerate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move() {
|
||||||
|
car.move();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeFuel() {
|
||||||
|
car.consumeFuel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply() {
|
||||||
|
boolean response = car.apply();
|
||||||
|
car.consumeFuel();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reverse(boolean active) {
|
||||||
|
car.reverse(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor() {
|
||||||
|
return car.getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return car.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPosition() {
|
||||||
|
return car.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScore() {
|
||||||
|
return car.getScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRound() {
|
||||||
|
return car.getRound();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFuel() {
|
||||||
|
return car.getFuel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return car.getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMap(Map map) {
|
||||||
|
car.setMap(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package model.car;
|
package model.car;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,14 +13,12 @@ import java.util.Random;
|
|||||||
* => On modifie seulement les actions utilisateur (accelerate/decelerate),
|
* => On modifie seulement les actions utilisateur (accelerate/decelerate),
|
||||||
* sans modifier la classe Car.
|
* sans modifier la classe Car.
|
||||||
*/
|
*/
|
||||||
public class DrunkCar implements Car {
|
public class DrunkCar extends CarDecorator {
|
||||||
/** Générateur de nombres aléatoires pour simuler la progression */
|
/** Générateur de nombres aléatoires pour simuler la progression */
|
||||||
protected static final Random RANDOM = new Random();
|
protected static final Random RANDOM = new Random();
|
||||||
|
|
||||||
private Car car;
|
|
||||||
|
|
||||||
public DrunkCar(Car car) {
|
public DrunkCar(Car car) {
|
||||||
this.car = car;
|
super(car);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,44 +29,4 @@ public class DrunkCar implements Car {
|
|||||||
car.move();
|
car.move();
|
||||||
car.reverse(false);
|
car.reverse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
car.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String accelerate() {
|
|
||||||
return car.accelerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String decelerate() {
|
|
||||||
return car.decelerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeFuel() {
|
|
||||||
car.consumeFuel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reverse(boolean active) {
|
|
||||||
car.reverse(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPos() {
|
|
||||||
return car.getPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color getColor() {
|
|
||||||
return car.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return car.getName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,12 +10,11 @@ import java.awt.Color;
|
|||||||
* - Mais elle consomme du carburant seulement 1 fois sur 2
|
* - Mais elle consomme du carburant seulement 1 fois sur 2
|
||||||
* => donc elle économise du carburant.
|
* => donc elle économise du carburant.
|
||||||
*/
|
*/
|
||||||
public class HybridCar implements Car {
|
public class HybridCar extends CarDecorator {
|
||||||
private Car car;
|
|
||||||
private int energy = 100; // énergie batterie (0..100)
|
private int energy = 100; // énergie batterie (0..100)
|
||||||
|
|
||||||
public HybridCar(Car car) {
|
public HybridCar(Car car) {
|
||||||
this.car = car;
|
super(car);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** pour afficher l'énergie dans le Dashboard */
|
/** pour afficher l'énergie dans le Dashboard */
|
||||||
@@ -24,68 +23,25 @@ public class HybridCar implements Car {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public boolean apply() {
|
||||||
// 1) La voiture avance toujours
|
boolean response = car.apply();
|
||||||
car.move();
|
|
||||||
|
|
||||||
// 2) Gestion énergie : elle perd 10% à chaque boucle
|
if (energy > 0) {
|
||||||
energy -= 10;
|
energy -= 10;
|
||||||
if (energy < 0)
|
} else {
|
||||||
energy = 0;
|
|
||||||
|
|
||||||
// 3) Consommation :
|
|
||||||
// - si on a encore de l'énergie, on économise le fuel (pas de conso)
|
|
||||||
// - sinon, on consomme normalement
|
|
||||||
if (energy == 0) {
|
|
||||||
car.consumeFuel();
|
car.consumeFuel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String decelerate() {
|
public String decelerate() {
|
||||||
// 1) On applique le ralentissement normal (State pattern)
|
|
||||||
String msg = car.decelerate();
|
String msg = car.decelerate();
|
||||||
|
|
||||||
// 2) Recharge +5% quand on ralentit
|
if (energy <= 100)
|
||||||
energy += 5;
|
energy += 5;
|
||||||
if (energy > 100)
|
|
||||||
energy = 100;
|
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeFuel() {
|
|
||||||
car.consumeFuel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void move() {
|
|
||||||
car.move();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String accelerate() {
|
|
||||||
return car.accelerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reverse(boolean active) {
|
|
||||||
car.reverse(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPos() {
|
|
||||||
return car.getPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color getColor() {
|
|
||||||
return car.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return car.getName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import java.awt.Color;
|
|||||||
* Décorateur Sound :
|
* Décorateur Sound :
|
||||||
* affiche un message sonore quand la voiture accélère.
|
* affiche un message sonore quand la voiture accélère.
|
||||||
*/
|
*/
|
||||||
public class SoundCar implements Car {
|
public class SoundCar extends CarDecorator {
|
||||||
private Car car;
|
|
||||||
|
|
||||||
public SoundCar(Car car) {
|
public SoundCar(Car car) {
|
||||||
this.car = car;
|
super(car);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -18,45 +16,4 @@ public class SoundCar implements Car {
|
|||||||
System.out.println("VROOOOM VROOOOOOM");
|
System.out.println("VROOOOM VROOOOOOM");
|
||||||
return car.accelerate();
|
return car.accelerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
car.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String decelerate() {
|
|
||||||
return car.decelerate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void move() {
|
|
||||||
car.move();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeFuel() {
|
|
||||||
car.consumeFuel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reverse(boolean active) {
|
|
||||||
car.reverse(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPos() {
|
|
||||||
return car.getPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color getColor() {
|
|
||||||
return car.getColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getName'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ import javax.swing.JLabel;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
import model.Game;
|
import model.Game;
|
||||||
import model.car.BasicCar;
|
import model.car.Car;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dashboard représente une vue graphique pour une voiture spécifique.
|
* Dashboard représente une vue graphique pour une voiture spécifique.
|
||||||
*
|
*
|
||||||
* Il affiche :
|
* Il affiche :
|
||||||
* - le carburant restant
|
* - le carburant restant
|
||||||
* - le nombre de tours complétés
|
* - le nombre de tours complétés
|
||||||
* - l'état courant de la voiture
|
* - l'état courant de la voiture
|
||||||
* - un message (info utilisateur)
|
* - un message (info utilisateur)
|
||||||
*
|
*
|
||||||
* Il fournit :
|
* Il fournit :
|
||||||
* - un bouton Pause/Reprise du jeu
|
* - un bouton Pause/Reprise du jeu
|
||||||
* - un bouton Accelerer
|
* - un bouton Accelerer
|
||||||
* - un bouton Rallentir
|
* - un bouton Rallentir
|
||||||
*/
|
*/
|
||||||
public class Dashboard extends GameView {
|
public class Dashboard extends GameView {
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public class Dashboard extends GameView {
|
|||||||
private final JButton decelerateButton = new JButton("Rallentir");
|
private final JButton decelerateButton = new JButton("Rallentir");
|
||||||
|
|
||||||
/** Voiture associée à ce dashboard */
|
/** Voiture associée à ce dashboard */
|
||||||
private final BasicCar car;
|
private Car car;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construit un dashboard pour une voiture donnée.
|
* Construit un dashboard pour une voiture donnée.
|
||||||
@@ -57,13 +57,15 @@ public class Dashboard extends GameView {
|
|||||||
* @param x position horizontale de la fenêtre
|
* @param x position horizontale de la fenêtre
|
||||||
* @param y position verticale de la fenêtre
|
* @param y position verticale de la fenêtre
|
||||||
*/
|
*/
|
||||||
public Dashboard(Game game, BasicCar car, String title, 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(game, "Dashboard: " + title, width, height, x, y);
|
super(game, "Dashboard: " + title, width, height, x, y);
|
||||||
|
|
||||||
this.car = car;
|
this.car = car;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (car != null && game != null)
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
// Fond de la fenêtre = couleur de la voiture
|
// Fond de la fenêtre = couleur de la voiture
|
||||||
frame.setBackground(car.getColor());
|
frame.setBackground(car.getColor());
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ public class Dashboard extends GameView {
|
|||||||
centerPanel.add(infoLabel);
|
centerPanel.add(infoLabel);
|
||||||
centerPanel.add(stateLabel);
|
centerPanel.add(stateLabel);
|
||||||
centerPanel.add(messageLabel);
|
centerPanel.add(messageLabel);
|
||||||
//pour rendre le panel transparent
|
// pour rendre le panel transparent
|
||||||
centerPanel.setOpaque(false);
|
centerPanel.setOpaque(false);
|
||||||
|
|
||||||
// ----- Partie boutons -----
|
// ----- Partie boutons -----
|
||||||
@@ -80,7 +82,6 @@ public class Dashboard extends GameView {
|
|||||||
buttonPanel.add(decelerateButton);
|
buttonPanel.add(decelerateButton);
|
||||||
buttonPanel.add(pauseButton);
|
buttonPanel.add(pauseButton);
|
||||||
buttonPanel.add(accelerateButton);
|
buttonPanel.add(accelerateButton);
|
||||||
|
|
||||||
|
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
add(centerPanel, BorderLayout.CENTER);
|
add(centerPanel, BorderLayout.CENTER);
|
||||||
@@ -108,25 +109,38 @@ public class Dashboard extends GameView {
|
|||||||
|
|
||||||
// Accélérer
|
// Accélérer
|
||||||
accelerateButton.addActionListener(e -> {
|
accelerateButton.addActionListener(e -> {
|
||||||
String msg = car.accelerate();
|
String msg = car.accelerate();
|
||||||
messageLabel.setText(msg);
|
messageLabel.setText(msg);
|
||||||
game.notifyObservers();
|
game.notifyObservers();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ralentir
|
// Ralentir
|
||||||
decelerateButton.addActionListener(e -> {
|
decelerateButton.addActionListener(e -> {
|
||||||
String msg = car.decelerate();
|
String msg = car.decelerate();
|
||||||
messageLabel.setText(msg);
|
messageLabel.setText(msg);
|
||||||
game.notifyObservers();
|
game.notifyObservers();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCar(Car car) {
|
||||||
|
this.car = car;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mise à jour de la vue.
|
* Mise à jour de la vue.
|
||||||
* Cette méthode est appelée par Game via notifyObservers().
|
* Cette méthode est appelée par Game via notifyObservers().
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean apply() {
|
public boolean apply() {
|
||||||
|
if (this.car == null) {
|
||||||
|
System.out.println("ERREUR Dashboard: car est null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!super.apply()) {
|
||||||
|
System.out.println("ERREUR Dashboard: game est null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
infoLabel.setText("Carburant : " + car.getFuel() + " | Tours : " + car.getRound());
|
infoLabel.setText("Carburant : " + car.getFuel() + " | Tours : " + car.getRound());
|
||||||
stateLabel.setText("Etat : " + car.getState());
|
stateLabel.setText("Etat : " + car.getState());
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ import model.Game;
|
|||||||
*/
|
*/
|
||||||
public abstract class GameView extends JComponent implements Game.Observer {
|
public abstract class GameView extends JComponent implements Game.Observer {
|
||||||
/** Fenêtre associée à cette vue */
|
/** Fenêtre associée à cette vue */
|
||||||
protected final JFrame frame;
|
protected JFrame frame;
|
||||||
protected final Game game;
|
protected Game game;
|
||||||
|
private String title;
|
||||||
|
private int width, height;
|
||||||
|
private int x, y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bloc statique exécuté au chargement de la classe pour vérifier
|
* Bloc statique exécuté au chargement de la classe pour vérifier
|
||||||
@@ -29,6 +32,10 @@ public abstract class GameView extends JComponent implements Game.Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGame(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construit une nouvelle GameView avec une fenêtre JFrame.
|
* Construit une nouvelle GameView avec une fenêtre JFrame.
|
||||||
*
|
*
|
||||||
@@ -38,7 +45,7 @@ public abstract class GameView extends JComponent implements Game.Observer {
|
|||||||
* @param x Position horizontale de la fenêtre à l'écran
|
* @param x Position horizontale de la fenêtre à l'écran
|
||||||
* @param y Position verticale de la fenêtre à l'écran
|
* @param y Position verticale de la fenêtre à l'écran
|
||||||
*/
|
*/
|
||||||
protected GameView(Game game, String title, int width, int height, int x, int y) {
|
protected void init(Game game) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
|
||||||
// la fenetre
|
// la fenetre
|
||||||
@@ -60,4 +67,20 @@ public abstract class GameView extends JComponent implements Game.Observer {
|
|||||||
|
|
||||||
game.addObserver(this);
|
game.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected GameView(Game game, String title, int width, int height, int x, int y) {
|
||||||
|
this.title = title;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
|
||||||
|
if (game != null)
|
||||||
|
init(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply() {
|
||||||
|
return (game != null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,12 @@ package visual;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
import model.Game;
|
import model.Game;
|
||||||
import model.car.BasicCar;
|
import model.car.Car;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rankboard est une vue graphique affichant le classement des voitures.
|
* Rankboard est une vue graphique affichant le classement des voitures.
|
||||||
@@ -18,58 +19,68 @@ import model.car.BasicCar;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class Rankboard extends GameView {
|
public class Rankboard extends GameView {
|
||||||
/** Liste des voitures à afficher */
|
/** Liste des voitures à afficher */
|
||||||
ArrayList<BasicCar> cars;
|
List<Car> cars;
|
||||||
|
|
||||||
/** Composant JLabel pour afficher le classement */
|
/** Composant JLabel pour afficher le classement */
|
||||||
private final JLabel label;
|
private JLabel label;
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Construit un Rankboard.
|
protected void init(Game game) {
|
||||||
*
|
super.init(game);
|
||||||
* @param title Titre de la fenêtre
|
this.cars = game.getCars();
|
||||||
* @param cars Liste des voitures à suivre
|
this.label = new JLabel();
|
||||||
* @param width Largeur de la fenêtre
|
this.add(label, BorderLayout.CENTER);
|
||||||
* @param height Hauteur de la fenêtre
|
}
|
||||||
* @param x Position horizontale de la fenêtre
|
|
||||||
* @param y Position verticale de la fenêtre
|
|
||||||
*/
|
|
||||||
public Rankboard(Game game, String title, int width, int height, int x, int y) {
|
|
||||||
super(game, title, width, height, x, y);
|
|
||||||
this.cars = game.getCars();
|
|
||||||
this.label = new JLabel();
|
|
||||||
this.add(label, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Met à jour le texte affiché dans le JLabel.
|
* Construit un Rankboard.
|
||||||
* <p>
|
*
|
||||||
* Trie les voitures par score décroissant et construit
|
* @param title Titre de la fenêtre
|
||||||
* un tableau HTML pour l'affichage.
|
* @param cars Liste des voitures à suivre
|
||||||
* </p>
|
* @param width Largeur de la fenêtre
|
||||||
*/
|
* @param height Hauteur de la fenêtre
|
||||||
private void updateRankText() {
|
* @param x Position horizontale de la fenêtre
|
||||||
|
* @param y Position verticale de la fenêtre
|
||||||
|
*/
|
||||||
|
public Rankboard(Game game, String title, int width, int height, int x, int y) {
|
||||||
|
super(game, title, width, height, x, y);
|
||||||
|
if (game != null)
|
||||||
|
init(game);
|
||||||
|
}
|
||||||
|
|
||||||
// cloner pour de modifier la classe principale
|
/**
|
||||||
ArrayList<BasicCar> cars_clone = new ArrayList<>(cars);
|
* Met à jour le texte affiché dans le JLabel.
|
||||||
cars_clone.sort(Comparator.comparingInt(BasicCar::getScore).reversed());
|
* <p>
|
||||||
|
* Trie les voitures par score décroissant et construit
|
||||||
|
* un tableau HTML pour l'affichage.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
private void updateRankText() {
|
||||||
|
// cloner pour de modifier la classe principale
|
||||||
|
List<Car> cars_clone = new ArrayList<>(cars);
|
||||||
|
cars_clone.sort(Comparator.comparingInt(Car::getScore).reversed());
|
||||||
|
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
s.append("<html><table>");
|
s.append("<html><table>");
|
||||||
for (BasicCar c : cars_clone) {
|
for (Car c : cars_clone) {
|
||||||
s.append("<tr><td>" + c.getName() + ": " + c.getScore() + "%</td></tr>");
|
s.append("<tr><td>" + c.getName() + ": " + c.getScore() + "%</td></tr>");
|
||||||
}
|
}
|
||||||
s.append("</table></html>");
|
s.append("</table></html>");
|
||||||
label.setText(s.toString());
|
label.setText(s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
/**
|
/**
|
||||||
* Méthode appelée par GameView.update().
|
* Méthode appelée par GameView.update().
|
||||||
* Elle met à jour le classement affiché.
|
* Elle met à jour le classement affiché.
|
||||||
*/
|
*/
|
||||||
public boolean apply() {
|
public boolean apply() {
|
||||||
updateRankText();
|
if (!super.apply()) {
|
||||||
return true;
|
System.out.println("ERREUR Rankboard: game est null");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
updateRankText();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,216 +1,229 @@
|
|||||||
package visual;
|
package visual;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.util.ArrayList;
|
import java.util.List;
|
||||||
|
|
||||||
import model.Game;
|
import model.Game;
|
||||||
import model.car.BasicCar;
|
import model.car.Car;
|
||||||
import model.map.Circuit;
|
import model.map.Circuit;
|
||||||
import model.map.Map;
|
import model.map.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>Track</code> est une vue graphique représentant le circuit de course
|
* <code>Track</code> est une vue graphique représentant le circuit de course
|
||||||
* ainsi que les voitures qui y circulent.
|
* ainsi que les voitures qui y circulent.
|
||||||
* Cette classe hérite de <code>GameView</code> pour être intégrée au système de vues.
|
* Cette classe hérite de <code>GameView</code> pour être intégrée au système de
|
||||||
|
* vues.
|
||||||
* <p>
|
* <p>
|
||||||
* Le rendu est basé sur une grille définie par <code>Map</code> et chaque cellule
|
* Le rendu est basé sur une grille définie par <code>Map</code> et chaque
|
||||||
|
* cellule
|
||||||
* est dessinée selon son type. Les voitures sont superposées sur la grille.
|
* est dessinée selon son type. Les voitures sont superposées sur la grille.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class Track extends GameView {
|
public class Track extends GameView {
|
||||||
/** La carte du circuit */
|
/** La carte du circuit */
|
||||||
private Map map;
|
private Map map;
|
||||||
/** Liste des voitures à dessiner */
|
/** Liste des voitures à dessiner */
|
||||||
private ArrayList<BasicCar> cars;
|
private List<Car> cars;
|
||||||
/** Échelle utilisée pour ajuster la taille des voitures dans les cellules */
|
/** Échelle utilisée pour ajuster la taille des voitures dans les cellules */
|
||||||
private final int scale = 80;
|
private final int scale = 80;
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Construit la vue Track avec une carte et une liste de voitures.
|
protected void init(Game game) {
|
||||||
*
|
super.init(game);
|
||||||
* @param map La carte du circuit
|
map = game.getMap();
|
||||||
* @param cars Liste des voitures
|
cars = game.getCars();
|
||||||
* @param title Titre de la fenêtre
|
}
|
||||||
* @param width Largeur de la fenêtre
|
|
||||||
* @param height Hauteur de la fenêtre
|
|
||||||
* @param x Position X de la fenêtre
|
|
||||||
* @param y Position Y de la fenêtre
|
|
||||||
*/
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Méthode de dessin appelée automatiquement par Swing.
|
* Construit la vue Track avec une carte et une liste de voitures.
|
||||||
* Dessine chaque cellule de la carte ainsi que les voitures.
|
*
|
||||||
*/
|
* @param map La carte du circuit
|
||||||
@Override
|
* @param cars Liste des voitures
|
||||||
protected void paintComponent(Graphics g) {
|
* @param title Titre de la fenêtre
|
||||||
super.paintComponent(g);
|
* @param width Largeur de la fenêtre
|
||||||
|
* @param height Hauteur de la fenêtre
|
||||||
|
* @param x Position X de la fenêtre
|
||||||
|
* @param y Position Y de la fenêtre
|
||||||
|
*/
|
||||||
|
public Track(Game game, String title, int width, int height, int x, int y) {
|
||||||
|
super(game, title, width, height, x, y);
|
||||||
|
if (game != null)
|
||||||
|
init(game);
|
||||||
|
}
|
||||||
|
|
||||||
int rows = map.getHeight();
|
/**
|
||||||
int cols = map.getWidth();
|
* Méthode de dessin appelée automatiquement par Swing.
|
||||||
|
* Dessine chaque cellule de la carte ainsi que les voitures.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
// Calcul de la taille d'une cellule en pixels selon la taille de la fenêtre
|
int rows = map.getHeight();
|
||||||
int[] cellSize = new int[] {
|
int cols = map.getWidth();
|
||||||
(getWidth() + 10) / cols,
|
|
||||||
(getHeight() + 10) / rows
|
|
||||||
};
|
|
||||||
|
|
||||||
// Définir une police monospace en gras pour les caractères du circuit
|
// Calcul de la taille d'une cellule en pixels selon la taille de la fenêtre
|
||||||
g.setFont(new Font("Monospaced", Font.BOLD, cellSize[1] / 2));
|
int[] cellSize = new int[] {
|
||||||
|
(getWidth() + 10) / cols,
|
||||||
|
(getHeight() + 10) / rows
|
||||||
|
};
|
||||||
|
|
||||||
// Parcours de toutes les cellules du circuit
|
// Définir une police monospace en gras pour les caractères du circuit
|
||||||
for (int y = 0; y < rows; y++) {
|
g.setFont(new Font("Monospaced", Font.BOLD, cellSize[1] / 2));
|
||||||
for (int x = 0; x < cols; x++) {
|
|
||||||
Circuit cell = this.map.getElement(x, y);
|
|
||||||
drawCell(g, cell, new int[] {x, y}, cellSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Parcours de toutes les cellules du circuit
|
||||||
* Retourne la couleur d'une cellule selon son type.
|
for (int y = 0; y < rows; y++) {
|
||||||
*/
|
for (int x = 0; x < cols; x++) {
|
||||||
private Color getCellColor(Circuit.Cell cell) {
|
Circuit cell = this.map.getElement(x, y);
|
||||||
return switch (cell) {
|
drawCell(g, cell, new int[] { x, y }, cellSize);
|
||||||
case ROAD -> Color.GRAY;
|
}
|
||||||
case START -> Color.YELLOW;
|
}
|
||||||
case FINISH -> Color.YELLOW;
|
}
|
||||||
case EMPTY -> Color.GREEN;
|
|
||||||
case YROAD -> Color.YELLOW;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne le caractère à afficher pour une cellule du circuit.
|
* Retourne la couleur d'une cellule selon son type.
|
||||||
*/
|
*/
|
||||||
private char getCellChar(Circuit cell) {
|
private Color getCellColor(Circuit.Cell cell) {
|
||||||
return switch (cell.getType()) {
|
return switch (cell) {
|
||||||
case ROAD -> '\0';
|
case ROAD -> Color.GRAY;
|
||||||
case START -> 'D';
|
case START -> Color.YELLOW;
|
||||||
case FINISH -> 'A';
|
case FINISH -> Color.YELLOW;
|
||||||
case EMPTY -> '\0';
|
case EMPTY -> Color.GREEN;
|
||||||
case YROAD -> (char)('0' + cell.getValue());
|
case YROAD -> Color.YELLOW;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessine toutes les voitures sur une cellule donnée.
|
* Retourne le caractère à afficher pour une cellule du circuit.
|
||||||
* Les voitures sont légèrement décalées pour ne pas avoir exactement la même taille.
|
*/
|
||||||
*/
|
private char getCellChar(Circuit cell) {
|
||||||
private void drawCars(Graphics g, int[] cellCoord) {
|
return switch (cell.getType()) {
|
||||||
int size = 1;
|
case ROAD -> '\0';
|
||||||
for (BasicCar c : cars) {
|
case START -> 'D';
|
||||||
int i = c.getPos();
|
case FINISH -> 'A';
|
||||||
Point p = this.map.getPath(i);
|
case EMPTY -> '\0';
|
||||||
int[] ncoord = new int[] {p.x, p.y};
|
case YROAD -> (char) ('0' + cell.getValue());
|
||||||
drawInnerBlock(g, ncoord, cellCoord, c.getColor(), scale - size);
|
};
|
||||||
size += 3; // pour différencier visuellement les voitures
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessine une cellule complète avec son contenu (caractère et voitures).
|
* Dessine toutes les voitures sur une cellule donnée.
|
||||||
*/
|
* Les voitures sont légèrement décalées pour ne pas avoir exactement la même
|
||||||
private void drawCell(Graphics g, Circuit cell, int[] coord, int[] cellCoord) {
|
* taille.
|
||||||
drawBlock(g, cell, coord, cellCoord);
|
*/
|
||||||
|
private void drawCars(Graphics g, int[] cellCoord) {
|
||||||
|
int size = 1;
|
||||||
|
for (Car c : cars) {
|
||||||
|
int i = c.getPosition();
|
||||||
|
Point p = this.map.getPath(i);
|
||||||
|
int[] ncoord = new int[] { p.x, p.y };
|
||||||
|
drawInnerBlock(g, ncoord, cellCoord, c.getColor(), scale - size);
|
||||||
|
size += 3; // pour différencier visuellement les voitures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char c = getCellChar(cell);
|
/**
|
||||||
if (c != '\0') {
|
* Dessine une cellule complète avec son contenu (caractère et voitures).
|
||||||
drawCharacter(g, coord, cellCoord, c);
|
*/
|
||||||
}
|
private void drawCell(Graphics g, Circuit cell, int[] coord, int[] cellCoord) {
|
||||||
|
drawBlock(g, cell, coord, cellCoord);
|
||||||
|
|
||||||
drawCars(g, cellCoord);
|
char c = getCellChar(cell);
|
||||||
}
|
if (c != '\0') {
|
||||||
|
drawCharacter(g, coord, cellCoord, c);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
drawCars(g, cellCoord);
|
||||||
* Dessine un caractère centré dans une cellule.
|
}
|
||||||
*/
|
|
||||||
private void drawCharacter(Graphics g, int[] coord, int[] cellCoord, char c) {
|
|
||||||
int x = coord[0];
|
|
||||||
int y = coord[1];
|
|
||||||
|
|
||||||
int cellWidth = cellCoord[0];
|
/**
|
||||||
int cellHeight = cellCoord[1];
|
* Dessine un caractère centré dans une cellule.
|
||||||
|
*/
|
||||||
|
private void drawCharacter(Graphics g, int[] coord, int[] cellCoord, char c) {
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
|
||||||
String s = c + "";
|
int cellWidth = cellCoord[0];
|
||||||
g.setColor(Color.BLACK);
|
int cellHeight = cellCoord[1];
|
||||||
|
|
||||||
FontMetrics fm = g.getFontMetrics();
|
String s = c + "";
|
||||||
// taille du string + font
|
g.setColor(Color.BLACK);
|
||||||
int textWidth = fm.stringWidth(s);
|
|
||||||
// hauteur haute par exemple: h depasse en haut
|
|
||||||
int textHeight = fm.getAscent();
|
|
||||||
// hauteur basse par exemple: g depasse en bas
|
|
||||||
int descent = fm.getDescent();
|
|
||||||
|
|
||||||
int cx = x * cellWidth + (cellWidth - textWidth) / 2;
|
FontMetrics fm = g.getFontMetrics();
|
||||||
int cy = y * cellHeight + (cellHeight + textHeight - descent) / 2;
|
// taille du string + font
|
||||||
|
int textWidth = fm.stringWidth(s);
|
||||||
|
// hauteur haute par exemple: h depasse en haut
|
||||||
|
int textHeight = fm.getAscent();
|
||||||
|
// hauteur basse par exemple: g depasse en bas
|
||||||
|
int descent = fm.getDescent();
|
||||||
|
|
||||||
g.drawString(s, cx, cy);
|
int cx = x * cellWidth + (cellWidth - textWidth) / 2;
|
||||||
}
|
int cy = y * cellHeight + (cellHeight + textHeight - descent) / 2;
|
||||||
|
|
||||||
/**
|
g.drawString(s, cx, cy);
|
||||||
* Dessine un bloc intérieur plus petit, utilisé pour représenter une voiture
|
}
|
||||||
*/
|
|
||||||
private void drawInnerBlock(Graphics g, int[] coord, int[] cellCoord, Color c, int scale) {
|
|
||||||
// scale de la taille du bloc
|
|
||||||
int w = cellCoord[0] * scale / 100;
|
|
||||||
int h = cellCoord[1] * scale / 100;
|
|
||||||
|
|
||||||
// calcul de la position avec la nouvelle taille
|
/**
|
||||||
int ox = coord[0] * cellCoord[0] + (cellCoord[0] - w) / 2;
|
* Dessine un bloc intérieur plus petit, utilisé pour représenter une voiture
|
||||||
int oy = coord[1] * cellCoord[1] + (cellCoord[1] - h) / 2;
|
*/
|
||||||
|
private void drawInnerBlock(Graphics g, int[] coord, int[] cellCoord, Color c, int scale) {
|
||||||
|
// scale de la taille du bloc
|
||||||
|
int w = cellCoord[0] * scale / 100;
|
||||||
|
int h = cellCoord[1] * scale / 100;
|
||||||
|
|
||||||
// dessine le bloc plus petit
|
// calcul de la position avec la nouvelle taille
|
||||||
g.setColor(c);
|
int ox = coord[0] * cellCoord[0] + (cellCoord[0] - w) / 2;
|
||||||
g.fillRect(ox, oy, w, h);
|
int oy = coord[1] * cellCoord[1] + (cellCoord[1] - h) / 2;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// dessine le bloc plus petit
|
||||||
* Dessine une cellule de base selon son type et ajoute un contour noir.
|
g.setColor(c);
|
||||||
*/
|
g.fillRect(ox, oy, w, h);
|
||||||
private void drawBlock(Graphics g, Circuit cell, int[] coord, int[] cellCoord) {
|
}
|
||||||
int x = coord[0];
|
|
||||||
int y = coord[1];
|
|
||||||
|
|
||||||
int cellWidth = cellCoord[0];
|
/**
|
||||||
int cellHeight = cellCoord[1];
|
* Dessine une cellule de base selon son type et ajoute un contour noir.
|
||||||
|
*/
|
||||||
|
private void drawBlock(Graphics g, Circuit cell, int[] coord, int[] cellCoord) {
|
||||||
|
int x = coord[0];
|
||||||
|
int y = coord[1];
|
||||||
|
|
||||||
switch (cell.getType()) {
|
int cellWidth = cellCoord[0];
|
||||||
case YROAD:
|
int cellHeight = cellCoord[1];
|
||||||
// dessine le bloc de route
|
|
||||||
g.setColor(getCellColor(Circuit.Cell.ROAD));
|
|
||||||
g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
|
||||||
|
|
||||||
// dessine le sous bloc de route
|
|
||||||
drawInnerBlock(g, coord, cellCoord, getCellColor(cell.getType()), scale);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g.setColor(getCellColor(cell.getType()));
|
|
||||||
g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contour noir
|
switch (cell.getType()) {
|
||||||
g.setColor(Color.BLACK);
|
case YROAD:
|
||||||
g.drawRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
// dessine le bloc de route
|
||||||
}
|
g.setColor(getCellColor(Circuit.Cell.ROAD));
|
||||||
|
g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
||||||
|
|
||||||
/**
|
// dessine le sous bloc de route
|
||||||
* Méthode appelée automatiquement pour mettre à jour l'affichage.
|
drawInnerBlock(g, coord, cellCoord, getCellColor(cell.getType()), scale);
|
||||||
*/
|
break;
|
||||||
@Override
|
default:
|
||||||
public boolean apply()
|
g.setColor(getCellColor(cell.getType()));
|
||||||
{
|
g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
||||||
repaint();
|
break;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
// contour noir
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode appelée automatiquement pour mettre à jour l'affichage.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean apply() {
|
||||||
|
if (!super.apply()) {
|
||||||
|
System.out.println("ERREUR Track: game est null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
repaint();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user