solution for exercise 10
added BackgroundMusic which is being handled in BackgroundMusic.java changed the menu to incoporate volume controls for the music
This commit is contained in:
parent
d15f1a3f5f
commit
d471f524d0
@@ -0,0 +1,101 @@
|
|||||||
|
package pp.battleship.client;
|
||||||
|
|
||||||
|
import com.jme3.app.Application;
|
||||||
|
import com.jme3.audio.AudioData.DataType;
|
||||||
|
import com.jme3.audio.AudioNode;
|
||||||
|
import com.jme3.audio.AudioSource.Status;
|
||||||
|
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
public class BackgroundMusic {
|
||||||
|
private static final String VOLUME_PREF = "volume";
|
||||||
|
private static final String MUSIC_ENABLED_PREF = "musicEnabled";
|
||||||
|
private Preferences prefs = Preferences.userNodeForPackage(BackgroundMusic.class);
|
||||||
|
|
||||||
|
|
||||||
|
private final AudioNode backgroundMusic;
|
||||||
|
private boolean musicEnabled;
|
||||||
|
private float volume;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
this.volume = prefs.getFloat(VOLUME_PREF, 1.0f);
|
||||||
|
this.musicEnabled = prefs.getBoolean(MUSIC_ENABLED_PREF, true);
|
||||||
|
|
||||||
|
backgroundMusic = new AudioNode(app.getAssetManager(), musicFilePath, DataType.Stream);
|
||||||
|
backgroundMusic.setLooping(true);
|
||||||
|
backgroundMusic.setPositional(false);
|
||||||
|
backgroundMusic.setVolume(1.0f);
|
||||||
|
|
||||||
|
if(musicEnabled) {
|
||||||
|
play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the music if the music is Stopped or paused
|
||||||
|
*/
|
||||||
|
public void play() {
|
||||||
|
if (musicEnabled && (backgroundMusic.getStatus() == Status.Stopped || backgroundMusic.getStatus() == Status.Paused)) {
|
||||||
|
backgroundMusic.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the music if it is playing
|
||||||
|
*/
|
||||||
|
public void stop(){
|
||||||
|
if (backgroundMusic.getStatus() == Status.Playing) {
|
||||||
|
backgroundMusic.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle Method to control the music
|
||||||
|
*/
|
||||||
|
public void toogleMusic() {
|
||||||
|
this.musicEnabled = !this.musicEnabled;
|
||||||
|
if (musicEnabled) {
|
||||||
|
play();
|
||||||
|
} else {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.putFloat(VOLUME_PREF, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set the volume for the music
|
||||||
|
*
|
||||||
|
* @param volume float to transfer the new volume
|
||||||
|
*/
|
||||||
|
public void setVolume(float volume) {
|
||||||
|
this.volume = volume;
|
||||||
|
backgroundMusic.setVolume(volume);
|
||||||
|
|
||||||
|
prefs.putFloat(VOLUME_PREF, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method retuns the volume
|
||||||
|
*
|
||||||
|
* @return the current volume as a float
|
||||||
|
*/
|
||||||
|
public float getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if music should be played or not
|
||||||
|
*
|
||||||
|
* @return boolean value in music should be played
|
||||||
|
*/
|
||||||
|
public boolean isMusicEnabled() {
|
||||||
|
return musicEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,6 +122,11 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
|
|||||||
*/
|
*/
|
||||||
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
|
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Object which handles the background music
|
||||||
|
*/
|
||||||
|
private BackgroundMusic backgroundMusic;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Configure logging
|
// Configure logging
|
||||||
LogManager manager = LogManager.getLogManager();
|
LogManager manager = LogManager.getLogManager();
|
||||||
@@ -225,6 +230,8 @@ public void simpleInitApp() {
|
|||||||
setupStates();
|
setupStates();
|
||||||
setupGui();
|
setupGui();
|
||||||
serverConnection.connect();
|
serverConnection.connect();
|
||||||
|
|
||||||
|
backgroundMusic = new BackgroundMusic(this, "Music/MainMenu/Dark_Intro.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -426,4 +433,13 @@ void errorDialog(String errorMessage) {
|
|||||||
.build()
|
.build()
|
||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method returns the object which handles the background music
|
||||||
|
*
|
||||||
|
* @return BackgroundMusic
|
||||||
|
*/
|
||||||
|
public BackgroundMusic getBackgroundMusic(){
|
||||||
|
return backgroundMusic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
|
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Checkbox;
|
import com.simsilica.lemur.Checkbox;
|
||||||
|
import com.simsilica.lemur.DefaultRangedValueModel;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
|
import com.simsilica.lemur.Slider;
|
||||||
|
import com.simsilica.lemur.core.VersionedReference;
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.dialog.StateCheckboxModel;
|
import pp.dialog.StateCheckboxModel;
|
||||||
@@ -34,6 +37,8 @@ class Menu extends Dialog {
|
|||||||
private final Button loadButton = new Button(lookup("menu.map.load"));
|
private final Button loadButton = new Button(lookup("menu.map.load"));
|
||||||
private final Button saveButton = new Button(lookup("menu.map.save"));
|
private final Button saveButton = new Button(lookup("menu.map.save"));
|
||||||
|
|
||||||
|
private final VersionedReference<Double> volumeRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the Menu dialog for the Battleship application.
|
* Constructs the Menu dialog for the Battleship application.
|
||||||
*
|
*
|
||||||
@@ -45,6 +50,19 @@ public Menu(BattleshipApp app) {
|
|||||||
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
|
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
|
||||||
addChild(new Checkbox(lookup("menu.sound-enabled"),
|
addChild(new Checkbox(lookup("menu.sound-enabled"),
|
||||||
new StateCheckboxModel(app, GameSound.class)));
|
new StateCheckboxModel(app, GameSound.class)));
|
||||||
|
|
||||||
|
Checkbox musicToggle = new Checkbox(lookup("menu.music.toggle"));
|
||||||
|
musicToggle.setChecked(app.getBackgroundMusic().isMusicEnabled());
|
||||||
|
musicToggle.addClickCommands(s -> toggleMusic());
|
||||||
|
|
||||||
|
addChild(musicToggle);
|
||||||
|
|
||||||
|
Slider volumeSlider = new Slider();
|
||||||
|
volumeSlider.setModel(new DefaultRangedValueModel(0.0 , 2.0, app.getBackgroundMusic().getVolume()));
|
||||||
|
addChild(volumeSlider);
|
||||||
|
|
||||||
|
volumeRef = volumeSlider.getModel().createReference();
|
||||||
|
|
||||||
addChild(loadButton)
|
addChild(loadButton)
|
||||||
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
.addClickCommands(s -> ifTopDialog(this::loadDialog));
|
||||||
addChild(saveButton)
|
addChild(saveButton)
|
||||||
@@ -56,6 +74,34 @@ public Menu(BattleshipApp app) {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method is used update the volume when there is a change in the slider
|
||||||
|
* @param tpf time per frame
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update(float tpf){
|
||||||
|
if(volumeRef.update()){
|
||||||
|
double newVolume = volumeRef.get();
|
||||||
|
adjustVolume(newVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method adjust the volume for the background music
|
||||||
|
*
|
||||||
|
* @param volume is the double value of the volume
|
||||||
|
*/
|
||||||
|
private void adjustVolume(double volume) {
|
||||||
|
app.getBackgroundMusic().setVolume((float) volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this method toggles the background music on and off
|
||||||
|
*/
|
||||||
|
private void toggleMusic() {
|
||||||
|
app.getBackgroundMusic().toogleMusic();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the state of the load and save buttons based on the game logic.
|
* Updates the state of the load and save buttons based on the game logic.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -144,18 +144,13 @@ public Spatial visit(Battleship ship) {
|
|||||||
* @return the spatial representing the battleship
|
* @return the spatial representing the battleship
|
||||||
*/
|
*/
|
||||||
private Spatial createShip(Battleship ship) {
|
private Spatial createShip(Battleship ship) {
|
||||||
switch (ship.getLength()){
|
return switch (ship.getLength()) {
|
||||||
case 1:
|
case 1 -> createPatrolBoat(ship);
|
||||||
return createPatrolBoat(ship);
|
case 2 -> createModernBattleship(ship);
|
||||||
case 2:
|
case 3 -> createUBoat(ship);
|
||||||
return createModernBattleship(ship);
|
case 4 -> createBattleship(ship);
|
||||||
case 3:
|
default -> throw new IllegalArgumentException("Ship length must be between 1 and 4 units long");
|
||||||
return createUBoat(ship);
|
};
|
||||||
case 4:
|
|
||||||
return createBattleship(ship);
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Ship length must be between 1 and 4 units long");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,6 +205,12 @@ private Spatial createBattleship(Battleship ship) {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a detailed 3D model to represent an UBoat
|
||||||
|
*
|
||||||
|
* @param ship the ship to be represented
|
||||||
|
* @return the spatial representing the Uboat
|
||||||
|
*/
|
||||||
private Spatial createUBoat(Battleship ship) {
|
private Spatial createUBoat(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(UBOAT);
|
final Spatial model = app.getAssetManager().loadModel(UBOAT);
|
||||||
|
|
||||||
@@ -221,6 +222,12 @@ private Spatial createUBoat(Battleship ship) {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a detailed 3D model to represent the modern battleship
|
||||||
|
*
|
||||||
|
* @param ship the ship to be represented
|
||||||
|
* @return the spatial representing the Modern Battleship
|
||||||
|
*/
|
||||||
private Spatial createModernBattleship(Battleship ship) {
|
private Spatial createModernBattleship(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(BATTLE_SHIP_MODERN);
|
final Spatial model = app.getAssetManager().loadModel(BATTLE_SHIP_MODERN);
|
||||||
|
|
||||||
@@ -232,6 +239,12 @@ private Spatial createModernBattleship(Battleship ship) {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a detailed 3D model to represent the patrol boat
|
||||||
|
*
|
||||||
|
* @param ship the ship to be represented
|
||||||
|
* @return the spatial representing the patrol boat
|
||||||
|
*/
|
||||||
private Spatial createPatrolBoat(Battleship ship) {
|
private Spatial createPatrolBoat(Battleship ship) {
|
||||||
final Spatial model = app.getAssetManager().loadModel(PATROL_BOAT);
|
final Spatial model = app.getAssetManager().loadModel(PATROL_BOAT);
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -31,6 +31,8 @@ menu.return-to-game=Return to game
|
|||||||
menu.sound-enabled=Sound switched on
|
menu.sound-enabled=Sound switched on
|
||||||
menu.map.load=Load map from file...
|
menu.map.load=Load map from file...
|
||||||
menu.map.save=Save map in file...
|
menu.map.save=Save map in file...
|
||||||
|
menu.music.toggle=Toggle the music
|
||||||
|
menu.volume=Volume
|
||||||
label.file=File:
|
label.file=File:
|
||||||
label.connecting=Connecting...
|
label.connecting=Connecting...
|
||||||
dialog.error=Error
|
dialog.error=Error
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ menu.return-to-game=Zurück zum Spiel
|
|||||||
menu.sound-enabled=Sound eingeschaltet
|
menu.sound-enabled=Sound eingeschaltet
|
||||||
menu.map.load=Karte von Datei laden...
|
menu.map.load=Karte von Datei laden...
|
||||||
menu.map.save=Karte in Datei speichern...
|
menu.map.save=Karte in Datei speichern...
|
||||||
|
menu.music.toggle=An/Ausschalten der Musik
|
||||||
|
menu.volume=Lautstärke
|
||||||
label.file=Datei:
|
label.file=Datei:
|
||||||
label.connecting=Verbindung wird aufgebaut...
|
label.connecting=Verbindung wird aufgebaut...
|
||||||
dialog.error=Fehler
|
dialog.error=Fehler
|
||||||
|
|||||||
Reference in New Issue
Block a user