Derniere version du jeu

This commit is contained in:
lecointre
2026-04-12 16:40:07 +02:00
parent 43cc3c1145
commit 86ff392e75
7 changed files with 734 additions and 244 deletions
+172 -62
View File
@@ -1,112 +1,222 @@
import javax.swing.*;
import java.awt.*;
/**
* Fenêtre affichant la partie en cours.
* Gère l'affichage de la grille, du compteur de mines et du bouton de sauvegarde.
*/
public class FenetreJeu extends JFrame {
/** Position X initiale de la fenêtre de jeu sur l'écran. */
private static final int POSITION_X = 100;
/** Position Y initiale de la fenêtre de jeu sur l'écran. */
private static final int POSITION_Y = 100;
/** Estimation de la taille en pixels d'une case pour la largeur de la fenêtre. */
private static final int LARGEUR_CASE_PIXELS = 50;
/** Estimation de la taille en pixels d'une case pour la hauteur de la fenêtre. */
private static final int HAUTEUR_CASE_PIXELS = 50;
/** Espace supplémentaire en hauteur pour afficher l'en-tête et le pied de page. */
private static final int MARGE_HAUTEUR_PIXELS = 100;
/** Référence vers le modèle logique du jeu. */
private Grille grille;
/** Tableau à deux dimensions stockant les composants graphiques des cases. */
private JButton[][] boutons;
/** Étiquette textuelle affichant le nombre de mines restantes à trouver. */
private JLabel labelCompteur;
private JButton btnActionBas; // NOUVEAU : On garde le bouton en mémoire
/** Bouton dynamique en bas de la fenêtre (Sauvegarder ou Retour Menu). */
private JButton boutonActionBas;
public FenetreJeu(Grille g) {
/**
* Constructeur de la fenêtre de jeu.
* @param grilleJeu la grille logique initialisée à afficher.
*/
public FenetreJeu(Grille grilleJeu) {
super("Démineur - Partie en cours");
this.grille = g;
this.boutons = new JButton[g.getLignes()][g.getColonnes()];
this.grille = grilleJeu;
this.boutons = new JButton[grilleJeu.getLignes()][grilleJeu.getColonnes()];
this.setSize(600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
int largeurFenetre = grilleJeu.getColonnes() * LARGEUR_CASE_PIXELS;
int hauteurFenetre = (grilleJeu.getLignes() * HAUTEUR_CASE_PIXELS) + MARGE_HAUTEUR_PIXELS;
this.setSize(largeurFenetre, hauteurFenetre);
this.setLocation(POSITION_X, POSITION_Y);
this.labelCompteur = new JLabel("Mines restantes : " + g.getMinesRestantes());
this.labelCompteur.setHorizontalAlignment(SwingConstants.CENTER);
this.labelCompteur.setFont(new Font("Arial", Font.BOLD, 16));
initialiserEntete();
initialiserPanneauGrille();
initialiserBoutonBas();
}
/**
* Prépare et ajoute le compteur de mines en haut de la fenêtre.
*/
private void initialiserEntete() {
this.labelCompteur = new JLabel("Mines restantes : " + this.grille.getMinesRestantes());
this.labelCompteur.setHorizontalAlignment(JLabel.CENTER);
this.add(this.labelCompteur, BorderLayout.NORTH);
}
/**
* Prépare et ajoute la zone centrale contenant tous les boutons cliquables.
*/
private void initialiserPanneauGrille() {
JPanel panneauGrille = new JPanel();
panneauGrille.setLayout(new GridLayout(g.getLignes(), g.getColonnes()));
panneauGrille.setLayout(new GridLayout(this.grille.getLignes(), this.grille.getColonnes()));
ControleurGrille controleurSouris = new ControleurGrille(this, this.grille);
for (int i = 0; i < g.getLignes(); i++) {
for (int j = 0; j < g.getColonnes(); j++) {
for (int ligne = 0; ligne < this.grille.getLignes(); ligne++) {
for (int colonne = 0; colonne < this.grille.getColonnes(); colonne++) {
JButton boutonCase = new JButton("");
this.boutons[i][j] = boutonCase;
this.boutons[ligne][colonne] = boutonCase;
panneauGrille.add(boutonCase);
boutonCase.addMouseListener(controleurSouris);
}
}
this.add(panneauGrille, BorderLayout.CENTER);
}
// --- MODIFICATION DU BOUTON DU BAS ---
this.btnActionBas = new JButton("Sauver et Quitter");
this.add(this.btnActionBas, BorderLayout.SOUTH);
/**
* Prépare et ajoute le bouton de contrôle général en bas de la fenêtre.
*/
private void initialiserBoutonBas() {
this.boutonActionBas = new JButton("Sauver et Quitter");
this.add(this.boutonActionBas, BorderLayout.SOUTH);
ControleurJeu controleurQuitter = new ControleurJeu(this);
this.btnActionBas.addActionListener(controleurQuitter);
this.boutonActionBas.addActionListener(controleurQuitter);
}
// --- NOUVEAUX OUTILS ---
public JButton getBouton(int l, int c) { return this.boutons[l][c]; }
public Grille getGrille() { return this.grille; } // Permet au contrôleur de lire la grille
/**
* Récupère un bouton graphique spécifique de la grille.
* @param indexLigne la ligne du bouton.
* @param indexColonne la colonne du bouton.
* @return le bouton correspondant.
*/
public JButton getBouton(int indexLigne, int indexColonne) { return this.boutons[indexLigne][indexColonne]; }
/**
* Accède à l'instance de la grille logique.
* @return la grille du jeu.
*/
public Grille getGrille() { return this.grille; }
/**
* Transforme le bouton de sauvegarde en bouton de retour au menu.
*/
public void changerBoutonEnRetourMenu() {
this.btnActionBas.setText("Retour au Menu");
this.boutonActionBas.setText("Retour au Menu");
}
/**
* Interroge la grille et rafraîchit le texte du compteur de mines.
*/
public void mettreAJourCompteur() {
this.labelCompteur.setText("Mines restantes : " + this.grille.getMinesRestantes());
}
public void rafraichirCase(int l, int c) {
Case caseLogique = this.grille.getCase(l, c);
JButton btn = this.boutons[l][c];
/**
* Met à jour l'apparence visuelle d'un bouton selon son état logique.
* @param ligne la ligne du bouton à rafraîchir.
* @param colonne la colonne du bouton à rafraîchir.
*/
public void rafraichirCase(int ligne, int colonne) {
Case caseLogique = this.grille.getCase(ligne, colonne);
JButton bouton = this.boutons[ligne][colonne];
if (caseLogique.isRevelee()) {
btn.setEnabled(false);
if (caseLogique.isMinee()) {
btn.setText("M");
btn.setBackground(Color.RED);
} else if (caseLogique.getNbMinesVoisines() > 0) {
btn.setText("" + caseLogique.getNbMinesVoisines());
} else {
btn.setText("");
}
appliquerStyleCaseRevelee(caseLogique, bouton);
} else {
if (caseLogique.getMarqueur() == 1) {
btn.setText("★");
} else if (caseLogique.getMarqueur() == 2) {
btn.setText("?");
} else {
btn.setText("");
}
appliquerStyleCaseCachee(caseLogique, bouton);
}
}
/**
* Applique les couleurs et le texte d'une case qui vient d'être révélée.
* @param caseLogique la donnée de la case.
* @param bouton le composant graphique associé.
*/
private void appliquerStyleCaseRevelee(Case caseLogique, JButton bouton) {
if (caseLogique.isMinee()) {
bouton.setText("M");
bouton.setBackground(Color.RED);
} else if (caseLogique.getNbMinesVoisines() > 0) {
bouton.setText("" + caseLogique.getNbMinesVoisines());
bouton.setBackground(Color.WHITE);
} else {
bouton.setText("");
bouton.setBackground(Color.LIGHT_GRAY);
}
}
/**
* Applique les symboles d'une case qui est encore masquée (marqueurs).
* @param caseLogique la donnée de la case.
* @param bouton le composant graphique associé.
*/
private void appliquerStyleCaseCachee(Case caseLogique, JButton bouton) {
if (caseLogique.getMarqueur() == Case.MARQUEUR_ETOILE) {
bouton.setText("*");
} else if (caseLogique.getMarqueur() == Case.MARQUEUR_INTERROGATION) {
bouton.setText("?");
} else {
bouton.setText("");
}
}
/**
* Force la mise à jour visuelle de toutes les cases de la grille.
*/
public void rafraichirTouteLaGrille() {
for (int i = 0; i < grille.getLignes(); i++) {
for (int j = 0; j < grille.getColonnes(); j++) {
rafraichirCase(i, j);
for (int ligne = 0; ligne < grille.getLignes(); ligne++) {
for (int colonne = 0; colonne < grille.getColonnes(); colonne++) {
rafraichirCase(ligne, colonne);
}
}
}
public void afficherDefaite(int lExplose, int cExplose) {
for (int i = 0; i < grille.getLignes(); i++) {
for (int j = 0; j < grille.getColonnes(); j++) {
Case c = grille.getCase(i, j);
JButton btn = boutons[i][j];
btn.setEnabled(false);
if (i == lExplose && j == cExplose) {
btn.setText("BOUM");
btn.setBackground(Color.RED);
} else if (c.isMinee() && c.getMarqueur() != 1) {
btn.setText("M");
btn.setBackground(Color.ORANGE);
} else if (!c.isMinee() && c.getMarqueur() == 1) {
btn.setText("X");
btn.setBackground(Color.YELLOW);
}
/**
* Affiche l'état de défaite en révélant les erreurs et les mines manquantes.
* @param ligneExplosion la ligne de la mine déclenchée.
* @param colonneExplosion la colonne de la mine déclenchée.
*/
public void afficherDefaite(int ligneExplosion, int colonneExplosion) {
for (int ligne = 0; ligne < grille.getLignes(); ligne++) {
for (int colonne = 0; colonne < grille.getColonnes(); colonne++) {
Case caseActuelle = grille.getCase(ligne, colonne);
JButton bouton = boutons[ligne][colonne];
appliquerStyleDefaite(caseActuelle, bouton, ligne, colonne, ligneExplosion, colonneExplosion);
}
}
}
/**
* Détermine la couleur spécifique d'une case en fin de partie (erreur, oubli, ou explosion).
* @param caseActuelle la donnée de la case.
* @param bouton le composant graphique.
* @param ligne la ligne en cours de parcours.
* @param colonne la colonne en cours de parcours.
* @param ligneExplosion la ligne de la mine fatale.
* @param colonneExplosion la colonne de la mine fatale.
*/
private void appliquerStyleDefaite(Case caseActuelle, JButton bouton, int ligne, int colonne, int ligneExplosion, int colonneExplosion) {
if (ligne == ligneExplosion && colonne == colonneExplosion) {
bouton.setText("BOUM");
bouton.setBackground(Color.RED);
} else if (caseActuelle.isMinee() && caseActuelle.getMarqueur() != Case.MARQUEUR_ETOILE) {
bouton.setText("M");
bouton.setBackground(Color.ORANGE);
} else if (!caseActuelle.isMinee() && caseActuelle.getMarqueur() == Case.MARQUEUR_ETOILE) {
bouton.setText("X");
bouton.setBackground(Color.YELLOW);
}
}
}