mirror of
https://github.com/guezoloic/racing-game.git
synced 2026-03-28 18:03:50 +00:00
feat: ajout Menu selection
This commit is contained in:
@@ -5,6 +5,7 @@ import model.car.BasicCar;
|
|||||||
import model.car.DrunkCar;
|
import model.car.DrunkCar;
|
||||||
import model.car.HybridCar;
|
import model.car.HybridCar;
|
||||||
import model.map.Map;
|
import model.map.Map;
|
||||||
|
import visual.SelectionView;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
@@ -21,14 +22,12 @@ public class Main {
|
|||||||
{ 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, 0, 0, 0, 0, 0 },
|
||||||
});
|
});
|
||||||
|
|
||||||
Game game = new Game.Builder()
|
SelectionView game = new SelectionView(3);
|
||||||
.car(new HybridCar(new BasicCar("Luwik", Color.RED)))
|
|
||||||
.car(new DrunkCar(new BasicCar("Charazade", Color.PINK)))
|
game.getGameBuilder()
|
||||||
.track("Piste Formule 1", 1000, 500, 1, 1)
|
.track("Piste Formule 1", 1000, 500, 1, 1)
|
||||||
.rankboard("Score", 200, 200, 0, 510)
|
.rankboard("Score", 200, 200, 0, 510)
|
||||||
.dashboards(300, 200, 1000, 0)
|
.dashboards(300, 200, 1000, 0)
|
||||||
.map(map)
|
.map(map);
|
||||||
.build();
|
|
||||||
game.run();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,19 +39,19 @@ public class Game {
|
|||||||
|
|
||||||
public Builder rankboard(String title, int width,
|
public Builder rankboard(String title, int width,
|
||||||
int height, int x, int y) {
|
int height, int x, int y) {
|
||||||
this.OBSERVERS.add(new Rankboard(null, title, width, height, x, y));
|
this.OBSERVERS.add(new RankboardView(null, title, width, height, x, y));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder track(String title, int width,
|
public Builder track(String title, int width,
|
||||||
int height, int x, int y) {
|
int height, int x, int y) {
|
||||||
this.OBSERVERS.add(new Track(null, title, width, height, x, y));
|
this.OBSERVERS.add(new TrackView(null, title, width, height, x, y));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dashboard(Car car, String title, int width,
|
public Builder dashboard(Car car, String title, int width,
|
||||||
int height, int x, int y) {
|
int height, int x, int y) {
|
||||||
this.OBSERVERS.add(new Dashboard(null, car, title, width, height, x, y));
|
this.OBSERVERS.add(new DashboardView(null, car, title, width, height, x, y));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class BasicCar implements Car {
|
|||||||
state = next;
|
state = next;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fait avancer la voiture d'un certain nombre de positions.
|
* Fait avancer la voiture d'un certain nombre de positions.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -130,73 +130,78 @@ public class BasicCar implements Car {
|
|||||||
* incrémenté et
|
* incrémenté et
|
||||||
* la position revient à zéro.
|
* la position revient à zéro.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param move nombre de positions à avancer
|
* @param move nombre de positions à avancer
|
||||||
* @return cette même instance (pour chaînage fluide)
|
* @return cette même instance (pour chaînage fluide)
|
||||||
*/
|
*/
|
||||||
private void move() {
|
private void move() {
|
||||||
int jump = RANDOM.nextInt(state.MIN, state.MAX);
|
int jump = RANDOM.nextInt(state.MIN, state.MAX);
|
||||||
|
|
||||||
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)) {
|
||||||
setDamage();
|
setDamage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
round = pos / map.getPathSize();
|
round = pos / map.getPathSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasAccident(Circuit element, int jump) {
|
private boolean hasAccident(Circuit element, int jump) {
|
||||||
return element.isYRoad() && element.getValue() <= jump;
|
return element.isYRoad() && element.getValue() <= jump;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consomme du carburant en fonction de l'état du jeu.
|
* Consomme du carburant en fonction de l'état du jeu.
|
||||||
*
|
*
|
||||||
* @return cette même instance pour chaînage
|
* @return cette même instance pour chaînage
|
||||||
*/
|
*/
|
||||||
public void consumeFuel() {
|
public void consumeFuel() {
|
||||||
fuel = state.fuelConsumption(fuel);
|
fuel = state.fuelConsumption(fuel);
|
||||||
if (fuel < 0)
|
if (fuel < 0)
|
||||||
fuel = 0; // sécurité
|
fuel = 0; // sécurité
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFinished() {
|
public boolean hasFinished() {
|
||||||
return 3 < round;
|
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.
|
||||||
* <p>
|
* <p>
|
||||||
* La progression est déterminée par un intervalle aléatoire fourni par l'état
|
* La progression est déterminée par un intervalle aléatoire fourni par l'état
|
||||||
* du jeu.
|
* du jeu.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean apply() {
|
public boolean apply() {
|
||||||
if (state.isDamaged()) {
|
if (state.isDamaged()) {
|
||||||
decreaseDamage();
|
decreaseDamage();
|
||||||
} else if (fuel > 0) {
|
} else if (fuel > 0) {
|
||||||
move();
|
move();
|
||||||
if (isConsuming)
|
if (isConsuming)
|
||||||
consumeFuel();
|
consumeFuel();
|
||||||
}
|
|
||||||
return !hasFinished();
|
|
||||||
}
|
}
|
||||||
|
return !hasFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumption(boolean active) {
|
||||||
|
isConsuming = active;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void consumption(boolean active) {
|
public Car remove() {
|
||||||
isConsuming = active;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reverse(boolean active) {
|
public void reverse(boolean active) {
|
||||||
movement = (active) ? -1 : 1;
|
movement = (active) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,18 +13,21 @@ public interface Car extends Observer {
|
|||||||
public void reverse(boolean active);
|
public void reverse(boolean active);
|
||||||
|
|
||||||
public void consumption(boolean active);
|
public void consumption(boolean active);
|
||||||
|
|
||||||
|
public Car remove();
|
||||||
|
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
public int getPosition();
|
public int getPosition();
|
||||||
|
|
||||||
public int getScore();
|
public int getScore();
|
||||||
|
|
||||||
public int getRound();
|
public int getRound();
|
||||||
|
|
||||||
public int getFuel();
|
public int getFuel();
|
||||||
|
|
||||||
public State getState();
|
public State getState();
|
||||||
|
|
||||||
public Color getColor();
|
public Color getColor();
|
||||||
|
|
||||||
public void setMap(Map map);
|
public void setMap(Map map);
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ public abstract class CarDecorator implements Car {
|
|||||||
this.car = car;
|
this.car = car;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Car remove() {
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String accelerate() {
|
public String accelerate() {
|
||||||
return car.accelerate();
|
return car.accelerate();
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package model.car;
|
package model.car;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DrunkCar = décorateur "pilote ivre".
|
* DrunkCar = décorateur "pilote ivre".
|
||||||
*
|
*
|
||||||
@@ -14,8 +12,7 @@ import java.util.Random;
|
|||||||
* sans modifier la classe Car.
|
* sans modifier la classe Car.
|
||||||
*/
|
*/
|
||||||
public class DrunkCar extends CarDecorator {
|
public class DrunkCar extends CarDecorator {
|
||||||
/** Générateur de nombres aléatoires pour simuler la progression */
|
private boolean reverse = false;
|
||||||
protected static final Random RANDOM = new Random();
|
|
||||||
|
|
||||||
public DrunkCar(Car car) {
|
public DrunkCar(Car car) {
|
||||||
super(car);
|
super(car);
|
||||||
@@ -25,9 +22,9 @@ public class DrunkCar extends CarDecorator {
|
|||||||
// 50% : fait l'inverse
|
// 50% : fait l'inverse
|
||||||
@Override
|
@Override
|
||||||
public boolean apply() {
|
public boolean apply() {
|
||||||
car.reverse(RANDOM.nextBoolean());
|
car.reverse(reverse);
|
||||||
car.apply();
|
car.apply();
|
||||||
car.reverse(false);
|
reverse = !reverse;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
80
src/model/car/Selection.java
Normal file
80
src/model/car/Selection.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package model.car;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import model.Game;
|
||||||
|
|
||||||
|
public class Selection {
|
||||||
|
private final Game.Builder gameBuilder;
|
||||||
|
private final List<Car> cars = new ArrayList<>();
|
||||||
|
|
||||||
|
public Selection(Game.Builder gameBuilder) {
|
||||||
|
this.gameBuilder = gameBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Car> getCars() {
|
||||||
|
return new ArrayList<>(cars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car addCar(String name, Color color) {
|
||||||
|
Car car = new BasicCar(name, color);
|
||||||
|
cars.add(car);
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeCar(Car car) {
|
||||||
|
cars.remove(car);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Car addDecorator(Function<Car, Car> fn, Car car) throws IllegalArgumentException {
|
||||||
|
int index = cars.indexOf(car);
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Aucune voiture dans la classe interne.");
|
||||||
|
}
|
||||||
|
|
||||||
|
car = fn.apply(car);
|
||||||
|
cars.set(index, car);
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car addHybridCarDecorator(Car car) throws IllegalArgumentException {
|
||||||
|
return addDecorator(HybridCar::new, car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car addDrunkCarDecorator(Car car) throws IllegalArgumentException {
|
||||||
|
return addDecorator(DrunkCar::new, car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car addBoostCarDecorator(Car car) throws IllegalArgumentException {
|
||||||
|
return addDecorator(BoostCar::new, car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Car removeDecorator(Car car) throws IllegalArgumentException {
|
||||||
|
int index = cars.indexOf(car);
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Aucune voiture dans la classe interne.");
|
||||||
|
}
|
||||||
|
car = car.remove();
|
||||||
|
cars.set(index, car);
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game.Builder select() {
|
||||||
|
for (Car car : cars) {
|
||||||
|
gameBuilder.car(car);
|
||||||
|
System.out.println("hello world");
|
||||||
|
}
|
||||||
|
return gameBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return cars.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ import model.car.HybridCar;
|
|||||||
* - un bouton Accelerer
|
* - un bouton Accelerer
|
||||||
* - un bouton Rallentir
|
* - un bouton Rallentir
|
||||||
*/
|
*/
|
||||||
public class Dashboard extends GameView {
|
public class DashboardView extends GameView {
|
||||||
|
|
||||||
/** Label affichant carburant et nombre de tours */
|
/** Label affichant carburant et nombre de tours */
|
||||||
private final JLabel infoLabel = new JLabel();
|
private final JLabel infoLabel = new JLabel();
|
||||||
@@ -58,7 +58,7 @@ 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, Car car, String title, int width, int height, int x, int y) {
|
public DashboardView(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;
|
||||||
|
|
||||||
@@ -66,7 +66,8 @@ public abstract class GameView extends JComponent implements Game.Observer {
|
|||||||
// mettre un layout (la disposition des elements de la fenetre)
|
// mettre un layout (la disposition des elements de la fenetre)
|
||||||
frame.setLayout(new BorderLayout());
|
frame.setLayout(new BorderLayout());
|
||||||
|
|
||||||
game.addObserver(this);
|
if (game != null)
|
||||||
|
game.addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GameView(Game game, String title, int width, int height, int x, int y) {
|
protected GameView(Game game, String title, int width, int height, int x, int y) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import model.car.Car;
|
|||||||
* Les scores sont triés du plus grand au plus petit.
|
* Les scores sont triés du plus grand au plus petit.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class Rankboard extends GameView {
|
public class RankboardView extends GameView {
|
||||||
/** Liste des voitures à afficher */
|
/** Liste des voitures à afficher */
|
||||||
List<Car> cars;
|
List<Car> cars;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public class Rankboard 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 Rankboard(Game game, String title, int width, int height, int x, int y) {
|
public RankboardView(Game game, String title, int width, int height, int x, int y) {
|
||||||
super(game, title, width, height, x, y);
|
super(game, title, width, height, x, y);
|
||||||
if (game != null)
|
if (game != null)
|
||||||
init(game);
|
init(game);
|
||||||
84
src/visual/SelectionView.java
Normal file
84
src/visual/SelectionView.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package visual;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import model.Game;
|
||||||
|
import model.car.Car;
|
||||||
|
import model.car.Selection;
|
||||||
|
|
||||||
|
public class SelectionView extends GameView {
|
||||||
|
private Game.Builder gameBuilder = new Game.Builder();
|
||||||
|
private Selection selection = new Selection(gameBuilder);
|
||||||
|
private JPanel buttonPanel = new JPanel();
|
||||||
|
|
||||||
|
public Game.Builder getGameBuilder() {
|
||||||
|
return gameBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectionView(int ncar) {
|
||||||
|
super(null, "Menu de sélection", 500, 300, 400, 400);
|
||||||
|
init(null); // forcer le init
|
||||||
|
|
||||||
|
buttonPanel.setLayout(new GridLayout(0, 3, 5, 5));
|
||||||
|
frame.add(buttonPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
for (int i = 1; i <= ncar; i++) {
|
||||||
|
Car car = selection.addCar("Car " + i, Color.getHSBColor(i / 3f, 0.8f, 0.8f));
|
||||||
|
// bouton Hybrid
|
||||||
|
JButton hybridBtn = new JButton("Hybrid " + car.getName());
|
||||||
|
// bouton Drunk
|
||||||
|
JButton drunkBtn = new JButton("Drunk " + car.getName());
|
||||||
|
// bouton boost
|
||||||
|
JButton boostBtn = new JButton("Boost " + car.getName());
|
||||||
|
|
||||||
|
final int I = i;
|
||||||
|
hybridBtn.addActionListener((ActionEvent e) -> {
|
||||||
|
try {
|
||||||
|
Car current = selection.getCars().get(I-1);
|
||||||
|
selection.addHybridCarDecorator(current);
|
||||||
|
hybridBtn.setEnabled(false);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
drunkBtn.addActionListener((ActionEvent e) -> {
|
||||||
|
try {
|
||||||
|
Car current = selection.getCars().get(I-1);
|
||||||
|
selection.addDrunkCarDecorator(current);
|
||||||
|
drunkBtn.setEnabled(false);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
boostBtn.addActionListener((ActionEvent e) -> {
|
||||||
|
try {
|
||||||
|
Car current = selection.getCars().get(I-1);
|
||||||
|
selection.addBoostCarDecorator(current);
|
||||||
|
boostBtn.setEnabled(false);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonPanel.add(hybridBtn);
|
||||||
|
buttonPanel.add(drunkBtn);
|
||||||
|
buttonPanel.add(boostBtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
JButton startBtn = new JButton("Start");
|
||||||
|
startBtn.addActionListener((ActionEvent e) -> {
|
||||||
|
frame.dispose();
|
||||||
|
new Thread(() -> selection.select().build().run()).start();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.frame.add(startBtn, BorderLayout.SOUTH);
|
||||||
|
frame.revalidate();
|
||||||
|
frame.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import model.map.Map;
|
|||||||
* 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 TrackView extends GameView {
|
||||||
/** La carte du circuit */
|
/** La carte du circuit */
|
||||||
private Map map;
|
private Map map;
|
||||||
/** Liste des voitures à dessiner */
|
/** Liste des voitures à dessiner */
|
||||||
@@ -49,7 +49,7 @@ public class Track extends GameView {
|
|||||||
* @param x Position X de la fenêtre
|
* @param x Position X de la fenêtre
|
||||||
* @param y Position Y 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) {
|
public TrackView(Game game, String title, int width, int height, int x, int y) {
|
||||||
super(game, title, width, height, x, y);
|
super(game, title, width, height, x, y);
|
||||||
if (game != null)
|
if (game != null)
|
||||||
init(game);
|
init(game);
|
||||||
Reference in New Issue
Block a user