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.

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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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