resolution bug score dans le mode 1 mais bug dans le mode 2,3 et 4
This commit is contained in:
BIN
TestV1/src/fr/monkhanny/dorfromantik/game/.DS_Store
vendored
Normal file
BIN
TestV1/src/fr/monkhanny/dorfromantik/game/.DS_Store
vendored
Normal file
Binary file not shown.
24
TestV1/src/fr/monkhanny/dorfromantik/game/BiomeGroup.java
Normal file
24
TestV1/src/fr/monkhanny/dorfromantik/game/BiomeGroup.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Représente un groupe de poches pour un biome spécifique.
|
||||
*/
|
||||
public class BiomeGroup {
|
||||
private final List<Pocket> pockets;
|
||||
|
||||
public BiomeGroup() {
|
||||
this.pockets = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<Pocket> getPockets() {
|
||||
return pockets;
|
||||
}
|
||||
|
||||
public void addPocket(Pocket pocket) {
|
||||
pockets.add(pocket);
|
||||
}
|
||||
}
|
||||
|
505
TestV1/src/fr/monkhanny/dorfromantik/game/Board.java
Normal file
505
TestV1/src/fr/monkhanny/dorfromantik/game/Board.java
Normal file
File diff suppressed because it is too large
Load Diff
110
TestV1/src/fr/monkhanny/dorfromantik/game/Cell.java
Normal file
110
TestV1/src/fr/monkhanny/dorfromantik/game/Cell.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Représente une cellule de base sur le plateau de jeu.
|
||||
* C'est la classe parente pour la classe Tile.
|
||||
*/
|
||||
public class Cell extends JComponent {
|
||||
private Board board; // Le plateau de jeu auquel cette cellule appartient
|
||||
public int x; // Coordonnée x du centre de la cellule
|
||||
public int y; // Coordonnée y du centre de la cellule
|
||||
public int radius; // Rayon de la cellule (si on parle d'un hexagone, c'est le rayon de l'hexagone)
|
||||
|
||||
/**
|
||||
* Constructeur de la classe Cell.
|
||||
*
|
||||
* @param board Le plateau de jeu auquel cette cellule appartient
|
||||
* @param x La coordonnée x du centre de la cellule
|
||||
* @param y La coordonnée y du centre de la cellule
|
||||
* @param radius Le rayon de la cellule
|
||||
*/
|
||||
public Cell(Board board, int x, int y, int radius) {
|
||||
this.board = board;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.radius = radius;
|
||||
|
||||
// Définir la taille du composant pour l'affichage
|
||||
this.setSize(2 * radius, 2 * radius);
|
||||
this.setLocation(x - radius, y - radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le plateau de jeu auquel cette cellule appartient.
|
||||
*
|
||||
* @return Le plateau de jeu
|
||||
*/
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la coordonnée x du centre de la cellule.
|
||||
*
|
||||
* @return La coordonnée x
|
||||
*/
|
||||
public int getXCoord() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la coordonnée y du centre de la cellule.
|
||||
*
|
||||
* @return La coordonnée y
|
||||
*/
|
||||
public int getYCoord() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le rayon de la cellule.
|
||||
*
|
||||
* @return Le rayon de la cellule
|
||||
*/
|
||||
public int getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit une coordonnée en degrés en une valeur de 0 à 360.
|
||||
*
|
||||
* @param angle L'angle en degrés
|
||||
* @return La valeur normalisée entre 0 et 360 degrés
|
||||
*/
|
||||
public static double to360Degrees(double angle) {
|
||||
angle = angle % 360;
|
||||
if (angle < 0) {
|
||||
angle += 360;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permet de changer la position de la cellule.
|
||||
* Cette méthode met à jour les coordonnées x et y et déplace la cellule dans le composant graphique.
|
||||
*
|
||||
* @param x La nouvelle coordonnée x du centre de la cellule
|
||||
* @param y La nouvelle coordonnée y du centre de la cellule
|
||||
*/
|
||||
public void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// Mettre à jour la position de la cellule sur le plateau
|
||||
this.setLocation(x - radius, y - radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Méthode pour redessiner la cellule si nécessaire.
|
||||
* Elle sera surchargée par les classes dérivées comme Tile.
|
||||
*
|
||||
* @param g Le contexte graphique
|
||||
*/
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
27
TestV1/src/fr/monkhanny/dorfromantik/game/Game.java
Normal file
27
TestV1/src/fr/monkhanny/dorfromantik/game/Game.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Représente un objet de jeu qui gère les fonctionnalités générales.
|
||||
*/
|
||||
public class Game {
|
||||
private Random random;
|
||||
|
||||
// Nouveau constructeur qui accepte un seed
|
||||
public Game(long seed) {
|
||||
this.random = new Random(seed);
|
||||
}
|
||||
|
||||
// Constructeur par défaut pour conserver la flexibilité
|
||||
public Game() {
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
public int getRandomInt(int max) {
|
||||
return random.nextInt(max);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
226
TestV1/src/fr/monkhanny/dorfromantik/game/GameOver.java
Normal file
226
TestV1/src/fr/monkhanny/dorfromantik/game/GameOver.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import fr.monkhanny.dorfromantik.utils.Database;
|
||||
import fr.monkhanny.dorfromantik.gui.MainMenu;
|
||||
import fr.monkhanny.dorfromantik.Main;
|
||||
import fr.monkhanny.dorfromantik.Options;
|
||||
import fr.monkhanny.dorfromantik.enums.Fonts;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class GameOver extends JPanel {
|
||||
private JFrame gameFrame;
|
||||
private int finalScore;
|
||||
private Database database;
|
||||
private MainMenu mainMenu;
|
||||
|
||||
public GameOver(JFrame gameFrame, int finalScore, Database database, MainMenu mainMenu) {
|
||||
this.gameFrame = gameFrame;
|
||||
this.mainMenu = mainMenu;
|
||||
this.finalScore = finalScore;
|
||||
this.database = database;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
// Background image setup
|
||||
JLabel background = new JLabel(new ImageIcon("./ressources/images/MainMenu/backgroundBlured.jpg"));
|
||||
background.setLayout(new BorderLayout());
|
||||
this.add(background, BorderLayout.CENTER);
|
||||
|
||||
// Main content panel
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
||||
mainPanel.setOpaque(false);
|
||||
background.add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
// Title for the Game Over message
|
||||
JLabel titleLabel = new JLabel("Partie terminée !");
|
||||
titleLabel.setFont(Fonts.TITLE.getFont(48)); // Using the TITLE font
|
||||
titleLabel.setForeground(Color.WHITE);
|
||||
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
mainPanel.add(titleLabel);
|
||||
|
||||
// Spacer
|
||||
mainPanel.add(Box.createVerticalStrut(30));
|
||||
|
||||
// Display the final score
|
||||
JLabel scoreLabel = new JLabel("Votre score est de : " + finalScore);
|
||||
scoreLabel.setFont(Fonts.SCORE.getFont(36)); // Using the SCORE font
|
||||
scoreLabel.setForeground(Color.WHITE);
|
||||
scoreLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
scoreLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); // Padding
|
||||
scoreLabel.setOpaque(true);
|
||||
scoreLabel.setBackground(new Color(0, 0, 0, 100)); // Background color with transparency
|
||||
mainPanel.add(scoreLabel);
|
||||
|
||||
// Spacer
|
||||
mainPanel.add(Box.createVerticalStrut(30));
|
||||
|
||||
// Grouping information and funny quote
|
||||
try {
|
||||
long seriesId = Options.SEED; // Get the correct seriesId
|
||||
List<Integer> allScores = database.getScoresBySeriesId(seriesId);
|
||||
|
||||
// Calculate the groups
|
||||
int totalPlayers = allScores.size();
|
||||
int groupSize = totalPlayers / 10;
|
||||
int playerGroup = 0;
|
||||
|
||||
// Check if there are less than 20 players
|
||||
String funnyQuote;
|
||||
if (totalPlayers < 20) {
|
||||
// Only show the funny quote if there are less than 20 players
|
||||
funnyQuote = "Vous n'êtes que " + totalPlayers + " à avoir joué à cette partie personalisée...";
|
||||
// Display the funny quote directly
|
||||
JLabel quoteLabel = new JLabel(funnyQuote);
|
||||
quoteLabel.setFont(Fonts.SCORE.getFont(24));
|
||||
quoteLabel.setForeground(Color.WHITE);
|
||||
quoteLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
mainPanel.add(quoteLabel);
|
||||
} else {
|
||||
// Calculate which group the player's score falls into
|
||||
for (int i = 0; i < totalPlayers; i++) {
|
||||
if (allScores.get(i) <= finalScore) {
|
||||
playerGroup = i / groupSize + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Group information
|
||||
JPanel groupPanel = new JPanel();
|
||||
groupPanel.setOpaque(false);
|
||||
groupPanel.setLayout(new BoxLayout(groupPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
JLabel groupTitleLabel = new JLabel("Vous êtes dans le groupe " + playerGroup + "/10 !");
|
||||
groupTitleLabel.setFont(Fonts.SCORE.getFont(24));
|
||||
groupTitleLabel.setForeground(Color.WHITE);
|
||||
groupTitleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
groupPanel.add(groupTitleLabel);
|
||||
|
||||
JLabel groupSizeLabel = new JLabel("Il y a " + groupSize + " joueurs dans ce groupe.");
|
||||
groupSizeLabel.setFont(Fonts.SCORE.getFont(24));
|
||||
groupSizeLabel.setForeground(Color.WHITE);
|
||||
groupSizeLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
groupPanel.add(groupSizeLabel);
|
||||
|
||||
// Show a funny quote based on the group
|
||||
funnyQuote = getFunnyQuote(playerGroup);
|
||||
JLabel quoteLabel = new JLabel(funnyQuote);
|
||||
quoteLabel.setFont(Fonts.SCORE.getFont(24));
|
||||
quoteLabel.setForeground(Color.WHITE);
|
||||
quoteLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
groupPanel.add(quoteLabel);
|
||||
|
||||
// Add group information panel
|
||||
mainPanel.add(groupPanel);
|
||||
|
||||
// Spacer
|
||||
mainPanel.add(Box.createVerticalStrut(30));
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Input panel for username and submission
|
||||
JPanel inputPanel = createInputPanel();
|
||||
mainPanel.add(inputPanel);
|
||||
|
||||
// Spacer
|
||||
mainPanel.add(Box.createVerticalStrut(30));
|
||||
}
|
||||
|
||||
|
||||
private String getFunnyQuote(int playerGroup) {
|
||||
// A list of funny and motivational quotes based on the group
|
||||
switch (playerGroup) {
|
||||
case 1: return "Vous êtes officiellement un génie ! Peut-être même un super-héros...!";
|
||||
case 2: return "Pas mal ! Mais attention, le groupe 1 vous attend avec des applaudissements !";
|
||||
case 3: return "Vous êtes sur la bonne voie, mais vous avez encore un peu de chemin à parcourir !";
|
||||
case 4: return "Il est encore temps d'appeler un coach... ou un ami pour vous aider !";
|
||||
case 5: return "Vous êtes dans la bonne direction, mais votre GPS semble un peu perdu !";
|
||||
case 6: return "Vous n'êtes pas loin du sommet, mais le sommet semble être dans un autre pays !";
|
||||
case 7: return "C'est un bon début ! Peut-être qu'un peu de café améliorerait encore la situation ?!";
|
||||
case 8: return "Sur le chemin de la gloire, mais vous êtes encore coincé dans les bouchons...";
|
||||
case 9: return "Pas de panique, il y a encore de la place pour s'améliorer... à peu près toute la place.";
|
||||
case 10: return "Félicitations ! Mais peut-être que vous voudriez réessayer sans les lunettes de soleil ?";
|
||||
default: return "Hé, on progresse ! Peut-être qu'un jour, vous dominerez le monde... ou du moins ce jeu !";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private JPanel createInputPanel() {
|
||||
JPanel inputPanel = new JPanel();
|
||||
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
|
||||
inputPanel.setOpaque(false);
|
||||
|
||||
// Username label and text field
|
||||
JPanel namePanel = new JPanel();
|
||||
namePanel.setOpaque(false);
|
||||
JLabel nameLabel = new JLabel("Entrez votre pseudo :");
|
||||
nameLabel.setForeground(Color.WHITE);
|
||||
nameLabel.setFont(Fonts.SCORE.getFont(24));
|
||||
namePanel.add(nameLabel);
|
||||
|
||||
JTextField nameField = new JTextField(20);
|
||||
nameField.setFont(Fonts.SCORE.getFont(18));
|
||||
nameField.setPreferredSize(new Dimension(250, 40));
|
||||
nameField.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
|
||||
nameField.setText("Anonyme");
|
||||
namePanel.add(nameField);
|
||||
|
||||
inputPanel.add(namePanel);
|
||||
|
||||
// Spacer between name field and button
|
||||
inputPanel.add(Box.createVerticalStrut(20));
|
||||
|
||||
// Add flexible space at the bottom to push the button down
|
||||
inputPanel.add(Box.createVerticalGlue());
|
||||
|
||||
// Submit button
|
||||
JButton submitButton = new JButton("Soumettre");
|
||||
submitButton.setFont(Fonts.BUTTON.getFont(24)); // Using the BUTTON font
|
||||
submitButton.setBackground(new Color(0, 255, 0));
|
||||
submitButton.setForeground(Color.WHITE);
|
||||
submitButton.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
|
||||
submitButton.setPreferredSize(new Dimension(150, 50));
|
||||
|
||||
// Center the button horizontally using BoxLayout
|
||||
submitButton.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
inputPanel.add(submitButton);
|
||||
|
||||
// Action to handle score submission
|
||||
submitButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String username = nameField.getText().trim();
|
||||
if (username.isEmpty()) {
|
||||
username = "Anonyme"; // Default to "Anonyme" if no name is given
|
||||
}
|
||||
|
||||
// Save the score to the database
|
||||
try {
|
||||
long seriesId = Options.SEED; // Replace with the appropriate series ID
|
||||
database.addScore(username, seriesId, finalScore);
|
||||
|
||||
// Débloquer les récompenses pour ce joueur
|
||||
database.unlockRewards(username, finalScore);
|
||||
|
||||
JOptionPane.showMessageDialog(gameFrame, "Score enregistré et récompenses débloquées !");
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(gameFrame, "Erreur lors de l'enregistrement du score : " + ex.getMessage());
|
||||
}
|
||||
|
||||
// Fermer la fenêtre de jeu
|
||||
Main.resetGame();
|
||||
}
|
||||
});
|
||||
return inputPanel;
|
||||
}
|
||||
|
||||
}
|
33
TestV1/src/fr/monkhanny/dorfromantik/game/Pocket.java
Normal file
33
TestV1/src/fr/monkhanny/dorfromantik/game/Pocket.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import fr.monkhanny.dorfromantik.enums.Biome;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Représente une poche de tuiles connectées pour un terrain donné.
|
||||
*/
|
||||
public class Pocket {
|
||||
private final Biome biome;
|
||||
private final Set<Tile> tiles;
|
||||
|
||||
public Pocket(Biome biome) {
|
||||
this.biome = biome;
|
||||
this.tiles = new HashSet<>();
|
||||
}
|
||||
|
||||
public Biome getBiome() {
|
||||
return biome;
|
||||
}
|
||||
|
||||
public Set<Tile> getTiles() {
|
||||
return tiles;
|
||||
}
|
||||
|
||||
public void addTile(Tile tile) {
|
||||
tiles.add(tile);
|
||||
}
|
||||
}
|
47
TestV1/src/fr/monkhanny/dorfromantik/game/ScoreManager.java
Normal file
47
TestV1/src/fr/monkhanny/dorfromantik/game/ScoreManager.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import fr.monkhanny.dorfromantik.enums.Biome;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Gère le calcul du score basé sur les poches de terrains connectées.
|
||||
*/
|
||||
public class ScoreManager {
|
||||
private final Map<Biome, BiomeGroup> biomeGroups;
|
||||
private int currentScore;
|
||||
|
||||
public ScoreManager(Map<Biome, BiomeGroup> biomeGroups) {
|
||||
this.biomeGroups = biomeGroups;
|
||||
this.currentScore = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour le score en recalculant toutes les poches.
|
||||
*/
|
||||
public void updateScore() {
|
||||
currentScore = 0;
|
||||
|
||||
for (BiomeGroup group : biomeGroups.values()) {
|
||||
Set<Pocket> uniquePockets = new HashSet<>(group.getPockets());
|
||||
for (Pocket pocket : uniquePockets) {
|
||||
int size = pocket.getTiles().size();
|
||||
System.out.println("Calculating score for pocket of biome " + pocket.getBiome() +
|
||||
": size=" + size + ", points=" + (size * size));
|
||||
currentScore += size * size;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Updated score: " + currentScore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getCurrentScore() {
|
||||
return currentScore;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
254
TestV1/src/fr/monkhanny/dorfromantik/game/Tile.java
Normal file
254
TestV1/src/fr/monkhanny/dorfromantik/game/Tile.java
Normal file
@@ -0,0 +1,254 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
|
||||
import fr.monkhanny.dorfromantik.enums.Biome;
|
||||
import fr.monkhanny.dorfromantik.enums.TileOrientation;
|
||||
import fr.monkhanny.dorfromantik.utils.Hexagon;
|
||||
|
||||
|
||||
public class Tile extends Cell {
|
||||
|
||||
private HashMap<TileOrientation, Biome> sideBiomes = new HashMap<>();
|
||||
|
||||
|
||||
public Tile(Board board, int x, int y, int radius, Biome... biomes) {
|
||||
super(board, x, y, radius);
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
for (int i = 0; i < sides.length; i++) {
|
||||
this.sideBiomes.put(sides[i], biomes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Tile(Board board, int x, int y, int radius) {
|
||||
super(board, x, y, radius);
|
||||
this.assignRandomBiomes();
|
||||
}
|
||||
|
||||
|
||||
public Tile(Board board, Point center, int radius, Biome... biomes) {
|
||||
this(board, center.x, center.y, radius, biomes);
|
||||
}
|
||||
|
||||
|
||||
public Tile(Board board, Point center, int radius) {
|
||||
this(board, center.x, center.y, radius);
|
||||
}
|
||||
|
||||
|
||||
public void setBiomes(Biome... biomes) {
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
for (int i = 0; i < sides.length; i++) {
|
||||
this.sideBiomes.put(sides[i], biomes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void assignRandomBiomes() {
|
||||
Game game = this.getBoard().getGame();
|
||||
Biome[] biomes = Biome.values();
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
|
||||
this.sideBiomes.clear();
|
||||
|
||||
Biome firstBiome = biomes[game.getRandomInt(biomes.length)];
|
||||
biomes = Arrays.stream(biomes).filter(b -> b != firstBiome).toArray(Biome[]::new);
|
||||
Biome secondBiome = biomes[game.getRandomInt(biomes.length)];
|
||||
|
||||
int firstBiomeSideCount = game.getRandomInt(sides.length + 1);
|
||||
int firstBiomeSideOffset = game.getRandomInt(sides.length);
|
||||
|
||||
for (int i = 0; i < sides.length; i++) {
|
||||
TileOrientation side = sides[(i + firstBiomeSideOffset) % sides.length];
|
||||
Biome assignedBiome = (i < firstBiomeSideCount) ? firstBiome : secondBiome;
|
||||
this.sideBiomes.put(side, assignedBiome);
|
||||
}
|
||||
}
|
||||
|
||||
public Biome getBiome(TileOrientation side) {
|
||||
return this.sideBiomes.get(side);
|
||||
}
|
||||
|
||||
|
||||
private Biome getDominantBiome() {
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
|
||||
int firstBiomeCount = 0;
|
||||
int secondBiomeCount = 0;
|
||||
Biome firstBiome = this.getBiome(sides[0]);
|
||||
Biome secondBiome = null;
|
||||
|
||||
for (TileOrientation side : sides) {
|
||||
Biome currentBiome = this.getBiome(side);
|
||||
if (currentBiome.equals(firstBiome)) {
|
||||
firstBiomeCount++;
|
||||
} else {
|
||||
secondBiome = currentBiome;
|
||||
secondBiomeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstBiomeCount > secondBiomeCount) {
|
||||
return firstBiome;
|
||||
} else if (firstBiomeCount < secondBiomeCount) {
|
||||
return secondBiome;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Biome[] getBiomes() {
|
||||
Biome[] biomes = new Biome[TileOrientation.values().length];
|
||||
for (TileOrientation side : TileOrientation.values()) {
|
||||
biomes[side.ordinal()] = this.getBiome(side);
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
|
||||
|
||||
public void rotate(boolean clockwise) {
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
HashMap<TileOrientation, Biome> newBiomesMap = new HashMap<>();
|
||||
|
||||
for (int i = 0; i < sides.length; i++) {
|
||||
TileOrientation side = sides[i];
|
||||
TileOrientation newSide = clockwise ? sides[(i + 1) % sides.length] : sides[(i + sides.length - 1) % sides.length];
|
||||
newBiomesMap.put(newSide, this.sideBiomes.get(side));
|
||||
}
|
||||
|
||||
this.sideBiomes = newBiomesMap;
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
|
||||
public boolean containsBiome(Biome biome) {
|
||||
for (TileOrientation side : TileOrientation.values()) {
|
||||
if (this.getBiome(side) == biome) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAdjacentTo(Tile otherTile) {
|
||||
// Obtenir le rayon de la tuile
|
||||
int tileRadius = this.getRadius();
|
||||
|
||||
// Compute the distance between the center of this tile and the other tile
|
||||
int deltaX = this.getX() - otherTile.getX();
|
||||
int deltaY = this.getY() - otherTile.getY();
|
||||
|
||||
// Calculate the Euclidean distance between the two tiles
|
||||
double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
// In a hexagonal grid, two tiles are adjacent if their distance is equal to the diameter (2 * radius)
|
||||
return distance <= (2 * tileRadius);
|
||||
}
|
||||
|
||||
private TileOrientation determineSide(int x, int y) {
|
||||
int radius = this.getRadius();
|
||||
TileOrientation[] sides = TileOrientation.values();
|
||||
double angle = Cell.to360Degrees(Math.toDegrees(Math.atan2(y - radius, x - radius)) + 120);
|
||||
|
||||
int floorSide = (int) Math.floor(Cell.to360Degrees(angle - 2) / 60);
|
||||
int ceilSide = (int) Math.floor(Cell.to360Degrees(angle + 2) / 60);
|
||||
|
||||
if (floorSide == ceilSide) {
|
||||
return sides[floorSide];
|
||||
}
|
||||
|
||||
Biome floorBiome = this.getBiome(sides[floorSide]);
|
||||
Biome dominantBiome = this.getDominantBiome();
|
||||
|
||||
if (dominantBiome == null && y > radius) {
|
||||
return TileOrientation.SOUTH;
|
||||
}
|
||||
|
||||
if (dominantBiome == null && y < radius) {
|
||||
return TileOrientation.NORTH;
|
||||
}
|
||||
|
||||
return floorBiome.equals(dominantBiome) ? sides[ceilSide] : sides[floorSide];
|
||||
}
|
||||
|
||||
|
||||
private void drawHexagonRow(Graphics2D g2d, double rowX, double rowY, double radius, int rowLength) {
|
||||
int gRadius = this.getRadius();
|
||||
|
||||
for (int i = 0; i < rowLength; i++) {
|
||||
Color[] colors;
|
||||
int x = (int) Math.round(rowX + radius * Math.sqrt(3) * i);
|
||||
int y = (int) Math.round(rowY);
|
||||
|
||||
if (x == Math.round(gRadius) && y == Math.round(gRadius)) {
|
||||
Biome dominantBiome = this.getDominantBiome();
|
||||
colors = (dominantBiome != null) ? dominantBiome.getBiomeColors() : this.getBiome(TileOrientation.SOUTH).getBiomeColors();
|
||||
} else {
|
||||
colors = this.getBiome(this.determineSide(x, y)).getBiomeColors();
|
||||
}
|
||||
|
||||
g2d.setColor(colors[i % colors.length]);
|
||||
g2d.fillPolygon(new Hexagon(x, y, (int) Math.ceil(radius), 90));
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawTileAt(Graphics g, int x, int y, float scale) {
|
||||
// Sauvegarde de l'état actuel du graphique
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
|
||||
// Déplacement du contexte graphique à la position souhaitée
|
||||
g2d.translate(x, y);
|
||||
|
||||
// Appel de la méthode de dessin de la tuile à la nouvelle position
|
||||
paintTile(g2d, scale);
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Méthode principale de dessin de la tuile.
|
||||
*
|
||||
* @param g Le contexte graphique
|
||||
* @param scale L'échelle de la tuile
|
||||
*/
|
||||
protected void paintTile(Graphics g, float scale) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
int radius = this.getRadius();
|
||||
Point center = new Point(radius, radius);
|
||||
radius = (int) (radius * scale);
|
||||
Hexagon hexagon = new Hexagon(center, radius);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setClip(hexagon);
|
||||
|
||||
double hexRadius = radius / Math.sqrt(3) / 3;
|
||||
double paddingX = center.x - radius;
|
||||
double paddingY = center.y - radius;
|
||||
|
||||
this.drawHexagonRow(g2d, paddingX + radius * 0.5, paddingY + radius - radius * Math.sqrt(3) / 2, hexRadius, 4);
|
||||
this.drawHexagonRow(g2d, paddingX, paddingY + radius - radius * Math.sqrt(3) / 3, hexRadius, 6);
|
||||
this.drawHexagonRow(g2d, paddingX - radius * 0.5, paddingY + radius - radius * Math.sqrt(3) / 6, hexRadius, 8);
|
||||
this.drawHexagonRow(g2d, paddingX - radius, paddingY + radius, hexRadius, 10);
|
||||
this.drawHexagonRow(g2d, paddingX - radius * 0.5, paddingY + radius + radius * Math.sqrt(3) / 6, hexRadius, 8);
|
||||
this.drawHexagonRow(g2d, paddingX, paddingY + radius + radius * Math.sqrt(3) / 3, hexRadius, 6);
|
||||
this.drawHexagonRow(g2d, paddingX + radius * 0.5, paddingY + radius + radius * Math.sqrt(3) / 2, hexRadius, 4);
|
||||
|
||||
g2d.setClip(null);
|
||||
g2d.setStroke(new BasicStroke((int) radius / 15));
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.drawPolygon(hexagon);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package fr.monkhanny.dorfromantik.game;
|
||||
|
||||
import fr.monkhanny.dorfromantik.listeners.TilePanningActionListener;
|
||||
|
||||
|
||||
public class TilePanningTransition {
|
||||
private Board board;
|
||||
private int targetOffsetX, targetOffsetY;
|
||||
private int steps;
|
||||
|
||||
public TilePanningTransition(Board board, int targetOffsetX, int targetOffsetY, int steps) {
|
||||
this.board = board;
|
||||
this.targetOffsetX = targetOffsetX;
|
||||
this.targetOffsetY = targetOffsetY;
|
||||
this.steps = steps;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// Créer un listener d'animation
|
||||
TilePanningActionListener listener = new TilePanningActionListener(board, targetOffsetX, targetOffsetY, steps);
|
||||
|
||||
// Démarrer l'animation si aucune n'est en cours
|
||||
listener.startAnimation();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user