From 588dd4af3286654bf6e11c4d0f35c8b1ac7db346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20GUEZO?= Date: Sun, 9 Nov 2025 12:12:30 +0100 Subject: [PATCH] feat: ajout GameView et Track --- src/GameView.java | 16 ++--- src/Track.java | 163 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 169 insertions(+), 10 deletions(-) diff --git a/src/GameView.java b/src/GameView.java index 335e8e3..e7522d2 100644 --- a/src/GameView.java +++ b/src/GameView.java @@ -1,32 +1,32 @@ import java.awt.Container; +import java.awt.Graphics; import java.util.ArrayList; +import javax.swing.JComponent; import javax.swing.JFrame; -public abstract class GameView extends JFrame +public abstract class GameView extends JComponent { private static ArrayList vobs = new ArrayList<>(); - protected Container window; + protected final JFrame frame; protected GameView(String title, int width, int height, int x, int y) { // la fenetre - JFrame frame = new JFrame(title); + this.frame = new JFrame(title); // position fenetre frame.setLocation(x, y); // taille fenetre frame.setSize(width, height); // bool pour resize la fenetre - frame.setResizable(false); + frame.setResizable(true); // le bouton close par defaut frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // acceder a l'interieur de la fenetre + frame.setContentPane(this); // visibilité de la fenetre frame.setVisible(true); - - // acceder a l'interieur de la fenetre - window = frame.getContentPane(); - register(); } protected GameView register() diff --git a/src/Track.java b/src/Track.java index f193251..e1770c0 100644 --- a/src/Track.java +++ b/src/Track.java @@ -1,3 +1,162 @@ -public class Track { - +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; + +public class Track extends GameView { + private Map map; + private Car[] cars; + + private final int scale = 75; + + protected Track(Map map, Car[] cars, String title, int width, int height, int x, int y) { + super(title, width, height, x, y); + this.map = map; + this.cars = cars; + register(); + } + + @Override + protected void paintComponent(Graphics g) + { + super.paintComponent(g); + + int rows = map.getHeight(); + int cols = map.getWidth(); + + int[] cellSize = new int[] { + (getWidth() + 10) / cols, // width + (getHeight() + 10) / rows // height + }; + + // Caractere bold de la taille de la longueur de l'ecran /2 + g.setFont(new Font("Monospaced", Font.BOLD, cellSize[1] / 2)); + + for (int y = 0; y < rows; y++) + { + for (int x = 0; x < cols; x++) + { + Circuit cell = this.map.getElement(x, y); + drawCell(g, cell, new int[] {x, y}, cellSize); + } + } + } + + private Color getCellColor(Circuit.Cell cell) + { + return switch (cell) { + case ROAD -> Color.GRAY; + case START -> Color.YELLOW; + case FINISH -> Color.YELLOW; + case EMPTY -> Color.GREEN; + case YROAD -> Color.YELLOW; + }; + } + + private char getCellChar(Circuit cell) + { + return switch (cell.getType()) { + case Circuit.Cell.ROAD -> '\0'; + case Circuit.Cell.START -> 'D'; + case Circuit.Cell.FINISH -> 'A'; + case Circuit.Cell.EMPTY -> '\0'; + case Circuit.Cell.YROAD -> (char)('0' + cell.getValue()); + }; + } + + private void drawCars(Graphics g, int[] cellCoord) + { + for (Car c : cars) + { + // index de pathMap + int i = c.getPos(); + Point p = this.map.getPath(i); + int[] ncoord = new int[] {p.x, p.y}; + drawInnerBlock(g, ncoord, cellCoord, c.getColor()); + } + } + + private void drawCell(Graphics g, Circuit cell, int[] coord, int[] cellCoord) + { + drawBlock(g, cell, coord, cellCoord); + + char c = getCellChar(cell); + if (c != '\0') + drawCharacter(g, coord, cellCoord, c); + + drawCars(g, cellCoord); + } + + 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]; + + String s = c + ""; + g.setColor(Color.BLACK); + + FontMetrics fm = g.getFontMetrics(); + + // 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(); + + int cx = x * cellWidth + (cellWidth - textWidth) / 2; + int cy = y * cellHeight + (cellHeight + textHeight - descent) / 2; + + g.drawString(s, cx, cy); + } + + private void drawInnerBlock(Graphics g, int[] coord, int[] cellCoord, Color c) + { + // 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; + int oy = coord[1] * cellCoord[1] + (cellCoord[1] - h) / 2; + + // dessine le bloc plus petit + 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]; + + switch (cell.getType()) { + case YROAD: + // dessine le bloc de route + g.setColor(getCellColor(Circuit.Cell.ROAD)); + g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight); + + drawInnerBlock(g, coord, cellCoord, getCellColor(cell.getType())); + break; + default: + g.setColor(getCellColor(cell.getType())); + g.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight); + break; + } + + g.setColor(Color.BLACK); + g.drawRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight); + } + + @Override + protected void run() + { + repaint(); + } + }