added different music for different game states

This commit is contained in:
Timo Brennförder
2024-10-05 20:56:26 +02:00
parent 329d3d7372
commit dac84388fc
18 changed files with 236 additions and 28 deletions

View File

@@ -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);
}

View File

@@ -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);
}
/**

View File

@@ -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

View File

@@ -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();
}

View File

@@ -0,0 +1 @@
Aluminum | Roie Shpigler | https://artlist.io/royalty-free-music/song/aluminum/122360

View File

@@ -0,0 +1 @@
A Touch of Dream | Max H. | https://artlist.io/royalty-free-music/song/a-touch-of-dream/126111

View File

@@ -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/

View File

@@ -0,0 +1 @@
Victory march of Valor | Land_of_Books_YouTube | https://pixabay.com/users/land_of_books_youtube-7733644/s

View File

@@ -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()));
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}
/**

View File

@@ -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 */ }
}

View File

@@ -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,
}

View File

@@ -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);
}
}