diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/BackgroundMusic.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/BackgroundMusic.java index 5961dd03..69a30d83 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/BackgroundMusic.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/BackgroundMusic.java @@ -4,71 +4,196 @@ import com.jme3.audio.AudioData.DataType; import com.jme3.audio.AudioNode; import com.jme3.audio.AudioSource.Status; +import pp.battleship.notification.Music; +import pp.battleship.notification.MusicEvent; +import pp.battleship.notification.GameEventListener; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; import java.util.prefs.Preferences; -public class BackgroundMusic { +public class BackgroundMusic implements GameEventListener { private static final String VOLUME_PREF = "volume"; private static final String MUSIC_ENABLED_PREF = "musicEnabled"; private final Preferences pref = Preferences.userNodeForPackage(BackgroundMusic.class); + static final Logger LOGGER = System.getLogger(BackgroundMusic.class.getName()); - - private final AudioNode backgroundMusic; + private static final String MENU_MUSIC = "Sound/Music/menu/cinematictrailerelite.ogg"; + private static final String GAME_MUSIC = "Sound/Music/game/Aluminum.ogg"; + private static final String VICTORY_MUSIC = "Sound/Music/victory/victorymarchofvalor.ogg"; + private static final String LOSE_MUSIC = "Sound/Music/lose/TouchofDream.ogg"; + private final AudioNode menuMusic; + private final AudioNode gameMusic; + private final AudioNode victoryMusic; + private final AudioNode loseMusic; + private String lastPlayedMusic; private boolean musicEnabled; private float volume; + private Application app; /** * Initializes and controls the BackgroundMusic * * @param app The main Application - * @param musicFilePath The Path for the specific background music */ - public BackgroundMusic(Application app, String musicFilePath) { + public BackgroundMusic(Application app) { this.volume = pref.getFloat(VOLUME_PREF, 1.0f); this.musicEnabled = pref.getBoolean(MUSIC_ENABLED_PREF, true); + this.app = app; - backgroundMusic = new AudioNode(app.getAssetManager(), musicFilePath, DataType.Stream); - backgroundMusic.setLooping(true); - backgroundMusic.setPositional(false); - backgroundMusic.setVolume(1.0f); + menuMusic = createMusicNode(MENU_MUSIC); + gameMusic = createMusicNode(GAME_MUSIC); + victoryMusic = createMusicNode(VICTORY_MUSIC); + loseMusic = createMusicNode(LOSE_MUSIC); + stop(gameMusic); + stop(victoryMusic); + stop(loseMusic); + lastPlayedMusic = menuMusic.getName(); if(musicEnabled) { - play(); + play(menuMusic); } } + /** + * creates an audio node for the music + * @param musicFilePath the file path to the music + * @return the created audio node + */ + + private AudioNode createMusicNode(String musicFilePath) { + AudioNode audioNode = new AudioNode(app.getAssetManager(), musicFilePath, DataType.Stream); + audioNode.setVolume(volume); + audioNode.setPositional(false); + audioNode.setLooping(true); + audioNode.setName(musicFilePath); + return audioNode; + } + /** * starts the music + * @param audioNode the audio node to be played */ - public void play() { - if (musicEnabled && (backgroundMusic.getStatus() == Status.Stopped || backgroundMusic.getStatus() == Status.Paused)) { - backgroundMusic.play(); + public void play(AudioNode audioNode) { + if (musicEnabled && (audioNode.getStatus() == Status.Stopped || audioNode.getStatus() == Status.Paused)) { + audioNode.play(); + lastPlayedMusic = audioNode.getName(); } } /** - * Stops the music + * pauses the music + * @param audioNode the audio node to be paused */ - public void stop(){ - if (backgroundMusic.getStatus() == Status.Playing) { - backgroundMusic.stop(); + public void pause(AudioNode audioNode){ + if(audioNode.getStatus() == Status.Playing){ + audioNode.pause(); + } + } + + /** + * stops the music + * @param audioNode the audio node to be stopped + */ + public void stop(AudioNode audioNode){ + if (audioNode.getStatus() == Status.Playing) { + audioNode.stop(); } } /** * Toggle Method to control the music */ - public void toogleMusic() { + public void toggleMusic() { this.musicEnabled = !this.musicEnabled; if (musicEnabled) { - play(); - } else { - stop(); + switch (lastPlayedMusic){ + case MENU_MUSIC: + play(menuMusic); + break; + case GAME_MUSIC: + play(gameMusic); + break; + case VICTORY_MUSIC: + play(victoryMusic); + break; + case LOSE_MUSIC: + play(loseMusic); + break; + } + } + else { + pause(menuMusic); + pause(gameMusic); + pause(victoryMusic); + pause(loseMusic); } - pref.putFloat(VOLUME_PREF, volume); + pref.putBoolean(MUSIC_ENABLED_PREF, musicEnabled); } + /** + * changes the music to the specified music if it isn't already playing + * + * @param music the music to play + */ + public void changeMusic(Music music) { + if(music == Music.MENU_THEME && !lastPlayedMusic.equals(MENU_MUSIC)) { + LOGGER.log(Level.DEBUG, "Received Music change Event {0}", music.toString()); + stop(gameMusic); + stop(victoryMusic); + stop(loseMusic); + play(menuMusic); + lastPlayedMusic = menuMusic.getName(); + } else if (music == Music.GAME_THEME && !lastPlayedMusic.equals(GAME_MUSIC)) { + LOGGER.log(Level.DEBUG, "Received Music change Event {0}", music.toString()); + stop(menuMusic); + stop(loseMusic); + stop(victoryMusic); + play(gameMusic); + lastPlayedMusic = gameMusic.getName(); + } else if (music == Music.VICTORY_THEME && !lastPlayedMusic.equals(VICTORY_MUSIC)) { + LOGGER.log(Level.DEBUG, "Received Music change Event {0}", music.toString()); + stop(menuMusic); + stop(gameMusic); + stop(loseMusic); + play(victoryMusic); + lastPlayedMusic = victoryMusic.getName(); + } else if (music == Music.LOSE_THEME && !lastPlayedMusic.equals(LOSE_MUSIC)){ + LOGGER.log(Level.DEBUG, "Received Music change Event {0}", music.toString()); + stop(menuMusic); + stop(gameMusic); + stop(victoryMusic); + play(loseMusic); + lastPlayedMusic = loseMusic.getName(); + } + } + + /** + * the method which receives the Event + * + * @param music the received Event + */ + @Override + public void receivedEvent (MusicEvent music){ + LOGGER.log(Level.DEBUG, "Received Music change Event {0}", music.toString()); + switch (music.music()){ + case MENU_THEME: + changeMusic(Music.MENU_THEME); + break; + case GAME_THEME: + changeMusic(Music.GAME_THEME); + break; + case VICTORY_THEME: + changeMusic(Music.VICTORY_THEME); + break; + case LOSE_THEME: + changeMusic(Music.LOSE_THEME); + break; + } + } + + /** * Method to set the volume for the music * @@ -76,7 +201,10 @@ public void toogleMusic() { */ public void setVolume(float volume) { this.volume = volume; - backgroundMusic.setVolume(volume); + menuMusic.setVolume(volume); + gameMusic.setVolume(volume); + victoryMusic.setVolume(volume); + loseMusic.setVolume(volume); pref.putFloat(VOLUME_PREF, volume); } diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/BattleshipApp.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/BattleshipApp.java index 4e8101f6..76474e23 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/BattleshipApp.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/BattleshipApp.java @@ -230,7 +230,9 @@ public void simpleInitApp() { setupStates(); setupGui(); serverConnection.connect(); - backgroundMusic = new BackgroundMusic(this, "Sound/Background/Aluminum.ogg"); + backgroundMusic = new BackgroundMusic(this); + logic.addListener(backgroundMusic); + } /** diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java index 72ccb285..7437eb41 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java @@ -28,7 +28,7 @@ * An application state that plays sounds. */ public class GameSound extends AbstractAppState implements GameEventListener { - private static final Logger LOGGER = System.getLogger(GameSound.class.getName()); + static final Logger LOGGER = System.getLogger(GameSound.class.getName()); private static final Preferences PREFERENCES = getPreferences(GameSound.class); private static final String ENABLED_PREF = "enabled"; //NON-NLS diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/Menu.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/Menu.java index 31d5fef0..fe3bccb5 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/Menu.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/Menu.java @@ -100,7 +100,7 @@ private void adjustVolume(double volume) { * this method toggles the background music on and off */ private void toggleMusic() { - app.getBackgroundMusic().toogleMusic(); + app.getBackgroundMusic().toggleMusic(); } diff --git a/Projekte/battleship/client/src/main/resources/Sound/Background/Aluminum.ogg b/Projekte/battleship/client/src/main/resources/Sound/Music/game/Aluminum.ogg similarity index 100% rename from Projekte/battleship/client/src/main/resources/Sound/Background/Aluminum.ogg rename to Projekte/battleship/client/src/main/resources/Sound/Music/game/Aluminum.ogg diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/game/Credits.txt b/Projekte/battleship/client/src/main/resources/Sound/Music/game/Credits.txt new file mode 100644 index 00000000..39308f93 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Sound/Music/game/Credits.txt @@ -0,0 +1 @@ +Aluminum | Roie Shpigler | https://artlist.io/royalty-free-music/song/aluminum/122360 \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/lose/Credits.txt b/Projekte/battleship/client/src/main/resources/Sound/Music/lose/Credits.txt new file mode 100644 index 00000000..24291664 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Sound/Music/lose/Credits.txt @@ -0,0 +1 @@ +A Touch of Dream | Max H. | https://artlist.io/royalty-free-music/song/a-touch-of-dream/126111 \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/lose/TouchofDream.ogg b/Projekte/battleship/client/src/main/resources/Sound/Music/lose/TouchofDream.ogg new file mode 100644 index 00000000..7d33fac7 Binary files /dev/null and b/Projekte/battleship/client/src/main/resources/Sound/Music/lose/TouchofDream.ogg differ diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/menu/Crerdits.txt b/Projekte/battleship/client/src/main/resources/Sound/Music/menu/Crerdits.txt new file mode 100644 index 00000000..f8fd90f2 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Sound/Music/menu/Crerdits.txt @@ -0,0 +1,5 @@ +Epic Cinematic Trailer | ELITE by Alex-Productions | https://onsound.eu/ +Music promoted by https://www.chosic.com/free-music/all/ +Creative Commons CC BY 3.0 +https://creativecommons.org/licenses/by/3.0/ + \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/menu/cinematictrailerelite.ogg b/Projekte/battleship/client/src/main/resources/Sound/Music/menu/cinematictrailerelite.ogg new file mode 100644 index 00000000..c1de9692 Binary files /dev/null and b/Projekte/battleship/client/src/main/resources/Sound/Music/menu/cinematictrailerelite.ogg differ diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/victory/Crerdits.txt b/Projekte/battleship/client/src/main/resources/Sound/Music/victory/Crerdits.txt new file mode 100644 index 00000000..33598a86 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Sound/Music/victory/Crerdits.txt @@ -0,0 +1 @@ +Victory march of Valor | Land_of_Books_YouTube | https://pixabay.com/users/land_of_books_youtube-7733644/s \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Sound/Music/victory/victorymarchofvalor.ogg b/Projekte/battleship/client/src/main/resources/Sound/Music/victory/victorymarchofvalor.ogg new file mode 100644 index 00000000..178779c2 Binary files /dev/null and b/Projekte/battleship/client/src/main/resources/Sound/Music/victory/victorymarchofvalor.ogg differ diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java index 99df8d0b..ab8a227d 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java @@ -11,6 +11,7 @@ import pp.battleship.message.server.EffectMessage; import pp.battleship.model.IntPoint; import pp.battleship.model.ShipMap; +import pp.battleship.notification.Music; import pp.battleship.notification.Sound; import java.lang.System.Logger.Level; @@ -29,6 +30,7 @@ class BattleState extends ClientState { */ public BattleState(ClientGameLogic logic, boolean myTurn) { super(logic); + logic.playMusic(Music.GAME_THEME); this.myTurn = myTurn; } @@ -61,7 +63,7 @@ public void receivedEffect(EffectMessage msg) { logic.getOpponentMap().add(msg.getDestroyedShip()); if (msg.isGameOver()) { msg.getRemainingOpponentShips().forEach(logic.getOpponentMap()::add); - logic.setState(new GameOverState(logic)); + logic.setState(new GameOverState(logic, msg.isGameLost())); } } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java index 3170e8be..ffa17667 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java @@ -20,6 +20,8 @@ import pp.battleship.notification.GameEventBroker; import pp.battleship.notification.GameEventListener; import pp.battleship.notification.InfoTextEvent; +import pp.battleship.notification.Music; +import pp.battleship.notification.MusicEvent; import pp.battleship.notification.Sound; import pp.battleship.notification.SoundEvent; @@ -352,4 +354,12 @@ public void notifyListeners(GameEvent event) { public void update(float delta) { state.update(delta); } + + /** + * Triggers an event to play specified music + * @param music the music to be played + */ + public void playMusic(Music music){ + notifyListeners(new MusicEvent(music)); + } } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/GameOverState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/GameOverState.java index 40d2edec..c54040fd 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/GameOverState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/GameOverState.java @@ -7,6 +7,8 @@ package pp.battleship.game.client; +import pp.battleship.notification.Music; + /** * Represents the state of the client when the game is over. */ @@ -16,8 +18,14 @@ class GameOverState extends ClientState { * * @param logic the client game logic */ - GameOverState(ClientGameLogic logic) { + GameOverState(ClientGameLogic logic, boolean loser) { super(logic); + if(loser){ + logic.playMusic(Music.LOSE_THEME); + } + else { + logic.playMusic(Music.VICTORY_THEME); + } } /** diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/notification/GameEventListener.java b/Projekte/battleship/model/src/main/java/pp/battleship/notification/GameEventListener.java index 4b966793..5b431546 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/notification/GameEventListener.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/notification/GameEventListener.java @@ -45,4 +45,12 @@ default void receivedEvent(SoundEvent event) { /* do nothing */ } * @param event the received event */ default void receivedEvent(ClientStateEvent event) { /* do nothing */ } + + /** + * Indicates that the music gets changed + * + * @param event the received Event + */ + default void receivedEvent(MusicEvent event) { /* do nothing */ } + } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/notification/Music.java b/Projekte/battleship/model/src/main/java/pp/battleship/notification/Music.java new file mode 100644 index 00000000..7c1d9036 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/notification/Music.java @@ -0,0 +1,23 @@ +package pp.battleship.notification; + +/** + * Enumeration representing different types of music used in the game. + */ +public enum Music { + /** + * menu music + */ + MENU_THEME, + /** + * ingame music + */ + GAME_THEME, + /** + * music for a victory + */ + VICTORY_THEME, + /** + * music for a loss + */ + LOSE_THEME, +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/notification/MusicEvent.java b/Projekte/battleship/model/src/main/java/pp/battleship/notification/MusicEvent.java new file mode 100644 index 00000000..f5fa4004 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/notification/MusicEvent.java @@ -0,0 +1,19 @@ +package pp.battleship.notification; + +/** + * Event when background music changes + * + * @param music the music to be played + */ +public record MusicEvent(Music music) implements GameEvent { + + /** + * Notifies the game event listener the music event. + * + * @param listener the game event listener + */ + @Override + public void notifyListener(GameEventListener listener) { + listener.receivedEvent(this); + } +}