From 5b167c761fc9fdf04055ebd50c342c7f152061c2 Mon Sep 17 00:00:00 2001 From: Felix-Vimalaratnam Date: Wed, 8 Oct 2025 17:42:50 +0200 Subject: [PATCH] ajout du score et limite du temps --- out/fr/iut/Projet/Action.class | Bin 6330 -> 7932 bytes out/fr/iut/Projet/GameTimer$1.class | Bin 1139 -> 1283 bytes out/fr/iut/Projet/GameTimer.class | Bin 1148 -> 1298 bytes out/fr/iut/Projet/Score.class | Bin 0 -> 1755 bytes src/fr/iut/Projet/Action.java | 255 +++++++++++++--------------- src/fr/iut/Projet/GameTimer.java | 23 ++- src/fr/iut/Projet/Score.java | 70 ++++++++ 7 files changed, 204 insertions(+), 144 deletions(-) create mode 100644 out/fr/iut/Projet/Score.class create mode 100644 src/fr/iut/Projet/Score.java diff --git a/out/fr/iut/Projet/Action.class b/out/fr/iut/Projet/Action.class index 2aee0676d9c38d403f2efe3c1fe79be8b549715a..995cf66fab07579dac6db6794cf9356add2aac70 100644 GIT binary patch delta 5057 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 diff --git a/out/fr/iut/Projet/GameTimer$1.class b/out/fr/iut/Projet/GameTimer$1.class index a09165db067f162c66f70773d6f19eaca8bb812e..db0f2165774d8e6d3791301df1db41fcd58474b4 100644 GIT binary patch delta 482 zcmey&(adFi>ff$?3=9nB46d9EoD9-j3|tJ7oD32SG9W@$h=GAYk&8izK^eqV;bu@} zP-ACMXJ^o4XV98xIERlnxFj(-+c&WwBrz!`b>eBGaBUt2J_a2|1`fZ};u4Si;u0PP z9tK_>23-a{9tM2|14ae`r~Leq;*z4o0^ihiT#}lXTExg8;**tF zmZ+bTn3t{}RGOCua*s75gAk@DBLj0$X&yU+9mqn*$@NT{jLwr+GA(0tnH<3EBg@Ia z#lXnG&A=!i0CG740|OHS0|OreKLaC!z~r6G(u#r%3=C`xj0_A6N(_t)LJYzn83qQ1 zYzAhqTC2%lnU(9cwlFYmVPHSTzz=2ZWZ+=~RG W92g`Sff$?3=9nB4Az_s>*w%oD8B2k|07#h=GAYj*CH_L4ln?k)1)A zok3-y^_+>%4ct|E7gfpZtPJ zlhJar5c4t?D@F#@$qLM>lOHmxM6xq*FfcN3GB64VfGlHRU|?ckVBlfkWng6BV_;xV zVqgM`aA|38Wnk3W&cL*hfq{XMfuDhafsKKYfq_AhfssLgK@h6mg@GBYUS)C|i*htV zEgu6j0|SE!122OrgEE5}11ke49GDn{8AKQu7+4rY8N?XG!M2MsC^0ZF2r)1*urok_ WDT4)r8G|H)Gy?S)hcxW diff --git a/out/fr/iut/Projet/GameTimer.class b/out/fr/iut/Projet/GameTimer.class index 6f35b7dc5cea00c45bfb605fef24d96433914cbe..6fd3bce57b39697d9e067e4144eb510d5d269fd2 100644 GIT binary patch delta 669 zcmeyvF^Mbs)W2Q(7#JAL8Qi!Sgc)=>8H5=0*ctRW7!0@=m>CQ~d?R)SV-UxLoxzly z!HkQ6i@}_Wfs?@kBxwmEtUz3A5McvSXv@xE$If6sF)Txsw!OW1_l)dMzCHEh&BO)Hi&Ju4D1Yc42%q_5FL}xGfUPB zA{2qlW?*n)U}bP-;A3!MU}R8ZP=`887HTxB))oe~4RBwuf$j5PU}Vr>(8QvYX$_iE iUj}9dEpX6kGw3idFo?1+Ffwp4h%hiPaDiD2AOHa5AW(Mz delta 542 zcmbQl^@k(u)W2Q(7#JAL863D6gcvk983Y+L*%`Dr7__+G0Hd|h@1JrGBqoxy;e z!H|oAi@}JCfs?@)BxwR-nSuy2kQ#G#1`Bou%Zbq$6JKdewr6bPkYbSLVUS>uoP3s1 zl|zcbiibgjL3HvjMtNpy2Ajz;Ohz(N47NNBQVe!H3}Ou8JPdLm4e}tup22EzKGSw> zK?WfP1_ovZCXiMJ1_maOLNG1CAj!bMz{bGHAjKffz{nsoIg;6}UY3D@L5hKmfq_Aq zfrUYafs;X&L5x9;L5@L@!GuABfe~Z}NHqfkgDwLT10w?i1FshIRt6@mEeyQd82C0a zFfcGOfQ;c|U}j)o&|zR@&}HCZ&|_d^kcU{rz`&rwzzEjL0nx<|(^b#Fz{SACz`$U{ zz|LUIz{sEg*P;)#jUQ$kn-I%31_78(1_p?I<_xS177Tn0mJEyxiVR9nr^-U@W7XQi zz_tPIM3C8MqjP89?p^ Iu^2!A02ziaqW}N^ diff --git a/out/fr/iut/Projet/Score.class b/out/fr/iut/Projet/Score.class new file mode 100644 index 0000000000000000000000000000000000000000..65eb45c767cc6696824937b2b11bd344461cefcc GIT binary patch literal 1755 zcmX^0Z`VEs1_pD6U@ith1~pCw0S0w;1`Qzw1_m8224)6bkcb{TgFXj?0T%;1gCR)J zh@HV0M4NCim@=4gF$gf2gSZy#43_K+R*Vch$)!a_sd**A$@xX8j0}vPj0{}GAhu6p zQfdw(gNRR7Vp(E^esOtbUb?;)Sk#)4fz2i}FSEpsk%3u5GmMde#W_DEm63tpCo?bA zuQWF)wJ0PpDJPYYK_DeHxhOTUIMt~#I5jyxFNKjo6d@E|l%JRGlUh=eTExg8o|y+z z>YQIxl$u-ulMzP9gy$EfxaF6E%;76eg}6E-KPt5-pOJyPv>+w1Bo*vLMh4z=s5F!> zrlE=5EBxuHCC(^;z^tJO3WnhP(xT*4w@i>fxWM6~2MP-w1~CS49tI%>VMYcakN|4n zFfs@@<>!|amlP!y_@nE0%=)2|T zl`t}}Iu>On=73Z<@Gv+sI59FvfmFcE4+cenbADcNNn&0}F%N??g9|%@D-VMkgF6p{ zJjhKR4EBr+!f8eNnWZKA0Y&*)sU`Yghchw=fK1ZQNz6;v_fN`7O)lYL@MQ2}WZ(qL zD_AKoGBSwgCT6EP=jSCSmV{@PWWcRrWDwQxgoGZ%gy52*%)E4KkT^I@QA9!ML0kh< z+|v^z!(Nyy2Tz zlEKKpoSRs|$iS-M=?RK6km(_*6(#Hp-k{L-XJk-8XvoYf%g;{Lhd3VMO}E74lKi4d zc7{Mk1~#Ak{Or;KMg|_wyu8#R=bXgi;?!bBh8a+Ig2N7K1|(uV67y1WQj1j}8m%$C zj3k1hF{H8}6^rs{B=wL;vPKSds1eSIIXS_ZC8^fz3_*+xsu=#m<~BwKIsEDv6d42< z1Q{3@m>8HqNgK=(VGw0tVBln61f_TeMg|E628J{SHU>rp1_mpw?F@`s0x4S=n6!2? zFh^=_VPM+Dz{0?=oq=^L1Dn z5YUR;!oVcJm4L%~4F+xoO$L4jEe1vgSzNk}aOu`#;AYTg;Ab#kU}TVk>(*jm0^7}{ z#f-yN69!fWQwB~3GX^G5IRFhcU8p`mP{4!24IDk&82Axk#>Kz{ib@6n25SaJ1_cI1 zs8(49MzEEvAgvqV@db%_dj>`ZB?e_IN}1N6DRp6BW>5hqB~=DL1_lN$21W)Sh5!a% S21y1@1_lNW21amDX#)VT`FlM8 literal 0 HcmV?d00001 diff --git a/src/fr/iut/Projet/Action.java b/src/fr/iut/Projet/Action.java index b0e79ba..a99d081 100644 --- a/src/fr/iut/Projet/Action.java +++ b/src/fr/iut/Projet/Action.java @@ -6,116 +6,100 @@ import java.awt.*; /** * Classe principale qui gère l'interface graphique du jeu du pendu. * - * Cette classe crée la fenêtre du jeu et affiche : - * - le mot caché avec les lettres devinées, - * - les lettres incorrectes, - * - le dessin du pendu (via {@link Affiche}), - * - le timer affiché en haut à droite (via {@link GameTimer}), - * et permet à l'utilisateur de saisir des lettres. - * Elle gère également : - * - la logique de mise à jour de l'interface, - * - la fin de partie, - * - le redémarrage, - * - et le changement de difficulté en utilisant {@link PlayButtonListener}. + * Affiche le mot caché, les lettres incorrectes, le dessin du pendu, le timer et le score. + * Gère également les interactions avec le joueur, la fin de partie et le redémarrage. */ public class Action { - /** Fenêtre principale du jeu */ + private Score score; private JFrame gameFrame; - - /** Label affichant le mot caché avec les lettres découvertes */ private JLabel wordLabel; - - /** Label affichant les lettres incorrectes devinées par le joueur */ private JLabel incorrectLettersLabel; - - /** Champ de texte pour saisir une lettre */ private JTextField letterInputField; - - /** Instance de la logique du jeu (mot secret, lettres, vies, etc.) */ private Random_word game; - - /** Composant graphique représentant le pendu */ private Affiche affiche; - - /** Timer qui compte le temps écoulé depuis le début du mot */ private GameTimer gameTimer; - - /** Niveau de difficulté courant ("facile", "moyen", "difficile", "hell") */ private String difficulty; /** - * Constructeur : initialise le jeu avec la difficulté choisie, - * crée les composants graphiques et démarre le timer. - * - * @param difficulty Niveau de difficulté pour le mot à deviner + * Constructeur : initialise le jeu selon la difficulté choisie, + * crée tous les composants graphiques et démarre le timer. + * @param difficulty Niveau de difficulté ("facile", "moyen", "difficile", "hell") */ public Action(String difficulty) { this.difficulty = difficulty; - - // Création du jeu avec le mot choisi selon la difficulté game = new Random_word(difficulty); - // Initialisation des composants graphiques + // Initialisation initializeComponents(); layoutComponents(); + setupListeners(); - // Gestion de la saisie utilisateur - letterInputField.addActionListener(e -> handleGuess()); - - // Démarre le timer dès l'ouverture de la partie + // Démarre le timer et affiche la fenêtre gameTimer.start(); - - // Affiche la fenêtre du jeu gameFrame.setVisible(true); } - // ==================== Initialisation des composants ==================== + // ==================== Initialisation ==================== - /** - * Initialise tous les composants graphiques du jeu : - * - fenêtre principale - * - dessin du pendu - * - labels pour le mot et les lettres incorrectes - * - champ de saisie - * - timer - */ + /** Initialise les composants principaux : fenêtre, jeu, timer et score */ private void initializeComponents() { + initializeFrameAndPanels(); + initializeGameComponents(); + initializeTimerAndScore(); + } + + /** Initialise la fenêtre principale */ + private void initializeFrameAndPanels() { gameFrame = new JFrame("Hanging Man - " + difficulty); gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); gameFrame.setSize(700, 500); + } - // Composant graphique pour dessiner le pendu + /** Initialise les composants du jeu : pendu, mot caché, lettres incorrectes, champ de saisie */ + private void initializeGameComponents() { affiche = new Affiche(); affiche.setPreferredSize(new Dimension(350, 400)); affiche.setBackground(Color.WHITE); affiche.setOpaque(true); - // Label affichant le mot caché wordLabel = new JLabel(game.getHiddenWord()); wordLabel.setFont(new Font("Arial", Font.BOLD, 32)); wordLabel.setHorizontalAlignment(SwingConstants.CENTER); - // Label affichant les lettres incorrectes incorrectLettersLabel = new JLabel("Incorrect letters: " + game.getIncorrectLetters()); incorrectLettersLabel.setFont(new Font("Arial", Font.PLAIN, 20)); incorrectLettersLabel.setHorizontalAlignment(SwingConstants.CENTER); - // Champ pour saisir une lettre letterInputField = new JTextField(3); letterInputField.setFont(new Font("Arial", Font.PLAIN, 24)); + } - // Création du timer + /** Initialise le timer et le score, avec un listener pour diminuer le score chaque seconde */ + private void initializeTimerAndScore() { gameTimer = new GameTimer(); + score = new Score(); + + // Listener pour diminuer le score chaque seconde et finir après 60s + gameTimer.setTimerListener(() -> { + score.decreaseBySecond(); // comportement normal selon le temps + + // Si 60 secondes écoulées et que la partie n'est pas finie + if (gameTimer.getSecondsElapsed() >= 60 && !game.isGameOver()) { + score.setScoreToZero(); // on met le score à 0 + endGame("Temps écoulé ! Vous avez perdu !"); + } + }); + } + + /** Ajoute les listeners sur les composants */ + private void setupListeners() { + letterInputField.addActionListener(e -> handleGuess()); } // ==================== Mise en page ==================== - /** - * Crée la mise en page principale avec un BorderLayout : - * - panneau gauche : dessin du pendu - * - panneau droit : mot, lettres incorrectes, champ de saisie, boutons et timer - */ + /** Organise la mise en page globale (BorderLayout : gauche pendu, droite info et saisie) */ private void layoutComponents() { JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(createLeftPanel(), BorderLayout.WEST); @@ -130,15 +114,7 @@ public class Action { return leftPanel; } - /** - * Crée le panneau droit avec tous les éléments : - * - mot caché - * - lettres incorrectes - * - champ de saisie - * - bouton restart - * - bouton changement de difficulté - * - timer en haut à droite - */ + /** Crée le panneau droit avec mot, lettres incorrectes, saisie, boutons et timer/score */ private JPanel createRightPanel() { JPanel rightPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); @@ -146,51 +122,58 @@ public class Action { gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(5, 5, 5, 5); - // Mot caché - gbc.gridy = 0; - gbc.weighty = 1.0; - rightPanel.add(wordLabel, gbc); - - // Lettres incorrectes - gbc.gridy = 1; - rightPanel.add(incorrectLettersLabel, gbc); - - // Champ de saisie - gbc.gridy = 2; - JPanel inputRow = new JPanel(); - inputRow.add(new JLabel("Enter a letter:")); - inputRow.add(letterInputField); - rightPanel.add(inputRow, gbc); - - // Bouton restart - gbc.gridy = 3; - JButton restartButton = new JButton("Restart"); - restartButton.addActionListener(e -> restartGame()); - rightPanel.add(restartButton, gbc); - - // Bouton changement de difficulté - gbc.gridy = 4; - JButton changeDifficultyButton = new JButton("Changer la difficulté"); - changeDifficultyButton.addActionListener(e -> showDifficultyDialog()); - rightPanel.add(changeDifficultyButton, gbc); - - // Timer en haut à droite - gbc.gridy = 5; - gbc.anchor = GridBagConstraints.NORTHEAST; - rightPanel.add(gameTimer.getTimerLabel(), gbc); + addWordAndIncorrectLetters(rightPanel, gbc); + addInputRow(rightPanel, gbc); + addButtons(rightPanel, gbc); + addTimerAndScore(rightPanel, gbc); return rightPanel; } + /** Ajoute le mot caché et les lettres incorrectes dans le panneau */ + private void addWordAndIncorrectLetters(JPanel panel, GridBagConstraints gbc) { + gbc.gridy = 0; + gbc.weighty = 1.0; + panel.add(wordLabel, gbc); + + gbc.gridy = 1; + panel.add(incorrectLettersLabel, gbc); + } + + /** Ajoute le champ de saisie pour les lettres */ + private void addInputRow(JPanel panel, GridBagConstraints gbc) { + gbc.gridy = 2; + JPanel inputRow = new JPanel(); + inputRow.add(new JLabel("Enter a letter:")); + inputRow.add(letterInputField); + panel.add(inputRow, gbc); + } + + /** Ajoute les boutons restart et changement de difficulté */ + private void addButtons(JPanel panel, GridBagConstraints gbc) { + gbc.gridy = 3; + JButton restartButton = new JButton("Restart"); + restartButton.addActionListener(e -> restartGame()); + panel.add(restartButton, gbc); + + gbc.gridy = 4; + JButton changeDifficultyButton = new JButton("Changer la difficulté"); + changeDifficultyButton.addActionListener(e -> showDifficultyDialog()); + panel.add(changeDifficultyButton, gbc); + } + + /** Ajoute le timer et le score en haut à droite */ + private void addTimerAndScore(JPanel panel, GridBagConstraints gbc) { + gbc.gridy = 5; + JPanel topRightPanel = new JPanel(new BorderLayout()); + topRightPanel.add(gameTimer.getTimerLabel(), BorderLayout.WEST); + topRightPanel.add(score.getScoreLabel(), BorderLayout.EAST); + panel.add(topRightPanel, gbc); + } + // ==================== Gestion des actions ==================== - /** - * Traite la saisie d'une lettre par le joueur : - * - vérifie la validité - * - met à jour le mot caché et lettres incorrectes - * - met à jour le pendu - * - termine la partie si nécessaire - */ + /** Traite la saisie d'une lettre par le joueur */ private void handleGuess() { String inputText = letterInputField.getText(); letterInputField.setText(""); @@ -200,12 +183,27 @@ public class Action { char guessedLetter = inputText.charAt(0); String message = game.guessLetter(guessedLetter); + updateScore(message); updateUI(); - if (game.isGameOver()) endGame(message); + if (game.isGameOver()) { + if (game.isWon()) { + score.increaseByWordFound(); + } + endGame(message); + } } - /** Vérifie que le texte saisi est une seule lettre */ + /** Met à jour le score selon le résultat de la lettre */ + private void updateScore(String message) { + if (message.contains("Bien joué")) { + score.increaseByCorrectLetter(); + } else if (message.contains("Mauvaise lettre")) { + score.decreaseByWrongLetter(); + } + } + + /** Vérifie que la saisie est une seule lettre */ private boolean isValidInput(String inputText) { if (inputText.length() != 1 || !Character.isLetter(inputText.charAt(0))) { JOptionPane.showMessageDialog(gameFrame, "Please enter a single letter!"); @@ -214,20 +212,14 @@ public class Action { return true; } - /** Met à jour les labels et le dessin du pendu */ + /** Met à jour l'affichage du mot, des lettres incorrectes et des vies du pendu */ private void updateUI() { wordLabel.setText(game.getHiddenWord()); incorrectLettersLabel.setText("Incorrect letters: " + game.getIncorrectLetters()); affiche.setLives(game.getLives()); } - /** - * Termine la partie : - * - arrête le timer - * - met à jour le dessin du pendu en cas de victoire/défaite - * - affiche le message de fin - * - désactive le champ de saisie - */ + /** Termine la partie, arrête le timer et affiche le message */ private void endGame(String message) { gameTimer.stop(); @@ -235,26 +227,24 @@ public class Action { affiche.setYouWin(true); } else { affiche.setLives(0); + score.setScoreToZero(); // <- on met le score à 0 en cas de défaite } JOptionPane.showMessageDialog(gameFrame, message); letterInputField.setEditable(false); } - /** Redémarre le jeu avec la même difficulté en utilisant PlayButtonListener */ + + /** Redémarre le jeu avec la même difficulté */ private void restartGame() { gameFrame.dispose(); JFrame tempFrame = new JFrame(); new PlayButtonListener(tempFrame, difficulty).actionPerformed(null); } - /** - * Affiche une boîte de dialogue pour changer la difficulté, - * puis relance le jeu avec la nouvelle difficulté. - */ + /** Affiche le dialogue pour changer la difficulté et relance le jeu */ private void showDifficultyDialog() { String[] options = {"Facile", "Moyen", "Difficile", "Hell"}; - int choice = JOptionPane.showOptionDialog( gameFrame, "Choisissez la difficulté :", @@ -269,23 +259,12 @@ public class Action { if (choice >= 0) { String newDifficulty; switch (choice) { - case 0: - newDifficulty = "facile"; - break; - case 1: - newDifficulty = "moyen"; - break; - case 2: - newDifficulty = "difficile"; - break; - case 3: - newDifficulty = "hell"; - break; - default: - newDifficulty = "moyen"; - break; + case 0: newDifficulty = "facile"; break; + case 1: newDifficulty = "moyen"; break; + case 2: newDifficulty = "difficile"; break; + case 3: newDifficulty = "hell"; break; + default: newDifficulty = "moyen"; break; } - gameFrame.dispose(); JFrame tempFrame = new JFrame(); new PlayButtonListener(tempFrame, newDifficulty).actionPerformed(null); diff --git a/src/fr/iut/Projet/GameTimer.java b/src/fr/iut/Projet/GameTimer.java index d412290..6bfd00a 100644 --- a/src/fr/iut/Projet/GameTimer.java +++ b/src/fr/iut/Projet/GameTimer.java @@ -7,8 +7,8 @@ import java.awt.event.ActionListener; /** * Classe GameTimer qui gère le temps écoulé sur un mot. * - * Affiche le temps en secondes dans un JLabel et peut être intégré - * à la fenêtre du jeu. + * Affiche le temps en secondes dans un JLabel et peut déclencher un listener + * à chaque seconde (par exemple pour réduire le score ou vérifier la limite de temps). */ public class GameTimer { @@ -21,9 +21,10 @@ public class GameTimer { /** Compteur de secondes écoulées */ private int secondsElapsed; - /** - * Constructeur : crée le label et initialise le timer. - */ + /** Listener appelé à chaque tick (chaque seconde) */ + private Runnable timerListener; + + /** Constructeur : crée le label et initialise le timer */ public GameTimer() { this.secondsElapsed = 0; this.timerLabel = new JLabel("Temps : 0 s"); @@ -35,10 +36,20 @@ public class GameTimer { public void actionPerformed(ActionEvent e) { secondsElapsed++; timerLabel.setText("Temps : " + secondsElapsed + " s"); + + // Appel du listener pour gérer le score ou la fin de partie + if (timerListener != null) { + timerListener.run(); + } } }); } + /** Définit le listener appelé à chaque seconde */ + public void setTimerListener(Runnable listener) { + this.timerListener = listener; + } + /** Démarre le timer */ public void start() { secondsElapsed = 0; @@ -65,4 +76,4 @@ public class GameTimer { public int getSecondsElapsed() { return secondsElapsed; } -} \ No newline at end of file +} diff --git a/src/fr/iut/Projet/Score.java b/src/fr/iut/Projet/Score.java new file mode 100644 index 0000000..7da2bbf --- /dev/null +++ b/src/fr/iut/Projet/Score.java @@ -0,0 +1,70 @@ +package fr.iut.Projet; + +import javax.swing.*; +import java.awt.*; + +/** + * Classe Score qui gère le score du joueur. + * + * Commence à 100, diminue à chaque seconde et à chaque erreur, + * augmente à chaque bonne lettre et ajoute un bonus si le mot est trouvé. + * Si le joueur perd, le score devient 0. + */ +public class Score { + + private int currentScore; + private JLabel scoreLabel; + + /** Constructeur : initialise le score à 100 */ + public Score() { + this.currentScore = 100; + this.scoreLabel = new JLabel("Score : " + currentScore); + this.scoreLabel.setFont(new Font("Arial", Font.BOLD, 16)); + this.scoreLabel.setHorizontalAlignment(SwingConstants.RIGHT); + } + + /** Décrémente le score de 1 point chaque seconde */ + public void decreaseBySecond() { + currentScore = Math.max(0, currentScore - 1); + updateLabel(); + } + + /** Décrémente le score de 5 points pour une mauvaise lettre */ + public void decreaseByWrongLetter() { + currentScore = Math.max(0, currentScore - 5); + updateLabel(); + } + + /** Incrémente le score de 10 points pour une bonne lettre */ + public void increaseByCorrectLetter() { + currentScore += 10; + updateLabel(); + } + + /** Incrémente le score de 50 points si le mot est trouvé */ + public void increaseByWordFound() { + currentScore += 50; + updateLabel(); + } + + /** Met le score à zéro (utilisé si le joueur perd) */ + public void setScoreToZero() { + currentScore = 0; + updateLabel(); + } + + /** Met à jour le texte du JLabel */ + private void updateLabel() { + scoreLabel.setText("Score : " + currentScore); + } + + /** @return le JLabel contenant le score */ + public JLabel getScoreLabel() { + return scoreLabel; + } + + /** @return le score actuel */ + public int getCurrentScore() { + return currentScore; + } +}