added background music and improved model code

reduced switch case for creating different ship models
created a new class for background music
added a button to toggle background music
added a slider so adjust volume
added new style for labeling the slider
This commit is contained in:
Timo Brennförder
2024-10-03 22:08:26 +02:00
parent 3bcaca8810
commit 9cfabdb15d
18 changed files with 186 additions and 697582 deletions

Binary file not shown.

View File

@@ -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 final Preferences pref = 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 = pref.getFloat(VOLUME_PREF, 1.0f);
this.musicEnabled = pref.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();
}
pref.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);
pref.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;
}
}

View File

@@ -122,6 +122,11 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
*/
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
/**
* Object handling the background music
*/
private BackgroundMusic backgroundMusic;
static {
// Configure logging
LogManager manager = LogManager.getLogManager();
@@ -225,6 +230,7 @@ public void simpleInitApp() {
setupStates();
setupGui();
serverConnection.connect();
backgroundMusic = new BackgroundMusic(this, "Sound/Background/Aluminum.ogg");
}
/**
@@ -315,6 +321,10 @@ public Draw getDraw() {
return draw;
}
public BackgroundMusic getBackgroundMusic(){
return backgroundMusic;
}
/**
* Handles a request to close the application.
* If the request is initiated by pressing ESC, this parameter is true.

View File

@@ -15,6 +15,7 @@
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;
import pp.battleship.notification.GameEventListener;
import pp.battleship.notification.Sound;
import pp.battleship.notification.SoundEvent;
import java.lang.System.Logger;
@@ -100,6 +101,7 @@ private AudioNode loadSound(Application app, String name) {
return null;
}
/**
* Plays the splash sound effect.
*/

View File

@@ -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;
@@ -33,6 +36,7 @@ class Menu extends Dialog {
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.
@@ -45,6 +49,20 @@ public Menu(BattleshipApp app) {
addChild(new Label(lookup("battleship.name"), new ElementId("header"))); //NON-NLS
addChild(new Checkbox(lookup("menu.sound-enabled"),
new StateCheckboxModel(app, GameSound.class)));
Checkbox musicToggle = new Checkbox(lookup("menu.music.toggle"));
musicToggle.setChecked(app.getBackgroundMusic().isMusicEnabled());
musicToggle.addClickCommands(s -> toggleMusic());
addChild(musicToggle);
addChild(new Label(lookup("menu.music.volume"), new ElementId("slider_label")));
Slider volumeSlider = new Slider();
volumeSlider.setModel(new DefaultRangedValueModel(0.00 , 1.00, app.getBackgroundMusic().getVolume()));
volumeSlider.setDelta(0.05);
addChild(volumeSlider);
volumeRef = volumeSlider.getModel().createReference();
addChild(loadButton)
.addClickCommands(s -> ifTopDialog(this::loadDialog));
addChild(saveButton)
@@ -53,9 +71,40 @@ public Menu(BattleshipApp app) {
.addClickCommands(s -> ifTopDialog(this::close));
addChild(new Button(lookup("menu.quit")))
.addClickCommands(s -> ifTopDialog(app::closeApp));
update();
}
/**
* this method is used update the volume when the slider is used
* @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.
*/

View File

@@ -37,7 +37,7 @@ class SeaSynchronizer extends ShipMapSynchronizer {
private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o";
private static final String UBOAT_MODEL = "Models/UBOAT/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj";
private static final String PATROL_BOAT_MODEL = "Models/PATROL_BOAT/12219_boat_v2_L2.obj";
private static final String BATTLESHIP_MODEL = "Models/BATTLESHIP/10619_Battleship.obj";
private static final String BATTLESHIPV2_MODEL = "Models/BATTLESHIP/10619_Battleship.obj";
private static final String COLOR = "Color"; //NON-NLS
private static final String SHIP = "ship"; //NON-NLS
private static final String SHOT = "shot"; //NON-NLS
@@ -144,18 +144,13 @@ public Spatial visit(Battleship ship) {
* @return the spatial representing the battleship
*/
private Spatial createShip(Battleship ship) {
switch (ship.getLength()){
case 1:
return createPatrolBoat(ship);
case 2:
return createBattleshipV2(ship);
case 3:
return createUboat(ship);
case 4:
return createBattleship(ship);
default:
return createBox(ship);
}
return switch (ship.getLength()){
case 1 -> createPatrolBoat(ship);
case 2 -> createBattleshipV2(ship);
case 3 -> createUboat(ship);
case 4 -> createBattleship(ship);
default -> createBox(ship);
};
}
/**
@@ -218,7 +213,7 @@ private Spatial createBattleship(Battleship ship) {
*/
private Spatial createBattleshipV2(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(BATTLESHIP_MODEL);
final Spatial model = app.getAssetManager().loadModel(BATTLESHIPV2_MODEL);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) + HALF_PI, 0f);
model.scale(0.000075f);

View File

@@ -1,73 +0,0 @@
newmtl Battleship
illum 4
Kd 0.00 0.00 0.00
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
map_Kd BattleshipC.jpg
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn1SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn2SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn3SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn4SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn5SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn6SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn7SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn8SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00

View File

@@ -1,104 +0,0 @@
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 16.12.2011 14:18:52
newmtl white
Ns 53.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.6667 0.6667 0.6667
Kd 0.6667 0.6667 0.6667
Ks 0.1800 0.1800 0.1800
Ke 0.0000 0.0000 0.0000
newmtl boat_elements_black
Ns 55.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.0000 0.0000 0.0000
Ks 0.3600 0.3600 0.3600
Ke 0.0000 0.0000 0.0000
newmtl boat_glass
Ns 60.0000
Ni 7.0000
d 0.4000
Tr 0.6000
Tf 0.4000 0.4000 0.4000
illum 2
Ka 0.1059 0.1569 0.1451
Kd 0.1059 0.1569 0.1451
Ks 0.6750 0.6750 0.6750
Ke 0.0000 0.0000 0.0000
newmtl boat_screw_hooks_bronze
Ns 80.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.2941 0.2157 0.0510
Kd 0.2941 0.2157 0.0510
Ks 0.7200 0.7200 0.7200
Ke 0.0000 0.0000 0.0000
newmtl boat_silver
Ns 80.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.3333 0.3333 0.3333
Kd 0.3333 0.3333 0.3333
Ks 0.7200 0.7200 0.7200
Ke 0.0000 0.0000 0.0000
newmtl boat_buffer
Ns 10.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.2700 0.2700 0.2700
Ke 0.0000 0.0000 0.0000
map_Ka boat_buffer_diffuse.jpg
map_Kd boat_buffer_diffuse.jpg
newmtl boat_roof_accessory
Ns 15.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.3600 0.3600 0.3600
Ke 0.0000 0.0000 0.0000
map_Ka boat_roof_accessory_diffuse.jpg
map_Kd boat_roof_accessory_diffuse.jpg
newmtl boat_body
Ns 55.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.3600 0.3600 0.3600
Ke 0.0000 0.0000 0.0000
map_Ka boat_body_diffuse.jpg
map_Kd boat_body_diffuse.jpg

View File

@@ -37,3 +37,7 @@ dialog.error=Error
dialog.question=Question
port.must.be.integer=Port must be an integer number
map.doesnt.fit=The map doesn't fit to this game
ships.dont.fit.the.map=Ships are out of bounds
menu.music.toggle= Music on/off
menu.music.volume= Volume

View File

@@ -27,7 +27,7 @@ host.name=Host
port.number=Port
wait.its.not.your.turn=Warte, Du bist nicht dran!!
menu.quit=Spiel beenden
menu.return-to-game=Zurück zum Spiel
menu.return-to-game=Zur<EFBFBD>ck zum Spiel
menu.sound-enabled=Sound eingeschaltet
menu.map.load=Karte von Datei laden...
menu.map.save=Karte in Datei speichern...
@@ -37,3 +37,7 @@ dialog.error=Fehler
dialog.question=Frage
port.must.be.integer=Der Port muss eine ganze Zahl sein
map.doesnt.fit=Diese Karte passt nicht zu diesem Spiel
ships.dont.fit.the.map=Schiffe sind au<61>erhalb der Map
menu.music.toggle= Musik an/aus
menu.music.volume= Lautst<EFBFBD>rke

View File

@@ -55,6 +55,12 @@
background.setColor(bgColor)
}
selector("slider_label", "pp"){
font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
color = color(1,0.5,0,1)
textHAlignment = HAlignment.Center
}
def pressedCommand = new Command<Button>() {
void execute(Button source) {
if (source.isPressed())