added background music to the game
- added a class BackgroundMusic: is an AbstractAppState and GameEventListener that handles the backgroundmusic - attached the BackgroundMusic to the stateManager in the BattleshipApp - added to the Menu a CheckBox and Slider to manipulate the volume of the backgroundmusic - added four different music files (for different states of the game) - edited the WaitState and BattleState to play different music files when chaing to that state - added to ClientGameLogic a new method playMusic(Music) to play the right music (depends on the current state) - added a new method receivedEvent(MusicEvent) to handle the music events - added a new enum Music, that represents different types of music - added a new record MusicEvent(Music), that decides which music shall play
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
package pp.battleship.client;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.state.AbstractAppState;
|
||||
import com.jme3.app.state.AppStateManager;
|
||||
import com.jme3.asset.AssetLoadException;
|
||||
import com.jme3.asset.AssetNotFoundException;
|
||||
import com.jme3.audio.AudioData.DataType;
|
||||
import com.jme3.audio.AudioNode;
|
||||
import pp.battleship.notification.GameEventListener;
|
||||
import pp.battleship.notification.MusicEvent;
|
||||
|
||||
import java.lang.System.Logger;
|
||||
import java.lang.System.Logger.Level;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import static pp.util.PreferencesUtils.getPreferences;
|
||||
|
||||
/**
|
||||
* The BackgroundMusic class represents the background music in the Battleship game application.
|
||||
* It extends the AbstractAppState class and provides functionalities for playing the menu music,
|
||||
* game music, victory music, and defeat music.
|
||||
*/
|
||||
public class BackgroundMusic extends AbstractAppState implements GameEventListener {
|
||||
/**
|
||||
* Logger for the BackgroundMusic class.
|
||||
*/
|
||||
private static final Logger LOGGER = System.getLogger(BackgroundMusic.class.getName());
|
||||
|
||||
/**
|
||||
* Preferences for storing music settings.
|
||||
*/
|
||||
private static final Preferences PREFERENCES = getPreferences(BackgroundMusic.class);
|
||||
|
||||
/**
|
||||
* Preference key for enabling/disabling music.
|
||||
*/
|
||||
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
||||
|
||||
/**
|
||||
* Preference key for storing the volume level.
|
||||
*/
|
||||
private static final String VOLUME_PREF = "volume"; //NON-NLS
|
||||
|
||||
/**
|
||||
* Path to the menu music file.
|
||||
*/
|
||||
private static final String MENU_MUSIC_PATH = "Sound/Music/menu_music.ogg";
|
||||
|
||||
/**
|
||||
* Path to the game music file.
|
||||
*/
|
||||
private static final String GAME_MUSIC_PATH = "Sound/Music/pirates.ogg";
|
||||
|
||||
/**
|
||||
* Path to the victory music file.
|
||||
*/
|
||||
private static final String VICTORY_MUSIC_PATH = "Sound/Music/win_the_game.ogg";
|
||||
|
||||
/**
|
||||
* Path to the defeat music file.
|
||||
*/
|
||||
private static final String DEFEAT_MUSIC_PATH = "Sound/Music/defeat.ogg";
|
||||
|
||||
/**
|
||||
* AudioNode for the menu music.
|
||||
*/
|
||||
private AudioNode menuMusic;
|
||||
|
||||
/**
|
||||
* AudioNode for the game music.
|
||||
*/
|
||||
private AudioNode gameMusic;
|
||||
|
||||
/**
|
||||
* AudioNode for the victory music.
|
||||
*/
|
||||
private AudioNode victoryMusic;
|
||||
|
||||
/**
|
||||
* AudioNode for the defeat music.
|
||||
*/
|
||||
private AudioNode defeatMusic;
|
||||
|
||||
/**
|
||||
* The currently playing AudioNode.
|
||||
*/
|
||||
private AudioNode currentMusic;
|
||||
|
||||
/**
|
||||
* The volume level for the background music.
|
||||
*/
|
||||
private float volume;
|
||||
|
||||
/**
|
||||
* Checks if music is enabled in the preferences.
|
||||
*
|
||||
* @return {@code true} if music is enabled, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean enabledInPreferences() {
|
||||
return PREFERENCES.getBoolean(ENABLED_PREF, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled state of this AppState.
|
||||
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
|
||||
*
|
||||
* @param enabled {@code true} to enable the AppState, {@code false} to disable it.
|
||||
*/
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
if (isEnabled() == enabled) return;
|
||||
super.setEnabled(enabled);
|
||||
LOGGER.log(Level.INFO, "Music enabled: {0}", enabled); //NON-NLS
|
||||
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
||||
playCurrentMusic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the music for the game.
|
||||
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
|
||||
*
|
||||
* @param stateManager The state manager
|
||||
* @param app The application
|
||||
*/
|
||||
@Override
|
||||
public void initialize(AppStateManager stateManager, Application app) {
|
||||
LOGGER.log(Level.INFO, "Initializing background music"); //NON-NLS
|
||||
super.initialize(stateManager, app);
|
||||
menuMusic = loadMusic(app, MENU_MUSIC_PATH);
|
||||
gameMusic = loadMusic(app, GAME_MUSIC_PATH);
|
||||
victoryMusic = loadMusic(app, VICTORY_MUSIC_PATH);
|
||||
defeatMusic = loadMusic(app, DEFEAT_MUSIC_PATH);
|
||||
currentMusic = menuMusic;
|
||||
playCurrentMusic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a music file and initializes an AudioNode with the specified settings.
|
||||
*
|
||||
* @param app The application instance.
|
||||
* @param name The name of the music file to load.
|
||||
* @return The initialized AudioNode, or {@code null} if the file could not be loaded.
|
||||
*/
|
||||
private AudioNode loadMusic(Application app, String name) {
|
||||
try {
|
||||
this.volume = PREFERENCES.getFloat(VOLUME_PREF, 0.5f);
|
||||
final AudioNode music = new AudioNode(app.getAssetManager(), name, DataType.Stream);
|
||||
music.setLooping(true);
|
||||
music.setVolume(volume);
|
||||
music.setPositional(false);
|
||||
music.setDirectional(false);
|
||||
return music;
|
||||
} catch (AssetLoadException | AssetNotFoundException ex) {
|
||||
LOGGER.log(Level.ERROR, ex.getMessage(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the current music if the music is enabled.
|
||||
* Stops the current music if the music is disabled.
|
||||
*/
|
||||
private void playCurrentMusic() {
|
||||
if (isEnabled()) {
|
||||
if (currentMusic != null) {
|
||||
LOGGER.log(Level.INFO, "Playing current music"); //NON-NLS
|
||||
currentMusic.play();
|
||||
}
|
||||
} else {
|
||||
if (currentMusic != null) {
|
||||
currentMusic.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the game music.
|
||||
*/
|
||||
private void gameMusic() {
|
||||
if (isEnabled() && gameMusic != null) {
|
||||
stopAll();
|
||||
LOGGER.log(Level.INFO, "Playing game music"); //NON-NLS
|
||||
gameMusic.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the victory music.
|
||||
*/
|
||||
private void victoryMusic() {
|
||||
if (isEnabled() && victoryMusic != null) {
|
||||
stopAll();
|
||||
LOGGER.log(Level.INFO, "Playing victory music"); //NON-NLS
|
||||
victoryMusic.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the defeat music.
|
||||
*/
|
||||
private void defeatMusic() {
|
||||
if (isEnabled() && defeatMusic != null) {
|
||||
stopAll();
|
||||
LOGGER.log(Level.INFO, "Playing defeat music"); //NON-NLS
|
||||
defeatMusic.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all music.
|
||||
*/
|
||||
private void stopAll() {
|
||||
if (menuMusic != null) menuMusic.stop();
|
||||
if (gameMusic != null) gameMusic.stop();
|
||||
if (victoryMusic != null) victoryMusic.stop();
|
||||
if (defeatMusic != null) defeatMusic.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the received music event and plays the corresponding music.
|
||||
*
|
||||
* @param event The music event to handle.
|
||||
*/
|
||||
@Override
|
||||
public void receivedEvent(MusicEvent event) {
|
||||
switch (event.music()) {
|
||||
case GAME_MUSIC -> {
|
||||
gameMusic();
|
||||
currentMusic = gameMusic;
|
||||
}
|
||||
case VICTORY_MUSIC -> {
|
||||
victoryMusic();
|
||||
currentMusic = victoryMusic;
|
||||
}
|
||||
case DEFEAT_MUSIC -> {
|
||||
defeatMusic();
|
||||
currentMusic = defeatMusic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the volume for the background music and updates the preferences.
|
||||
*
|
||||
* @param volume The volume level to set.
|
||||
*/
|
||||
public void setVolume(float volume) {
|
||||
LOGGER.log(Level.INFO, "Setting volume to {0}", volume); //NON-NLS
|
||||
this.volume = volume;
|
||||
currentMusic.setVolume(volume);
|
||||
PREFERENCES.putFloat(VOLUME_PREF, volume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the volume level for the background music.
|
||||
*
|
||||
* @return The volume level as a float.
|
||||
*/
|
||||
public float getVolume() {
|
||||
return volume;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
import com.jme3.app.DebugKeysAppState;
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.app.StatsAppState;
|
||||
import com.jme3.audio.AudioNode;
|
||||
import com.jme3.font.BitmapFont;
|
||||
import com.jme3.font.BitmapText;
|
||||
import com.jme3.input.KeyInput;
|
||||
@@ -128,8 +129,7 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
|
||||
try {
|
||||
manager.readConfiguration(new FileInputStream("logging.properties"));
|
||||
LOGGER.log(Level.INFO, "Successfully read logging properties"); //NON-NLS
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.INFO, e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -267,6 +267,7 @@ private void setupStates() {
|
||||
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
|
||||
|
||||
attachGameSound();
|
||||
attachBackgroundSound();
|
||||
stateManager.attachAll(new EditorAppState(), new BattleAppState(), new SeaAppState());
|
||||
}
|
||||
|
||||
@@ -280,6 +281,19 @@ private void attachGameSound() {
|
||||
stateManager.attach(gameSound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the background music state and sets its initial enabled state.
|
||||
* The background music state is responsible for managing the background music
|
||||
* playback in the game. It listens to the game logic for any changes in the
|
||||
* background music settings.
|
||||
*/
|
||||
private void attachBackgroundSound() {
|
||||
final BackgroundMusic backgroundMusic = new BackgroundMusic();
|
||||
logic.addListener(backgroundMusic);
|
||||
backgroundMusic.setEnabled(BackgroundMusic.enabledInPreferences());
|
||||
stateManager.attach(backgroundMusic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the application state every frame.
|
||||
* This method is called once per frame during the game loop.
|
||||
@@ -405,12 +419,12 @@ public void stop(boolean waitFor) {
|
||||
*/
|
||||
void confirmDialog(String question, Runnable yesAction) {
|
||||
DialogBuilder.simple(dialogManager)
|
||||
.setTitle(lookup("dialog.question"))
|
||||
.setText(question)
|
||||
.setOkButton(lookup("button.yes"), yesAction)
|
||||
.setNoButton(lookup("button.no"))
|
||||
.build()
|
||||
.open();
|
||||
.setTitle(lookup("dialog.question"))
|
||||
.setText(question)
|
||||
.setOkButton(lookup("button.yes"), yesAction)
|
||||
.setNoButton(lookup("button.no"))
|
||||
.build()
|
||||
.open();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,10 +434,10 @@ void confirmDialog(String question, Runnable yesAction) {
|
||||
*/
|
||||
void errorDialog(String errorMessage) {
|
||||
DialogBuilder.simple(dialogManager)
|
||||
.setTitle(lookup("dialog.error"))
|
||||
.setText(errorMessage)
|
||||
.setOkButton(lookup("button.ok"))
|
||||
.build()
|
||||
.open();
|
||||
.setTitle(lookup("dialog.error"))
|
||||
.setText(errorMessage)
|
||||
.setOkButton(lookup("button.ok"))
|
||||
.build()
|
||||
.open();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Checkbox;
|
||||
import com.simsilica.lemur.DefaultRangedValueModel;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Slider;
|
||||
import com.simsilica.lemur.core.VersionedReference;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.StateCheckboxModel;
|
||||
@@ -19,6 +22,8 @@
|
||||
import java.io.IOException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import java.lang.System.Logger;
|
||||
|
||||
import static pp.battleship.Resources.lookup;
|
||||
import static pp.util.PreferencesUtils.getPreferences;
|
||||
|
||||
@@ -28,11 +33,13 @@
|
||||
* returning to the game, and quitting the application.
|
||||
*/
|
||||
class Menu extends Dialog {
|
||||
private static final Logger LOGGER = System.getLogger(Menu.class.getName());
|
||||
private static final Preferences PREFERENCES = getPreferences(Menu.class);
|
||||
private static final String LAST_PATH = "last.file.path";
|
||||
private final BattleshipApp app;
|
||||
private final Button loadButton = new Button(lookup("menu.map.load"));
|
||||
private final Button saveButton = new Button(lookup("menu.map.save"));
|
||||
private final VersionedReference<Double> volumeRef;
|
||||
|
||||
/**
|
||||
* Constructs the Menu dialog for the Battleship application.
|
||||
@@ -43,8 +50,19 @@ public Menu(BattleshipApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
|
||||
|
||||
addChild(new Checkbox(lookup("menu.sound-enabled"),
|
||||
new StateCheckboxModel(app, GameSound.class)));
|
||||
new StateCheckboxModel(app, GameSound.class)));
|
||||
|
||||
addChild(new Checkbox(lookup("menu.music-toggle"),
|
||||
new StateCheckboxModel(app, BackgroundMusic.class)));
|
||||
|
||||
Slider volumeSlider = new Slider();
|
||||
volumeSlider.setModel(new DefaultRangedValueModel(0.0, 2.0, app.getStateManager().getState(BackgroundMusic.class).getVolume()));
|
||||
volumeSlider.setDelta(0.1f);
|
||||
addChild(volumeSlider);
|
||||
volumeRef = volumeSlider.getModel().createReference();
|
||||
|
||||
addChild(loadButton)
|
||||
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
||||
addChild(saveButton)
|
||||
@@ -65,6 +83,28 @@ public void update() {
|
||||
saveButton.setEnabled(app.getGameLogic().maySaveMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the menu state based on the time per frame (tpf).
|
||||
* If the volume reference has been updated, adjusts the volume accordingly.
|
||||
*
|
||||
* @param tpf the time per frame
|
||||
*/
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
if (volumeRef.update()) {
|
||||
adjustVolume(volumeRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the volume of the background music.
|
||||
*
|
||||
* @param volume the new volume level to set, as a double
|
||||
*/
|
||||
private void adjustVolume(double volume) {
|
||||
app.getStateManager().getState(BackgroundMusic.class).setVolume((float) volume);
|
||||
}
|
||||
|
||||
/**
|
||||
* As an escape action, this method closes the menu if it is the top dialog.
|
||||
*/
|
||||
@@ -99,8 +139,7 @@ private void handle(FileAction fileAction, TextInputDialog dialog) {
|
||||
PREFERENCES.put(LAST_PATH, path);
|
||||
fileAction.run(new File(path));
|
||||
dialog.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
app.errorDialog(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
@@ -114,13 +153,13 @@ private void handle(FileAction fileAction, TextInputDialog dialog) {
|
||||
private void fileDialog(FileAction fileAction, String label) {
|
||||
final TextInputDialog dialog =
|
||||
TextInputDialog.builder(app.getDialogManager())
|
||||
.setLabel(lookup("label.file"))
|
||||
.setFocus(TextInputDialog::getInput)
|
||||
.setTitle(label)
|
||||
.setOkButton(lookup("button.ok"), d -> handle(fileAction, d))
|
||||
.setNoButton(lookup("button.cancel"))
|
||||
.setOkClose(false)
|
||||
.build();
|
||||
.setLabel(lookup("label.file"))
|
||||
.setFocus(TextInputDialog::getInput)
|
||||
.setTitle(label)
|
||||
.setOkButton(lookup("button.ok"), d -> handle(fileAction, d))
|
||||
.setNoButton(lookup("button.cancel"))
|
||||
.setOkClose(false)
|
||||
.build();
|
||||
final String path = PREFERENCES.get(LAST_PATH, null);
|
||||
if (path != null)
|
||||
dialog.getInput().setText(path.trim());
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Personal-use only.
|
||||
|
||||
menu_music.ogg
|
||||
https://pixabay.com/de/music/szenen-aufbauen-demolition-outline-science-fiction-trailer-music-191960/
|
||||
pirates.ogg
|
||||
https://pixabay.com/de/music/epische-klassik-pirates-163389/
|
||||
win_the_game.gg
|
||||
https://pixabay.com/de/users/enrico_dering-31760131/
|
||||
defeat.ogg
|
||||
https://pixabay.com/de/music/dramaszene-defeat-charles-michel-140604/
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
@@ -62,6 +63,10 @@ public void receivedEffect(EffectMessage msg) {
|
||||
if (msg.isGameOver()) {
|
||||
msg.getRemainingOpponentShips().forEach(logic.getOpponentMap()::add);
|
||||
logic.setState(new GameOverState(logic));
|
||||
if (msg.isOwnShot())
|
||||
logic.playMusic(Music.VICTORY_MUSIC);
|
||||
else
|
||||
logic.playMusic(Music.DEFEAT_MUSIC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,7 @@
|
||||
import pp.battleship.model.IntPoint;
|
||||
import pp.battleship.model.ShipMap;
|
||||
import pp.battleship.model.dto.ShipMapDTO;
|
||||
import pp.battleship.notification.ClientStateEvent;
|
||||
import pp.battleship.notification.GameEvent;
|
||||
import pp.battleship.notification.GameEventBroker;
|
||||
import pp.battleship.notification.GameEventListener;
|
||||
import pp.battleship.notification.InfoTextEvent;
|
||||
import pp.battleship.notification.Sound;
|
||||
import pp.battleship.notification.SoundEvent;
|
||||
import pp.battleship.notification.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -258,6 +252,15 @@ public void playSound(Sound sound) {
|
||||
notifyListeners(new SoundEvent(sound));
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event to play the specified music.
|
||||
*
|
||||
* @param music the music to be played.
|
||||
*/
|
||||
public void playMusic(Music music) {
|
||||
notifyListeners(new MusicEvent(music));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a map from the specified file.
|
||||
*
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
import pp.battleship.message.client.MapMessage;
|
||||
import pp.battleship.model.Battleship;
|
||||
import pp.battleship.model.IntPoint;
|
||||
import pp.battleship.model.Rotation;
|
||||
import pp.battleship.model.ShipMap;
|
||||
import pp.battleship.model.dto.ShipMapDTO;
|
||||
|
||||
@@ -113,8 +112,7 @@ private void placeShip(IntPoint cursor) {
|
||||
harbor().remove(selectedInHarbor);
|
||||
preview = null;
|
||||
selectedInHarbor = null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
preview.setStatus(INVALID_PREVIEW);
|
||||
ownMap().add(preview);
|
||||
}
|
||||
@@ -137,8 +135,7 @@ public void clickHarbor(IntPoint pos) {
|
||||
harbor().add(selectedInHarbor);
|
||||
preview = null;
|
||||
selectedInHarbor = null;
|
||||
}
|
||||
else if (shipAtCursor != null) {
|
||||
} else if (shipAtCursor != null) {
|
||||
selectedInHarbor = shipAtCursor;
|
||||
selectedInHarbor.setStatus(VALID_PREVIEW);
|
||||
harbor().remove(selectedInHarbor);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
import pp.battleship.message.server.GameDetails;
|
||||
import pp.battleship.message.server.StartBattleMessage;
|
||||
import pp.battleship.notification.Music;
|
||||
|
||||
import java.lang.System.Logger.Level;
|
||||
|
||||
@@ -38,6 +39,7 @@ public void receivedStartBattle(StartBattleMessage msg) {
|
||||
ClientGameLogic.LOGGER.log(Level.INFO, "start battle, {0} turn", msg.isMyTurn() ? "my" : "other's"); //NON-NLS
|
||||
logic.setInfoText(msg.getInfoTextKey());
|
||||
logic.setState(new BattleState(logic, msg.isMyTurn()));
|
||||
logic.playMusic(Music.GAME_MUSIC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,6 +39,13 @@ default void receivedEvent(InfoTextEvent event) { /* do nothing */ }
|
||||
*/
|
||||
default void receivedEvent(SoundEvent event) { /* do nothing */ }
|
||||
|
||||
/**
|
||||
* Indicates that music shall be played.
|
||||
*
|
||||
* @param event the received event
|
||||
*/
|
||||
default void receivedEvent(MusicEvent event) { /* do nothing */ }
|
||||
|
||||
/**
|
||||
* Indicates that the client's state has changed.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package pp.battleship.notification;
|
||||
|
||||
/**
|
||||
* Enumeration representing different types of music used in the game.
|
||||
*/
|
||||
public enum Music {
|
||||
/**
|
||||
* Music for the game.
|
||||
*/
|
||||
GAME_MUSIC,
|
||||
/**
|
||||
* Music for the menu.
|
||||
*/
|
||||
MENU_MUSIC,
|
||||
/**
|
||||
* Music for victory.
|
||||
*/
|
||||
VICTORY_MUSIC,
|
||||
/**
|
||||
* Music for defeat.
|
||||
*/
|
||||
DEFEAT_MUSIC
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package pp.battleship.notification;
|
||||
|
||||
|
||||
/**
|
||||
* Event when music is played in the game.
|
||||
*
|
||||
* @param music the music to be played
|
||||
*/
|
||||
public record MusicEvent(Music music) implements GameEvent {
|
||||
|
||||
/**
|
||||
* Notifies the game event listener of this event.
|
||||
*
|
||||
* @param listener the game event listener
|
||||
*/
|
||||
@Override
|
||||
public void notifyListener(GameEventListener listener) {
|
||||
listener.receivedEvent(this);
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ menu.return-to-game=Return to game
|
||||
menu.sound-enabled=Sound switched on
|
||||
menu.map.load=Load map from file...
|
||||
menu.map.save=Save map in file...
|
||||
menu.music-toggle=Music on/off
|
||||
label.file=File:
|
||||
label.connecting=Connecting...
|
||||
dialog.error=Error
|
||||
|
||||
@@ -31,6 +31,7 @@ menu.return-to-game=Zur
|
||||
menu.sound-enabled=Sound eingeschaltet
|
||||
menu.map.load=Karte von Datei laden...
|
||||
menu.map.save=Karte in Datei speichern...
|
||||
menu.music-toggle=Musik an/aus
|
||||
label.file=Datei:
|
||||
label.connecting=Verbindung wird aufgebaut...
|
||||
dialog.error=Fehler
|
||||
|
||||
Reference in New Issue
Block a user