Pair Programming (bamba, david, vincent ) -fix grille + rotations

This commit is contained in:
Vincent 2024-10-25 22:22:11 +02:00
parent d5825ab8f5
commit 07515d748d
25 changed files with 252 additions and 206 deletions

BIN
bin/Music/Music/audio.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/controller/Point.class Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,36 +1,34 @@
package controller;
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
import java.awt.Point;
public class CameraController {
private Point mouseDragStart = null; // Stocke la position de départ du clic droit
private Point viewOffset = new Point(0, 0); // Stocke le décalage actuel de la vue
private JPanel gridPanel;
private Point mouseDragStart = null;
private GameContext context;
private JPanel gridPanel;
public CameraController(JPanel gridPanel, GameContext context) {
this.gridPanel = gridPanel;
this.context = context;
setupMouseDragToMove(); // Initialise les écouteurs pour gérer le déplacement
}
public Point getViewOffset() {
return viewOffset;
setupMouseDragToMove(gridPanel); // Initialise les écouteurs pour gérer le déplacement
}
public void updateViewOffset(int deltaX, int deltaY) {
viewOffset.translate(deltaX, deltaY);
gridPanel.setLocation(viewOffset);
// Met à jour uniquement l'offset dans GameContext
context.updateOffset(deltaX, deltaY);
// Repeindre la grille après mise à jour
context.repaintGrid(gridPanel);
// Debug : Affiche l'offset actuel
System.out.println("Nouvel offset dans GameContext : " + context.getOffset());
}
private void setupMouseDragToMove() {
MousePressHandler mousePressHandler = new MousePressHandler(this, context);
MouseDragHandler mouseDragHandler = new MouseDragHandler(this, context);
gridPanel.addMouseListener(mousePressHandler);
gridPanel.addMouseMotionListener(mouseDragHandler);
private void setupMouseDragToMove(JPanel gridPanel) {
gridPanel.addMouseListener(new MousePressHandler(this, context));
gridPanel.addMouseMotionListener(new MouseDragHandler(this, context));
}
public void setMouseDragStart(Point point) {
@ -45,7 +43,7 @@ public class CameraController {
this.mouseDragStart = null;
}
public JPanel getGridPanel() {
return gridPanel;
public Point getViewOffset() {
return context.getOffset();
}
}

@ -1,12 +1,12 @@
package controller;
import view.HexagonTile;
import java.awt.*;
import java.awt.Point;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.JPanel;
public class GameContext {
private Map<Point, HexagonTile> hexagonMap; // Stocke la grille
@ -36,4 +36,30 @@ public class GameContext {
public void updateOffset(int deltaX, int deltaY) {
offset.translate(deltaX, deltaY);
}
// Ajout de la méthode pour recalculer les positions de la grille en fonction de l'offset
public void repaintGrid(JPanel gridPanel) {
for (Map.Entry<Point, HexagonTile> entry : hexagonMap.entrySet()) {
Point position = entry.getKey();
HexagonTile tile = entry.getValue();
// Calcule la position avec l'offset
int xOffset = position.x * (int) (50 * 3 / 2); // Ajuste la distance horizontale
int yOffset = position.y * (int) (Math.sqrt(3) * 50); // Ajuste la distance verticale
// Si la colonne est impaire, décale la tuile d'une demi-hauteur d'hexagone
if (position.x % 2 != 0) {
yOffset += (int) (Math.sqrt(3) * 50 / 2);
}
// Applique l'offset de vue
xOffset += offset.x;
yOffset += offset.y;
// Met à jour la position de l'hexagone
tile.setBounds(xOffset, yOffset, 50, 50);
}
gridPanel.revalidate();
gridPanel.repaint();
}
}

@ -4,58 +4,120 @@ import model.Tile;
import view.HexagonTile;
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.HashSet;
import java.awt.Point;
import java.util.Map;
import java.util.Set;
public class GameController {
private Map<Point, HexagonTile> hexagonMap; // Carte pour stocker les tuiles par position
private Set<Point> availablePositions; // Ensemble pour suivre les positions disponibles
private Map<Point, HexagonTile> hexagonMap;
private Set<Point> availablePositions;
private JPanel gridPanel;
private Tile nextTile;
private HexagonTile nextTilePreview;
private GameContext gameContext;
public GameController(GameContext gameContext, JPanel gridPanel, Tile nextTile, HexagonTile nextTilePreview) {
this.gameContext = gameContext;
this.gridPanel = gridPanel;
this.hexagonMap = gameContext.getHexagonMap();
this.availablePositions = gameContext.getAvailablePositions();
this.nextTile = nextTile;
this.nextTilePreview = nextTilePreview;
// Initialiser hexagonMap et availablePositions
this.hexagonMap = new HashMap<>();
this.availablePositions = new HashSet<>();
// Mettre à jour la preview initiale
updatePreview();
}
public void placeTile(Point position) {
// Vérifier si la position est disponible
if (availablePositions.contains(position)) {
HexagonTile hexTile = hexagonMap.get(position);
if (hexTile == null) {
System.out.println("Erreur: hexTile est null à la position : " + position);
return;
}
// Assigner la tuile actuelle
hexTile.setTile(nextTile);
gridPanel.revalidate();
gridPanel.repaint();
// Retirer la position des positions disponibles
availablePositions.remove(position);
// Mettre à jour les positions adjacentes
Point[] adjacentPositions = getAdjacentPositions(position);
for (Point adj : adjacentPositions) {
if (!hexagonMap.containsKey(adj)) {
availablePositions.add(adj);
addHexagonTile(adj, gridPanel, 50, null, null); // Ajouter des placeholders
}
}
// Repeindre la grille
gameContext.repaintGrid(gridPanel);
// Générer une nouvelle tuile pour la prochaine preview
generateNextTile();
}
}
public void initializeGame(CameraController cameraController) {
Tile initialTile = generateRandomTile();
int centerX = gridPanel.getPreferredSize().width / 2;
int centerY = gridPanel.getPreferredSize().height / 2;
Point initialPosition = new Point(0, 0);
initialPosition.setLocation(centerX / 50, centerY / 50);
placeInitialTile(initialPosition, cameraController, initialTile);
// Générer la première tuile pour la preview
generateNextTile();
}
public void placeInitialTile(Point position, CameraController cameraController, Tile tile) {
// Place la première tuile pleine au point central
addHexagonTile(position, gridPanel, 50, cameraController, tile);
addHexagonTile(position, gridPanel, 50, cameraController, tile);
availablePositions.remove(position);
// Ajouter des placeholders autour de la première tuile
Point[] adjacentPositions = getAdjacentPositions(position);
for (Point adj : adjacentPositions) {
if (!hexagonMap.containsKey(adj)) {
availablePositions.add(adj);
addHexagonTile(adj, gridPanel, 50, cameraController, null); // Passer `null` pour les placeholders
addHexagonTile(adj, gridPanel, 50, cameraController, null);
}
}
}
public void addHexagonTile(Point position, JPanel panel, int hexSize, CameraController cameraController, Tile tile) {
if (position == null || panel == null) {
System.out.println("Erreur : position ou panel est null");
return;
}
int xOffset = position.x * (int) (hexSize * 3 / 2);
int yOffset = position.y * (int) (Math.sqrt(3) * hexSize);
Point viewOffset = cameraController.getViewOffset();
xOffset += viewOffset.x;
yOffset += viewOffset.y;
if (cameraController != null) {
Point viewOffset = cameraController.getViewOffset();
xOffset += viewOffset.x;
yOffset += viewOffset.y;
}
if (position.x % 2 != 0) {
yOffset += (int) (Math.sqrt(3) * hexSize / 2);
}
HexagonTile hexTile = new HexagonTile(position);
hexTile.setTile(tile); // Place la tuile fournie, ou null pour un placeholder
hexTile.setBounds(xOffset, yOffset, hexSize, hexSize);
if (tile != null) {
hexTile.setTile(tile);
} else {
System.out.println("Aucun tile n'a été fourni pour cette position : " + position);
}
// Ajout de l'écouteur pour gérer le clic sur l'hexagone
hexTile.addMouseListener(new HexagonMouseListener(hexTile, this, availablePositions, cameraController));
hexTile.setBounds(xOffset, yOffset, hexSize, hexSize);
hexTile.addMouseListener(new HexagonMouseListener(hexTile, this, availablePositions));
hexagonMap.put(position, hexTile);
panel.add(hexTile);
@ -63,14 +125,44 @@ public class GameController {
panel.repaint();
}
public void generateNextTile() {
// Génère une nouvelle tuile pour la prochaine pose
nextTile = new Tile();
updatePreview();
}
private void updatePreview() {
nextTilePreview.setTile(nextTile);
nextTilePreview.repaint();
}
private Point[] getAdjacentPositions(Point position) {
return new Point[]{
new Point(position.x + 1, position.y),
new Point(position.x - 1, position.y),
new Point(position.x, position.y + 1),
new Point(position.x, position.y - 1),
new Point(position.x + 1, position.y - 1),
new Point(position.x - 1, position.y + 1)
};
if (position.x % 2 == 0) {
return new Point[]{
new Point(position.x + 1, position.y),
new Point(position.x - 1, position.y),
new Point(position.x, position.y + 1),
new Point(position.x, position.y - 1),
new Point(position.x + 1, position.y - 1),
new Point(position.x - 1, position.y - 1)
};
} else {
return new Point[]{
new Point(position.x + 1, position.y),
new Point(position.x - 1, position.y),
new Point(position.x, position.y + 1),
new Point(position.x, position.y - 1),
new Point(position.x + 1, position.y + 1),
new Point(position.x - 1, position.y + 1)
};
}
}
private Tile generateRandomTile() {
return new Tile();
}
public Tile getNextTile() {
return nextTile;
}
}

@ -1,18 +1,19 @@
package controller;
import view.HexagonTile;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Point;
import java.util.Set;
public class HexagonMouseListener extends MouseAdapter {
private final HexagonTile hexTile;
private final GameController gameController;
private final Set<Point> availablePositions;
public HexagonMouseListener(HexagonTile hexTile, GameController gameController, Set<Point> availablePositions, CameraController cameraController) {
public HexagonMouseListener(HexagonTile hexTile, GameController gameController, Set<Point> availablePositions) {
this.hexTile = hexTile;
this.gameController = gameController;
this.availablePositions = availablePositions;
}
@ -21,8 +22,12 @@ public class HexagonMouseListener extends MouseAdapter {
Point position = hexTile.getPosition();
if (availablePositions.contains(position)) {
System.out.println("Hexagone cliqué à la position : " + position);
// Logique de placement de la tuile ou appel à GameController ici si nécessaire
// Par exemple, nous pourrions générer la tuile suivante directement ici
// Appeler le GameController pour placer une nouvelle tuile à cet emplacement
gameController.placeTile(position);
// Générer la prochaine tuile après avoir placé celle-ci
gameController.generateNextTile();
} else {
System.out.println("Position non disponible pour le placement");
}

@ -4,12 +4,8 @@ import view.*;
public class MenuController {
private MenuModel model;
private MenuView view;
public MenuController(MenuModel model, MenuView view) {
this.model = model;
this.view = view;
view.getResumeButton().addActionListener(new ResListener());
view.getNewGameButton().addActionListener(new NewListener());

@ -1,6 +1,5 @@
package controller;
import view.HexagonTile;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Point;
@ -9,11 +8,9 @@ import javax.swing.SwingUtilities;
public class MouseDragHandler extends MouseAdapter {
private CameraController controller;
private GameContext context;
public MouseDragHandler(CameraController controller, GameContext context) {
this.controller = controller;
this.context = context;
}
@Override
@ -23,18 +20,11 @@ public class MouseDragHandler extends MouseAdapter {
int deltaX = current.x - controller.getMouseDragStart().x;
int deltaY = current.y - controller.getMouseDragStart().y;
// Déplace chaque tuile dans le contexte de la grille
for (HexagonTile hexTile : context.getHexagonMap().values()) {
Point currentPos = hexTile.getLocation();
hexTile.setLocation(currentPos.x + deltaX, currentPos.y + deltaY);
}
// Déplacement dans CameraController
controller.updateViewOffset(deltaX, deltaY);
// Mettre à jour la position initiale pour le prochain déplacement
// Met à jour la position de départ
controller.setMouseDragStart(current);
// Rafraîchir la vue
controller.getGridPanel().revalidate();
controller.getGridPanel().repaint();
}
}

@ -0,0 +1,31 @@
package controller;
import model.Tile;
import view.HexagonTile;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
public class MouseWheelController implements MouseWheelListener {
private HexagonTile previewTile;
private GameController gameController;
public MouseWheelController(HexagonTile previewTile, GameController gameController) {
this.previewTile = previewTile;
this.gameController = gameController;
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
Tile nextTile = gameController.getNextTile();
if (e.getWheelRotation() < 0) {
nextTile.rotateClockwise();
} else if (e.getWheelRotation() > 0) {
nextTile.rotateClockwise();
}
previewTile.repaint(); // Mettre à jour l'aperçu avec la nouvelle rotation
}
}

@ -6,11 +6,23 @@ public class Tile {
private TerrainType[] terrains; // 2 terrains maximum par tuile
private int segmentsForTerrain1; // Nombre de segments pour le premier terrain
private static final Random random = new Random();
private int rotation;
public Tile() {
this.terrains = new TerrainType[2]; // Seulement deux terrains
generateTerrains();
assignSegments();
this.rotation = 0; // Rotation initiale à 0
}
// Méthode pour tourner la tuile dans le sens des aiguilles d'une montre
public void rotateClockwise() {
rotation = (rotation + 1) % 6; // Modulo 6 pour garder une rotation entre 0 et 5
}
// Méthode pour obtenir la rotation actuelle
public int getRotation() {
return rotation;
}
// Génère deux terrains aléatoires pour la tuile

@ -3,6 +3,7 @@ package view;
import controller.GameController;
import controller.CameraController;
import controller.GameContext;
import controller.MouseWheelController;
import model.Tile;
import javax.swing.*;
@ -10,8 +11,8 @@ import java.awt.*;
public class GameView extends JFrame {
private JPanel gridPanel;
private Tile nextTile;
private HexagonTile nextTilePreview;
private Tile nextTile; // Tuile en attente
private HexagonTile nextTilePreview; // Composant pour afficher la tuile en attente
private GameController gameController;
private CameraController cameraController;
private GameContext gameContext;
@ -34,48 +35,42 @@ public class GameView extends JFrame {
add(gridPanel, BorderLayout.CENTER);
// Créer le panneau de contrôle à droite
// Initialiser la tuile en attente et la preview
nextTile = new Tile();
nextTilePreview = new HexagonTile(null);
nextTilePreview.setTile(nextTile); // Lier nextTile à la preview
JPanel controlPanel = createControlPanel();
controlPanel.setPreferredSize(new Dimension(200, 600));
add(controlPanel, BorderLayout.EAST);
// Initialiser les contrôleurs avec le contexte de jeu
gameController = new GameController(gameContext, gridPanel, nextTile, nextTilePreview);
gameController = new GameController(gameContext, gridPanel, nextTile, nextTilePreview); // Passer nextTile et nextTilePreview
cameraController = new CameraController(gridPanel, gameContext);
// Générer une première tuile pleine et la placer au centre
placeInitialTileWithRandomTile();
// Ajouter un écouteur pour la molette de la souris
MouseWheelController wheelController = new MouseWheelController(nextTilePreview, gameController);
addMouseWheelListener(wheelController);
// Appeler l'initialisation du jeu
gameController.initializeGame(cameraController);
setVisible(true);
}
private JPanel createHexagonGrid() {
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setLayout(null); // Permet de placer des composants avec des coordonnées absolues
panel.setBackground(Color.WHITE);
panel.setPreferredSize(new Dimension(800, 800));
panel.setPreferredSize(new Dimension(800, 800)); // Peut être ajusté si nécessaire
return panel;
}
private void centerGridPanel() {
int gridX = (getWidth() - gridPanel.getPreferredSize().width) / 2;
int gridY = (getHeight() - gridPanel.getPreferredSize().height) / 2;
gridPanel.setLocation(gridX, gridY);
gameContext.updateOffset(gridX, gridY); // Mettre à jour l'offset dans GameContext
}
private Tile generateRandomTile() {
return new Tile(); // Génère une tuile aléatoire avec des caractéristiques définies dans Tile.java
}
private void placeInitialTileWithRandomTile() {
// Générer une première tuile pleine de manière aléatoire
Tile initialTile = generateRandomTile();
// Utiliser `placeInitialTile` pour placer cette tuile au centre de la grille
Point initialPosition = new Point(0, 0);
gameController.placeInitialTile(initialPosition, cameraController, initialTile);
int centerX = (getWidth() - gridPanel.getPreferredSize().width) / 2;
int centerY = (getHeight() - gridPanel.getPreferredSize().height) / 2;
gameContext.updateOffset(centerX, centerY);
gameContext.repaintGrid(gridPanel); // Rappel pour centrer initialement les tuiles
}
private JPanel createControlPanel() {
@ -87,7 +82,6 @@ public class GameView extends JFrame {
panel.add(new JLabel("Prochaine tuile : "));
panel.add(Box.createRigidArea(new Dimension(0, 10)));
nextTilePreview = new HexagonTile(null);
nextTilePreview.setPreferredSize(new Dimension(150, 150));
nextTilePreview.setBackground(Color.GRAY);
nextTilePreview.setOpaque(true);

@ -1,16 +0,0 @@
package view;
import javax.swing.*;
import java.awt.*;
public class HexagonGridPanel extends JPanel {
public HexagonGridPanel() {
super(null); // Layout null pour gérer manuellement la position des composants
}
@Override
public Dimension getPreferredSize() {
return new Dimension(3000, 3000);
}
}

@ -27,6 +27,10 @@ public class HexagonTile extends JPanel {
repaint();
}
public Tile getTile() {
return tile;
}
public boolean isFilled() {
return this.tile != null; // Vérifie si la tuile a déjà été placée
}
@ -45,8 +49,8 @@ public class HexagonTile extends JPanel {
g2d.setClip(largeHexagon);
if (tile != null) {
// Dessiner les 6 segments de terrain en fonction des proportions
drawTerrainSegments(g2d, centerX, centerY, largeRadius);
// Dessiner les 6 segments de terrain en fonction des proportions et de la rotation
drawTerrainSegments(g2d, centerX, centerY, largeRadius, tile.getRotation());
} else {
g2d.setColor(Color.LIGHT_GRAY); // Couleur par défaut pour une case vide
g2d.fill(largeHexagon);
@ -59,14 +63,12 @@ public class HexagonTile extends JPanel {
g2d.draw(largeHexagon);
}
// Dessiner les 6 segments de terrain avec une répartition variée
private void drawTerrainSegments(Graphics2D g2d, int centerX, int centerY, int radius) {
// Déterminer combien de segments sont attribués à chaque terrain
// Dessiner les 6 segments de terrain avec la rotation
private void drawTerrainSegments(Graphics2D g2d, int centerX, int centerY, int radius, int rotation) {
int segmentsTerrain1 = tile.getSegmentsForTerrain(0);
// Dessiner les segments adjacents pour chaque terrain
for (int i = 0; i < 6; i++) {
if (i < segmentsTerrain1) {
int segmentIndex = (i + rotation) % 6; // Appliquer la rotation aux segments
if (segmentIndex < segmentsTerrain1) {
g2d.setColor(getTerrainColor(tile.getTerrain(0))); // Premier terrain
} else {
g2d.setColor(getTerrainColor(tile.getTerrain(1))); // Deuxième terrain

@ -1,84 +0,0 @@
package view;
import model.Tile;
import model.TerrainType;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Path2D;
public class TileView extends JPanel {
private Tile tile;
public TileView(Tile tile) {
this.tile = tile;
setPreferredSize(new Dimension(100, 100));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
int largeRadius = 50;
// Créer la zone de découpe pour le grand hexagone
Shape largeHexagon = createHexagon(centerX, centerY, largeRadius);
g2d.setClip(largeHexagon);
// Diviser l'hexagone en 4 parties (quart de cercle) pour chaque terrain
drawTerrainQuadrants(g2d, centerX, centerY, largeRadius);
// Dessiner la bordure de l'hexagone
g2d.setClip(null);
g2d.setColor(Color.BLACK);
g2d.setStroke(new BasicStroke(3)); // Bordure épaisse
g2d.draw(largeHexagon);
}
// Dessiner les 4 quadrants de terrain
private void drawTerrainQuadrants(Graphics2D g2d, int centerX, int centerY, int radius) {
for (int i = 0; i < 4; i++) {
g2d.setColor(getTerrainColor(tile.getTerrain(i)));
g2d.fillArc(centerX - radius, centerY - radius, 2 * radius, 2 * radius, 90 * i, 90);
}
}
// Créer la forme hexagonale
private Shape createHexagon(int centerX, int centerY, int radius) {
Path2D hexagon = new Path2D.Double();
for (int i = 0; i < 6; i++) {
double angle = Math.toRadians(60 * i);
double x = centerX + radius * Math.cos(angle);
double y = centerY + radius * Math.sin(angle);
if (i == 0) {
hexagon.moveTo(x, y);
} else {
hexagon.lineTo(x, y);
}
}
hexagon.closePath();
return hexagon;
}
// Obtenir la couleur en fonction du type de terrain
private Color getTerrainColor(TerrainType terrain) {
switch (terrain) {
case MER:
return Color.BLUE;
case CHAMP:
return Color.YELLOW;
case PRE:
return Color.GREEN;
case FORET:
return new Color(34, 139, 34); // Vert foncé
case MONTAGNE:
return Color.GRAY;
default:
return Color.WHITE;
}
}
}