diff --git a/TestV2/ressources/sounds/Music/mainMenuMusic.wav b/TestV2/ressources/sounds/Music/mainMenuMusic.wav new file mode 100644 index 0000000..f00f883 Binary files /dev/null and b/TestV2/ressources/sounds/Music/mainMenuMusic.wav differ diff --git a/TestV2/ressources/sounds/SFX/1.mp3 b/TestV2/ressources/sounds/SFX/1.mp3 new file mode 100644 index 0000000..6ae6339 Binary files /dev/null and b/TestV2/ressources/sounds/SFX/1.mp3 differ diff --git a/TestV2/src/fr/monkhanny/dorfromantik/Main.java b/TestV2/src/fr/monkhanny/dorfromantik/Main.java index 6d6813d..91faeba 100644 --- a/TestV2/src/fr/monkhanny/dorfromantik/Main.java +++ b/TestV2/src/fr/monkhanny/dorfromantik/Main.java @@ -1,14 +1,17 @@ package fr.monkhanny.dorfromantik; import fr.monkhanny.dorfromantik.gui.MainMenu; -import fr.monkhanny.dorfromantik.controller.MainMenuController; +import fr.monkhanny.dorfromantik.controller.MainMenuResizeController; +import fr.monkhanny.dorfromantik.controller.MainMenuButtonController; +import fr.monkhanny.dorfromantik.utils.MusicPlayer; +import fr.monkhanny.dorfromantik.enums.Musics; /** * Classe principale du jeu * @version 1.0 * @author Moncef STITI * @see MainMenu - * @see MainMenuController + * @see MainMenuResizeController */ public class Main { /** @@ -16,7 +19,9 @@ public class Main { * @param args Tableau de String contenant les arguments passé en paramètre au programme */ public static void main(String[] args) { + MusicPlayer.play(); MainMenu mainMenu = new MainMenu(); - MainMenuController mainMenuController = new MainMenuController(mainMenu); + MainMenuResizeController MainMenuResizeController = new MainMenuResizeController(mainMenu); + MainMenuButtonController MainMenuButtonController = new MainMenuButtonController(mainMenu); } } diff --git a/TestV2/src/fr/monkhanny/dorfromantik/Options.java b/TestV2/src/fr/monkhanny/dorfromantik/Options.java index e79488b..a69a690 100644 --- a/TestV2/src/fr/monkhanny/dorfromantik/Options.java +++ b/TestV2/src/fr/monkhanny/dorfromantik/Options.java @@ -1,7 +1,29 @@ package fr.monkhanny.dorfromantik; public class Options { - public static final float BASE_TITLE_FONT_SIZE = 70f; - + + /** + * Taille de police de base pour les titres du menu principal + */ + public static final float BASE_TITLE_FONT_SIZE = 90f; + + /** + * Taille de police de base pour les boutons du menu principal + */ public static final float BASE_BUTTON_FONT_SIZE = 50f; + + /** + * Niveau de volume par défaut + */ + public static final int DEFAULT_VOLUME = 60; + + /** + * Musique en sourdine ou non + */ + public static final boolean MUSIC_MUTED = false; + + /** + * Sons en sourdine ou non + */ + public static final boolean SOUNDS_MUTED = false; } diff --git a/TestV2/src/fr/monkhanny/dorfromantik/components/Button.java b/TestV2/src/fr/monkhanny/dorfromantik/components/Button.java index 48b2028..75affe7 100644 --- a/TestV2/src/fr/monkhanny/dorfromantik/components/Button.java +++ b/TestV2/src/fr/monkhanny/dorfromantik/components/Button.java @@ -7,7 +7,7 @@ import java.awt.*; public class Button { - public static JButton createStyledButton(String text, float fontSize) { + public static JButton createCustomTextButton(String text, float fontSize) { JButton button = new JButton(text); button.setFocusPainted(false); // Retirer le focus button.setBackground(new Color(102, 178, 255)); // Couleur de fond @@ -16,4 +16,33 @@ public class Button { button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); // Espacement autour du texte du bouton return button; } + + public static JButton createCustomIconButton(String iconPath) { + // Créer le bouton + JButton button = new JButton(); + button.setFocusPainted(false); // Retirer le focus + + // Charger l'icône depuis le chemin spécifié + ImageIcon icon = new ImageIcon(iconPath); + + // Calculer automatiquement la taille de l'icône pour l'adapter à la taille du bouton + int buttonWidth = 100; // Taille du bouton (largeur) + int buttonHeight = 100; // Taille du bouton (hauteur) + + // Vous pouvez ajuster ces valeurs ou les calculer dynamiquement en fonction de la taille du bouton + Image img = icon.getImage(); + Image resizedImage = img.getScaledInstance(buttonWidth, buttonHeight, Image.SCALE_SMOOTH); + button.setIcon(new ImageIcon(resizedImage)); + + // Optionnel : changer la couleur de fond ou de bordure si nécessaire + button.setBackground(new Color(102, 178, 255)); // Couleur de fond (facultatif) + + // Retirer la bordure du bouton (facultatif) + button.setBorder(BorderFactory.createEmptyBorder()); + + // Redimensionner le bouton pour s'adapter à l'icône si nécessaire + button.setPreferredSize(new Dimension(buttonWidth, buttonHeight)); + + return button; + } } diff --git a/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuButtonController.java b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuButtonController.java new file mode 100644 index 0000000..ea73b1b --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuButtonController.java @@ -0,0 +1,75 @@ +package fr.monkhanny.dorfromantik.controller; + +import fr.monkhanny.dorfromantik.gui.MainMenu; +import fr.monkhanny.dorfromantik.gui.ButtonPanel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MainMenuButtonController implements ActionListener { + + private MainMenu mainMenu; + + public MainMenuButtonController(MainMenu mainMenu) { + this.mainMenu = mainMenu; + // Ajouter les écouteurs d'événements sur les boutons + ButtonPanel buttonPanel = mainMenu.getButtonPanel(); + + // Attacher les actions aux boutons + buttonPanel.getNewGameButton().addActionListener(this); + buttonPanel.getContinueGameButton().addActionListener(this); + buttonPanel.getHowToPlayButton().addActionListener(this); + buttonPanel.getSettingsButton().addActionListener(this); + buttonPanel.getExitButton().addActionListener(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + String command = e.getActionCommand(); + + switch (command) { + case "Nouvelle partie": + startNewGame(); + break; + case "Continuer une partie": + continueGame(); + break; + case "Comment jouer ?": + showHowToPlay(); + break; + case "Paramètres": + openSettings(); + break; + case "Quitter": + exitGame(); + break; + default: + System.out.println("Commande inconnue: " + command); + break; + } + } + + private void startNewGame() { + System.out.println("Démarrer une nouvelle partie..."); + // Logic to start a new game + } + + private void continueGame() { + System.out.println("Continuer une partie..."); + // Logic to continue the game + } + + private void showHowToPlay() { + System.out.println("Afficher comment jouer..."); + // Logic to show how to play + } + + private void openSettings() { + System.out.println("Ouvrir les paramètres..."); + // Logic to open settings + } + + private void exitGame() { + System.exit(0); // Fermer l'application + } +} diff --git a/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuMouseController.java b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuMouseController.java new file mode 100644 index 0000000..d79fa3a --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuMouseController.java @@ -0,0 +1,94 @@ +package fr.monkhanny.dorfromantik.controller; + +import fr.monkhanny.dorfromantik.gui.ButtonPanel; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class MainMenuMouseController { + + private final ButtonPanel buttonPanel; + + // Couleur et échelle au survol + private static final Color BUTTON_HOVER_COLOR = new Color(70, 130, 180); + private static final float HOVER_FONT_SCALE = 1.1f; + private static final int ANIMATION_STEPS = 10; + private static final int ANIMATION_DELAY = 15; // Délai entre chaque étape en ms + + public MainMenuMouseController(ButtonPanel buttonPanel) { + this.buttonPanel = buttonPanel; + initMouseListeners(); + } + + private void initMouseListeners() { + buttonPanel.getNewGameButton().addMouseListener(new ButtonHoverListener(buttonPanel.getNewGameButton())); + buttonPanel.getContinueGameButton().addMouseListener(new ButtonHoverListener(buttonPanel.getContinueGameButton())); + buttonPanel.getHowToPlayButton().addMouseListener(new ButtonHoverListener(buttonPanel.getHowToPlayButton())); + buttonPanel.getSettingsButton().addMouseListener(new ButtonHoverListener(buttonPanel.getSettingsButton())); + buttonPanel.getExitButton().addMouseListener(new ButtonHoverListener(buttonPanel.getExitButton())); + } + + // Classe interne pour la gestion des événements de survol de la souris avec animation + private static class ButtonHoverListener extends MouseAdapter { + private final JButton button; + private final Color originalColor; + private final Font originalFont; + private Timer animationTimer; + private boolean isHovered = false; + private float currentScale = 1.0f; + + public ButtonHoverListener(JButton button) { + this.button = button; + this.originalColor = button.getForeground(); + this.originalFont = button.getFont(); + } + + @Override + public void mouseEntered(MouseEvent e) { + isHovered = true; + startAnimation(true); + } + + @Override + public void mouseExited(MouseEvent e) { + isHovered = false; + startAnimation(false); + } + + private void startAnimation(boolean entering) { + if (animationTimer != null && animationTimer.isRunning()) { + animationTimer.stop(); + } + + animationTimer = new Timer(ANIMATION_DELAY, new ActionListener() { + int step = 0; + final float scaleIncrement = (HOVER_FONT_SCALE - 1.0f) / ANIMATION_STEPS; + + @Override + public void actionPerformed(ActionEvent e) { + // Calculer la nouvelle échelle du texte + currentScale = entering ? (1.0f + step * scaleIncrement) : (HOVER_FONT_SCALE - step * scaleIncrement); + + // Mettre à jour la couleur et la police + button.setForeground(entering ? BUTTON_HOVER_COLOR : originalColor); + button.setFont(originalFont.deriveFont(originalFont.getSize2D() * currentScale)); + + // Augmenter le compteur d'étapes + step++; + if (step >= ANIMATION_STEPS) { + animationTimer.stop(); + if (!entering) { + // Restaurer la police d'origine après l'animation de sortie + button.setFont(originalFont); + } + } + } + }); + animationTimer.start(); + } + } +} diff --git a/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuController.java b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuResizeController.java similarity index 90% rename from TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuController.java rename to TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuResizeController.java index da80f4b..ecf820f 100644 --- a/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuController.java +++ b/TestV2/src/fr/monkhanny/dorfromantik/controller/MainMenuResizeController.java @@ -6,11 +6,11 @@ import fr.monkhanny.dorfromantik.Options; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -public class MainMenuController { +public class MainMenuResizeController { private MainMenu mainMenu; - public MainMenuController(MainMenu mainMenu) { + public MainMenuResizeController(MainMenu mainMenu) { this.mainMenu = mainMenu; addComponentListener(); } diff --git a/TestV2/src/fr/monkhanny/dorfromantik/enums/Images.java b/TestV2/src/fr/monkhanny/dorfromantik/enums/Images.java new file mode 100644 index 0000000..86ecb05 --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/enums/Images.java @@ -0,0 +1,17 @@ +package fr.monkhanny.dorfromantik.enums; + + +public enum Images { + SETTINGS_ICON, EXIT_ICON; + + public String getImagePath() { + switch (this) { + case SETTINGS_ICON: + return "./ressources/images/Icone/SettingsIcon.png"; + case EXIT_ICON: + return "./ressources/images/Icone/ExitIcon.png"; + default: + throw new IllegalArgumentException("Unexpected value: " + this); + } + } +} \ No newline at end of file diff --git a/TestV2/src/fr/monkhanny/dorfromantik/enums/Musics.java b/TestV2/src/fr/monkhanny/dorfromantik/enums/Musics.java new file mode 100644 index 0000000..219f064 --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/enums/Musics.java @@ -0,0 +1,14 @@ +package fr.monkhanny.dorfromantik.enums; + +public enum Musics { + MAIN_MENU_MUSIC; + + public String getSoundsPath() { + switch (this) { + case MAIN_MENU_MUSIC: + return "./ressources/sounds/Music/mainMenuMusic.wav"; + default: + throw new IllegalArgumentException("Unexpected value: " + this); + } + } +} \ No newline at end of file diff --git a/TestV2/src/fr/monkhanny/dorfromantik/enums/Sounds.java b/TestV2/src/fr/monkhanny/dorfromantik/enums/Sounds.java new file mode 100644 index 0000000..a94115d --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/enums/Sounds.java @@ -0,0 +1,16 @@ +package fr.monkhanny.dorfromantik.enums; + +public enum Sounds { + SOUNDS1, SOUNDS2; + + public String getSoundsPath() { + switch (this) { + case SOUNDS1: + return "./ressources/sounds/SFX/1.mp3"; + case SOUNDS2: + return "./ressources/sounds/SFX/2.mp3"; + default: + throw new IllegalArgumentException("Unexpected value: " + this); + } + } +} \ No newline at end of file diff --git a/TestV2/src/fr/monkhanny/dorfromantik/gui/ButtonPanel.java b/TestV2/src/fr/monkhanny/dorfromantik/gui/ButtonPanel.java index 1611b72..bb0890c 100644 --- a/TestV2/src/fr/monkhanny/dorfromantik/gui/ButtonPanel.java +++ b/TestV2/src/fr/monkhanny/dorfromantik/gui/ButtonPanel.java @@ -2,6 +2,7 @@ package fr.monkhanny.dorfromantik.gui; import fr.monkhanny.dorfromantik.utils.FontManager; import fr.monkhanny.dorfromantik.components.Button; +import fr.monkhanny.dorfromantik.controller.MainMenuMouseController; import javax.swing.*; import java.awt.*; @@ -11,6 +12,8 @@ public class ButtonPanel extends JPanel { private JButton newGameButton; private JButton continueGameButton; private JButton howToPlayButton; + private JButton settingsButton; + private JButton exitButton; public ButtonPanel(float fontSize) { // Paramétrage de l'apparence du panneau @@ -22,9 +25,11 @@ public class ButtonPanel extends JPanel { this.add(Box.createVerticalGlue()); // Créer les boutons avec un style personnalisé - newGameButton = Button.createStyledButton("Nouvelle partie", fontSize); - continueGameButton = Button.createStyledButton("Continuer une partie", fontSize); - howToPlayButton = Button.createStyledButton("Comment jouer ?", fontSize); + newGameButton = Button.createCustomTextButton("Nouvelle partie", fontSize); + continueGameButton = Button.createCustomTextButton("Continuer une partie", fontSize); + howToPlayButton = Button.createCustomTextButton("Comment jouer ?", fontSize); + settingsButton = Button.createCustomTextButton("Paramètres", fontSize); + exitButton = Button.createCustomTextButton("Quitter", fontSize); // Ajouter les boutons au panneau this.add(newGameButton); @@ -32,9 +37,15 @@ public class ButtonPanel extends JPanel { this.add(continueGameButton); this.add(Box.createVerticalStrut(20)); this.add(howToPlayButton); + this.add(Box.createVerticalStrut(20)); + this.add(settingsButton); + this.add(Box.createVerticalStrut(20)); + this.add(exitButton); // Espacement extensible pour maintenir les icônes en bas this.add(Box.createVerticalGlue()); + + MainMenuMouseController gestionSouris = new MainMenuMouseController(this); } public JButton getNewGameButton() { @@ -49,11 +60,21 @@ public class ButtonPanel extends JPanel { return howToPlayButton; } + public JButton getSettingsButton() { + return settingsButton; + } + + public JButton getExitButton() { + return exitButton; + } + public void updateButtonFonts(int windowWidth) { // Mettre à jour la police des boutons avec la taille ajustée float newFontSize = windowWidth / 30f; newGameButton.setFont(FontManager.getTitleFont(newFontSize)); continueGameButton.setFont(FontManager.getTitleFont(newFontSize)); howToPlayButton.setFont(FontManager.getTitleFont(newFontSize)); + settingsButton.setFont(FontManager.getTitleFont(newFontSize)); + exitButton.setFont(FontManager.getTitleFont(newFontSize)); } } diff --git a/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicLoader.java b/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicLoader.java new file mode 100644 index 0000000..0216894 --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicLoader.java @@ -0,0 +1,23 @@ +package fr.monkhanny.dorfromantik.utils; + +import javax.sound.sampled.*; +import java.io.File; +import java.io.IOException; + +public class MusicLoader { + + public static Clip loadMusic(String filePath) { + try { + File musicFile = new File(filePath); + AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile); + Clip clip = AudioSystem.getClip(); + clip.open(audioStream); + return clip; + } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) { + e.printStackTrace(); + System.err.println("Failed to load music at path: " + filePath); + return null; + } + } + +} \ No newline at end of file diff --git a/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicPlayer.java b/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicPlayer.java new file mode 100644 index 0000000..e29cafd --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/utils/MusicPlayer.java @@ -0,0 +1,57 @@ +package fr.monkhanny.dorfromantik.utils; + +import fr.monkhanny.dorfromantik.enums.Musics; +import fr.monkhanny.dorfromantik.Options; + +import javax.sound.sampled.Clip; +import javax.sound.sampled.FloatControl; + +public class MusicPlayer { + private static Clip musicClip; + private static boolean isPlaying = false; + + public static void loadMusic(Musics music) { + if (music == Musics.MAIN_MENU_MUSIC) { + musicClip = MusicLoader.loadMusic(Musics.MAIN_MENU_MUSIC.getSoundsPath()); + if (musicClip != null) { + setVolume(Options.DEFAULT_VOLUME); + } + } + } + + public static void play() { + loadMusic(Musics.MAIN_MENU_MUSIC); + if (musicClip != null && !isPlaying) { + musicClip.start(); + isPlaying = true; + } + } + + public static void pause() { + if (musicClip != null && isPlaying) { + musicClip.stop(); + isPlaying = false; + } + } + + public static void stop() { + if (musicClip != null) { + musicClip.stop(); + musicClip.setFramePosition(0); + isPlaying = false; + } + } + + public static void setVolume(int volume) { + if (musicClip != null) { + FloatControl volumeControl = (FloatControl) musicClip.getControl(FloatControl.Type.MASTER_GAIN); + float range = volumeControl.getMaximum() - volumeControl.getMinimum(); + float gain = (range * volume / 100f) + volumeControl.getMinimum(); + volumeControl.setValue(gain); + } + } + + public static boolean isPlaying() { + return isPlaying; + } +} \ No newline at end of file diff --git a/TestV2/src/fr/monkhanny/dorfromantik/utils/SoundLoader.java b/TestV2/src/fr/monkhanny/dorfromantik/utils/SoundLoader.java new file mode 100644 index 0000000..153bb3e --- /dev/null +++ b/TestV2/src/fr/monkhanny/dorfromantik/utils/SoundLoader.java @@ -0,0 +1,23 @@ +package fr.monkhanny.dorfromantik.utils; + +import javax.sound.sampled.*; +import java.io.File; +import java.io.IOException; + +public class SoundLoader { + + public static Clip loadMusic(String filePath) { + try { + File musicFile = new File(filePath); + AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile); + Clip clip = AudioSystem.getClip(); + clip.open(audioStream); + return clip; + } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) { + e.printStackTrace(); + System.err.println("Failed to load sound at path: " + filePath); + return null; + } + } + +} \ No newline at end of file