diff --git a/Jeu_pendu/Front/Gallows.java b/Jeu_pendu/Front/Gallows.java new file mode 100644 index 0000000..9c9368f --- /dev/null +++ b/Jeu_pendu/Front/Gallows.java @@ -0,0 +1,62 @@ +package front; + +import javax.swing.*; +import java.awt.*; +import java.io.File; + +/** + * Gère les images du pendu (une par étape). + * - Charge les images depuis assets + */ +public class Gallows { + /** Dossier d'assets relatif à la racine du projet */ + private static final String ASSETS_DIR = "assets" + File.separator + "images"; + /** Nombre d'étapes (0 = aucun membre, 7 = étape finale) */ + private static final int MAX_STAGE = 6; + + private static final ImageIcon[] ICONS = new ImageIcon[MAX_STAGE + 1]; + + static { + for (int i = 0; i <= MAX_STAGE; i++) { + String path = ASSETS_DIR + File.separator + i + ".png"; + File f = new File(path); + if (f.exists()) { + ICONS[i] = new ImageIcon(path); + } else { + // Placeholder si fichier manquant + ICONS[i] = placeholder("Missing: " + i + ".png"); + } + } + } + + /** + * Retourne l'icône correspondant au nombre d'erreurs. + */ + public static ImageIcon icon(int errors) { + int idx = Math.max(0, Math.min(errors, MAX_STAGE)); + return ICONS[idx]; + } + + /** + * Crée une petite image placeholder (si un asset est manquant). + */ + private static ImageIcon placeholder(String text) { + int w = 320, h = 240; + Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D) img.getGraphics(); + g.setColor(Color.LIGHT_GRAY); + g.fillRect(0, 0, w, h); + g.setColor(Color.DARK_GRAY); + g.drawRect(0, 0, w - 1, h - 1); + g.drawString(text, 10, h / 2); + g.dispose(); + return new ImageIcon(img); + } + + // Import manquant pour BufferedImage + private static class BufferedImage extends java.awt.image.BufferedImage { + public BufferedImage(int width, int height, int imageType) { + super(width, height, imageType); + } + } +} \ No newline at end of file diff --git a/Jeu_pendu/Front/GameUI.java b/Jeu_pendu/Front/GameUI.java new file mode 100644 index 0000000..2764d5e --- /dev/null +++ b/Jeu_pendu/Front/GameUI.java @@ -0,0 +1,123 @@ +package front; + +import back.*; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +/** + * Interface graphique (Swing) du jeu du pendu. + * - Affiche une image différente à chaque erreur. + * - Champ de saisie pour entrer une lettre. + * - Texte pour le mot masqué et les lettres essayées. + */ +public class GameUI { + private JFrame frame; + private JLabel imgLabel; + private JLabel wordLabel; + private JLabel triedLabel; + private JTextField input; + private JButton tryBtn; + private JButton newGameBtn; + + private Game game; + private String currentWord; + + /** Affiche la fenêtre principale */ + public void show() { + setupUI(); + startNewGame(); + frame.setVisible(true); + } + + /** Initialise les composants Swing */ + private void setupUI() { + frame = new JFrame("Jeu du Pendu"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(520, 520); + frame.setLocationRelativeTo(null); + frame.setLayout(new BorderLayout(12, 12)); + + // Image du pendu + imgLabel = new JLabel("", SwingConstants.CENTER); + frame.add(imgLabel, BorderLayout.CENTER); + + // Panneau bas: saisie + actions + JPanel bottom = new JPanel(new BorderLayout(8, 8)); + JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + input = new JTextField(5); + tryBtn = new JButton("Essayer"); + inputPanel.add(new JLabel("Lettre :")); + inputPanel.add(input); + inputPanel.add(tryBtn); + + newGameBtn = new JButton("Nouvelle partie"); + bottom.add(inputPanel, BorderLayout.WEST); + bottom.add(newGameBtn, BorderLayout.EAST); + frame.add(bottom, BorderLayout.SOUTH); + + // Panneau haut: mot + lettres essayées + JPanel top = new JPanel(); + top.setLayout(new BoxLayout(top, BoxLayout.Y_AXIS)); + wordLabel = new JLabel("Mot : "); + triedLabel = new JLabel("Lettres essayées : "); + wordLabel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + triedLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8)); + top.add(wordLabel); + top.add(triedLabel); + frame.add(top, BorderLayout.NORTH); + + // Actions + tryBtn.addActionListener(this::onTry); + input.addActionListener(this::onTry); + newGameBtn.addActionListener(e -> startNewGame()); + } + + /** Démarre une nouvelle partie */ + private void startNewGame() { + currentWord = Words.random(); + game = new Game(currentWord, 7); + input.setText(""); + input.requestFocusInWindow(); + refreshUI(); + } + + /** Gère le clic sur "Essayer" ou Entrée dans le champ */ + private void onTry(ActionEvent e) { + String text = input.getText(); + if (!Check.isLetter(text)) { + JOptionPane.showMessageDialog(frame, "Tape une seule lettre (A-Z)."); + input.requestFocusInWindow(); + input.selectAll(); + return; + } + char c = Character.toLowerCase(text.charAt(0)); + Result res = game.play(c); + + switch (res) { + case ALREADY -> JOptionPane.showMessageDialog(frame, "Lettre déjà utilisée."); + case HIT -> {} // rien, rafraîchissement visuel suffit + case MISS -> {} // idem + } + + input.setText(""); + refreshUI(); + + if (game.isWin()) { + refreshUI(); + JOptionPane.showMessageDialog(frame, "Bravo ! Le mot était : " + currentWord); + } else if (game.isLose()) { + refreshUI(); + JOptionPane.showMessageDialog(frame, "Perdu ! Le mot était : " + currentWord); + } + } + + /** Met à jour l'image et les textes selon l'état courant */ + private void refreshUI() { + imgLabel.setIcon(Gallows.icon(game.getErrors())); + wordLabel.setText("Mot : " + game.maskedWord()); + triedLabel.setText("Lettres essayées : " + String.join(", ", game.triedLetters())); + frame.repaint(); + } +} + diff --git a/Jeu_pendu/Front/main b/Jeu_pendu/Front/main deleted file mode 100644 index bdf6855..0000000 --- a/Jeu_pendu/Front/main +++ /dev/null @@ -1 +0,0 @@ -blablabla \ No newline at end of file diff --git a/Jeu_pendu/Main/Main.java b/Jeu_pendu/Main/Main.java new file mode 100644 index 0000000..42ac4ae --- /dev/null +++ b/Jeu_pendu/Main/Main.java @@ -0,0 +1,17 @@ +package main; + +import front.GameUI; + +/** + * Point d'entrée du programme. + * Lance l'interface graphique du jeu du pendu. + */ +public class Main { + public static void main(String[] args) { + // Démarre l'UI Swing sur le thread de l'EDT + javax.swing.SwingUtilities.invokeLater(() -> { + GameUI ui = new GameUI(); + ui.show(); + }); + } +} \ No newline at end of file diff --git a/Jeu_pendu/assets/images/0.png b/Jeu_pendu/assets/images/0.png new file mode 100644 index 0000000..9d63d5f Binary files /dev/null and b/Jeu_pendu/assets/images/0.png differ diff --git a/Jeu_pendu/assets/images/1.png b/Jeu_pendu/assets/images/1.png new file mode 100644 index 0000000..0fc7563 Binary files /dev/null and b/Jeu_pendu/assets/images/1.png differ diff --git a/Jeu_pendu/assets/images/2.png b/Jeu_pendu/assets/images/2.png new file mode 100644 index 0000000..f9dbe06 Binary files /dev/null and b/Jeu_pendu/assets/images/2.png differ diff --git a/Jeu_pendu/assets/images/3.png b/Jeu_pendu/assets/images/3.png new file mode 100644 index 0000000..f9ff091 Binary files /dev/null and b/Jeu_pendu/assets/images/3.png differ diff --git a/Jeu_pendu/assets/images/4.png b/Jeu_pendu/assets/images/4.png new file mode 100644 index 0000000..1d81a8a Binary files /dev/null and b/Jeu_pendu/assets/images/4.png differ diff --git a/Jeu_pendu/assets/images/5.png b/Jeu_pendu/assets/images/5.png new file mode 100644 index 0000000..023025e Binary files /dev/null and b/Jeu_pendu/assets/images/5.png differ diff --git a/Jeu_pendu/assets/images/6.png b/Jeu_pendu/assets/images/6.png new file mode 100644 index 0000000..81369e2 Binary files /dev/null and b/Jeu_pendu/assets/images/6.png differ