Ajout d'effet sonnore dans le menu principal)

This commit is contained in:
2024-11-06 19:24:55 +01:00
parent 2c84169d7f
commit 13705cc751
15 changed files with 214 additions and 139 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -19,7 +19,8 @@ public class Main {
* @param args Tableau de String contenant les arguments passé en paramètre au programme * @param args Tableau de String contenant les arguments passé en paramètre au programme
*/ */
public static void main(String[] args) { public static void main(String[] args) {
MusicPlayer.play(); MusicPlayer.loadMusic(Musics.MAIN_MENU_MUSIC);
MusicPlayer.playMusic();
MainMenu mainMenu = new MainMenu(); MainMenu mainMenu = new MainMenu();
MainMenuResizeController MainMenuResizeController = new MainMenuResizeController(mainMenu); MainMenuResizeController MainMenuResizeController = new MainMenuResizeController(mainMenu);
MainMenuButtonController MainMenuButtonController = new MainMenuButtonController(mainMenu); MainMenuButtonController MainMenuButtonController = new MainMenuButtonController(mainMenu);

View File

@@ -1,16 +1,18 @@
package fr.monkhanny.dorfromantik; package fr.monkhanny.dorfromantik;
import java.awt.Color;
public class Options { public class Options {
/** /**
* Taille de police de base pour les titres du menu principal * Taille de police de base pour les titres du menu principal
*/ */
public static final float BASE_TITLE_FONT_SIZE = 90f; public static final float BASE_TITLE_FONT_SIZE = 80f;
/** /**
* Taille de police de base pour les boutons du menu principal * Taille de police de base pour les boutons du menu principal
*/ */
public static final float BASE_BUTTON_FONT_SIZE = 50f; public static final float BASE_BUTTON_FONT_SIZE = 45f;
/** /**
* Niveau de volume par défaut * Niveau de volume par défaut
@@ -26,4 +28,14 @@ public class Options {
* Sons en sourdine ou non * Sons en sourdine ou non
*/ */
public static final boolean SOUNDS_MUTED = false; public static final boolean SOUNDS_MUTED = false;
/**
* Couleur de subrillance des boutons
*/
public static final Color BUTTON_HOVER_COLOR = new Color(70, 130, 180);
public static final float HOVER_FONT_SCALE = 1.1f;
public static final int ANIMATION_STEPS = 10;
public static final int ANIMATION_DELAY = 15;
} }

View File

@@ -0,0 +1,43 @@
package fr.monkhanny.dorfromantik.gui;
import fr.monkhanny.dorfromantik.Options;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ButtonHoverAnimationListener implements ActionListener {
private int step = 0;
private final float scaleIncrement;
private final boolean entering;
private final JButton button;
private final Color originalColor;
private final Font originalFont;
private float currentScale = 1.0f;
public ButtonHoverAnimationListener(boolean entering, JButton button, Color originalColor, Font originalFont) {
this.entering = entering;
this.button = button;
this.originalColor = originalColor;
this.originalFont = originalFont;
this.scaleIncrement = (Options.HOVER_FONT_SCALE - 1.0f) / Options.ANIMATION_STEPS;
}
@Override
public void actionPerformed(ActionEvent e) {
currentScale = entering ? (1.0f + step * scaleIncrement) : (Options.HOVER_FONT_SCALE - step * scaleIncrement);
button.setForeground(entering ? Options.BUTTON_HOVER_COLOR : originalColor);
button.setFont(originalFont.deriveFont(originalFont.getSize2D() * currentScale));
step++;
if (step >= Options.ANIMATION_STEPS) {
((Timer) e.getSource()).stop();
if (!entering) {
button.setFont(originalFont); // Restore the original font
}
}
}
}

View File

@@ -0,0 +1,29 @@
package fr.monkhanny.dorfromantik.controller;
import fr.monkhanny.dorfromantik.gui.ButtonHoverAnimator;
import fr.monkhanny.dorfromantik.utils.MusicPlayer;
import fr.monkhanny.dorfromantik.enums.Sounds;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ButtonHoverListener extends MouseAdapter {
private final ButtonHoverAnimator animator;
public ButtonHoverListener(ButtonHoverAnimator animator) {
this.animator = animator;
}
@Override
public void mouseEntered(MouseEvent e) {
animator.startAnimation(true);
MusicPlayer.loadSound(Sounds.SOUNDS1); // Charge le son
MusicPlayer.playSound(); // Joue le son
}
@Override
public void mouseExited(MouseEvent e) {
animator.startAnimation(false);
}
}

View File

@@ -1,11 +1,9 @@
package fr.monkhanny.dorfromantik.controller; package fr.monkhanny.dorfromantik.controller;
import fr.monkhanny.dorfromantik.gui.ButtonPanel; import fr.monkhanny.dorfromantik.gui.ButtonPanel;
import fr.monkhanny.dorfromantik.gui.ButtonHoverAnimator;
import javax.swing.*; 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.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
@@ -13,82 +11,21 @@ public class MainMenuMouseController {
private final ButtonPanel buttonPanel; 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) { public MainMenuMouseController(ButtonPanel buttonPanel) {
this.buttonPanel = buttonPanel; this.buttonPanel = buttonPanel;
initMouseListeners(); initMouseListeners();
} }
private void initMouseListeners() { private void initMouseListeners() {
buttonPanel.getNewGameButton().addMouseListener(new ButtonHoverListener(buttonPanel.getNewGameButton())); addButtonHoverListener(buttonPanel.getNewGameButton());
buttonPanel.getContinueGameButton().addMouseListener(new ButtonHoverListener(buttonPanel.getContinueGameButton())); addButtonHoverListener(buttonPanel.getContinueGameButton());
buttonPanel.getHowToPlayButton().addMouseListener(new ButtonHoverListener(buttonPanel.getHowToPlayButton())); addButtonHoverListener(buttonPanel.getHowToPlayButton());
buttonPanel.getSettingsButton().addMouseListener(new ButtonHoverListener(buttonPanel.getSettingsButton())); addButtonHoverListener(buttonPanel.getSettingsButton());
buttonPanel.getExitButton().addMouseListener(new ButtonHoverListener(buttonPanel.getExitButton())); addButtonHoverListener(buttonPanel.getExitButton());
} }
// Classe interne pour la gestion des événements de survol de la souris avec animation private void addButtonHoverListener(JButton button) {
private static class ButtonHoverListener extends MouseAdapter { ButtonHoverAnimator animator = new ButtonHoverAnimator(button);
private final JButton button; button.addMouseListener(new ButtonHoverListener(animator));
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();
}
} }
} }

View File

@@ -1,31 +1,19 @@
package fr.monkhanny.dorfromantik.controller; package fr.monkhanny.dorfromantik.controller;
import fr.monkhanny.dorfromantik.gui.MainMenu; import fr.monkhanny.dorfromantik.gui.MainMenu;
import fr.monkhanny.dorfromantik.Options;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class MainMenuResizeController { public class MainMenuResizeController {
private MainMenu mainMenu; private MainMenu mainMenu;
private MainMenuResizeHandler resizeHandler;
public MainMenuResizeController(MainMenu mainMenu) { public MainMenuResizeController(MainMenu mainMenu) {
this.mainMenu = mainMenu; this.mainMenu = mainMenu;
this.resizeHandler = new MainMenuResizeHandler(mainMenu);
addComponentListener(); addComponentListener();
} }
private void addComponentListener() { private void addComponentListener() {
mainMenu.addComponentListener(new ComponentAdapter() { mainMenu.addComponentListener(resizeHandler);
@Override
public void componentResized(ComponentEvent e) {
// Ajuster la taille de la police du titre en fonction de la taille de la fenêtre
float newFontSize = Options.BASE_TITLE_FONT_SIZE * (mainMenu.getWidth() / 900f);
mainMenu.getTitleLabel().updateTitleFont(newFontSize);
// Mettre à jour les polices des boutons
mainMenu.getButtonPanel().updateButtonFonts(mainMenu.getWidth());
}
});
} }
} }

View File

@@ -0,0 +1,26 @@
package fr.monkhanny.dorfromantik.controller;
import fr.monkhanny.dorfromantik.gui.MainMenu;
import fr.monkhanny.dorfromantik.Options;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class MainMenuResizeHandler extends ComponentAdapter {
private MainMenu mainMenu;
public MainMenuResizeHandler(MainMenu mainMenu) {
this.mainMenu = mainMenu;
}
@Override
public void componentResized(ComponentEvent e) {
// Ajuster la taille de la police du titre en fonction de la taille de la fenêtre
float newFontSize = Options.BASE_TITLE_FONT_SIZE * (mainMenu.getWidth() / 900f);
mainMenu.getTitleLabel().updateTitleFont(newFontSize);
// Mettre à jour les polices des boutons
mainMenu.getButtonPanel().updateButtonFonts(mainMenu.getWidth());
}
}

View File

@@ -6,9 +6,9 @@ public enum Sounds {
public String getSoundsPath() { public String getSoundsPath() {
switch (this) { switch (this) {
case SOUNDS1: case SOUNDS1:
return "./ressources/sounds/SFX/1.mp3"; return "./ressources/sounds/SFX/1.wav";
case SOUNDS2: case SOUNDS2:
return "./ressources/sounds/SFX/2.mp3"; return "./ressources/sounds/SFX/2.wav";
default: default:
throw new IllegalArgumentException("Unexpected value: " + this); throw new IllegalArgumentException("Unexpected value: " + this);
} }

View File

@@ -0,0 +1,33 @@
package fr.monkhanny.dorfromantik.gui;
import fr.monkhanny.dorfromantik.Options;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ButtonHoverAnimator {
private final JButton button;
private final Color originalColor;
private final Font originalFont;
private Timer animationTimer;
private float currentScale = 1.0f;
public ButtonHoverAnimator(JButton button) {
this.button = button;
this.originalColor = button.getForeground();
this.originalFont = button.getFont();
}
public void startAnimation(boolean entering) {
if (animationTimer != null && animationTimer.isRunning()) {
animationTimer.stop();
}
// Create a new ActionListener instance
animationTimer = new Timer(Options.ANIMATION_DELAY, new ButtonHoverAnimationListener(entering, button, originalColor, originalFont));
animationTimer.start();
}
}

View File

@@ -33,13 +33,13 @@ public class ButtonPanel extends JPanel {
// Ajouter les boutons au panneau // Ajouter les boutons au panneau
this.add(newGameButton); this.add(newGameButton);
this.add(Box.createVerticalStrut(20)); // Espace entre les boutons this.add(Box.createVerticalStrut(10)); // Espace entre les boutons
this.add(continueGameButton); this.add(continueGameButton);
this.add(Box.createVerticalStrut(20)); this.add(Box.createVerticalStrut(10));
this.add(howToPlayButton); this.add(howToPlayButton);
this.add(Box.createVerticalStrut(20)); this.add(Box.createVerticalStrut(10));
this.add(settingsButton); this.add(settingsButton);
this.add(Box.createVerticalStrut(20)); this.add(Box.createVerticalStrut(25));
this.add(exitButton); this.add(exitButton);
// Espacement extensible pour maintenir les icônes en bas // Espacement extensible pour maintenir les icônes en bas

View File

@@ -1,23 +0,0 @@
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;
}
}
}

View File

@@ -1,57 +1,86 @@
package fr.monkhanny.dorfromantik.utils; package fr.monkhanny.dorfromantik.utils;
import fr.monkhanny.dorfromantik.enums.Musics; import fr.monkhanny.dorfromantik.enums.Musics;
import fr.monkhanny.dorfromantik.enums.Sounds;
import fr.monkhanny.dorfromantik.Options; import fr.monkhanny.dorfromantik.Options;
import javax.sound.sampled.Clip; import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.FloatControl; import javax.sound.sampled.FloatControl;
public class MusicPlayer { public class MusicPlayer {
private static Clip musicClip; private static Clip musicClip;
private static boolean isPlaying = false; private static Clip soundClip; // Clip séparé pour les bruitages
private static boolean isPlayingMusic = false;
private static boolean isPlayingSound = false;
public static void loadMusic(Musics music) { public static void loadMusic(Musics music) {
if (music == Musics.MAIN_MENU_MUSIC) { if (music == Musics.MAIN_MENU_MUSIC) {
musicClip = MusicLoader.loadMusic(Musics.MAIN_MENU_MUSIC.getSoundsPath()); musicClip = SoundLoader.loadMusic(Musics.MAIN_MENU_MUSIC.getSoundsPath());
if (musicClip != null) { if (musicClip != null) {
setVolume(Options.DEFAULT_VOLUME); setVolume(musicClip, Options.DEFAULT_VOLUME);
} }
} }
} }
public static void play() { public static void loadSound(Sounds sound) {
loadMusic(Musics.MAIN_MENU_MUSIC); if (sound == Sounds.SOUNDS1) {
if (musicClip != null && !isPlaying) { soundClip = SoundLoader.loadMusic(Sounds.SOUNDS1.getSoundsPath()); // Utilise soundClip pour les bruitages
if (soundClip != null) {
setVolume(soundClip, Options.DEFAULT_VOLUME);
}
}
}
public static void playMusic() {
if (musicClip != null && !isPlayingMusic) {
musicClip.start(); musicClip.start();
isPlaying = true; isPlayingMusic = true;
} }
} }
public static void pause() { public static void playSound() {
if (musicClip != null && isPlaying) { if (soundClip != null && !isPlayingSound) {
soundClip.start();
isPlayingSound = true;
soundClip.addLineListener(event -> { // Réinitialiser isPlayingSound à la fin du son
if (event.getType() == LineEvent.Type.STOP) {
soundClip.setFramePosition(0); // Retour au début du son pour rejouer si nécessaire
isPlayingSound = false;
}
});
}
}
public static void pauseMusic() {
if (musicClip != null && isPlayingMusic) {
musicClip.stop(); musicClip.stop();
isPlaying = false; isPlayingMusic = false;
} }
} }
public static void stop() { public static void stopMusic() {
if (musicClip != null) { if (musicClip != null) {
musicClip.stop(); musicClip.stop();
musicClip.setFramePosition(0); musicClip.setFramePosition(0);
isPlaying = false; isPlayingMusic = false;
} }
} }
public static void setVolume(int volume) { public static void setVolume(Clip clip, int volume) {
if (musicClip != null) { if (clip != null) {
FloatControl volumeControl = (FloatControl) musicClip.getControl(FloatControl.Type.MASTER_GAIN); FloatControl volumeControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
float range = volumeControl.getMaximum() - volumeControl.getMinimum(); float range = volumeControl.getMaximum() - volumeControl.getMinimum();
float gain = (range * volume / 100f) + volumeControl.getMinimum(); float gain = (range * volume / 100f) + volumeControl.getMinimum();
volumeControl.setValue(gain); volumeControl.setValue(gain);
} }
} }
public static boolean isPlaying() { public static boolean isPlayingMusic() {
return isPlaying; return isPlayingMusic;
}
public static boolean isPlayingSound() {
return isPlayingSound;
} }
} }

View File

@@ -8,8 +8,8 @@ public class SoundLoader {
public static Clip loadMusic(String filePath) { public static Clip loadMusic(String filePath) {
try { try {
File musicFile = new File(filePath); File soundFile = new File(filePath);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile); AudioInputStream audioStream = AudioSystem.getAudioInputStream(soundFile);
Clip clip = AudioSystem.getClip(); Clip clip = AudioSystem.getClip();
clip.open(audioStream); clip.open(audioStream);
return clip; return clip;