diff --git a/app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java b/app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java index 8049024..a891d7f 100644 --- a/app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java +++ b/app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java @@ -41,6 +41,9 @@ public final class OptionsPopup extends Popup { final var fxVolumeHeader = NodeBuilder.header(AppContext.getString("effectsVolume")); final var fxVolumeSeparator = NodeBuilder.separator(); + final var musicVolumeHeader = NodeBuilder.header(AppContext.getString("musicVolume")); + final var musicVolumeSeparator = NodeBuilder.separator(); + final var themeHeader = NodeBuilder.header(AppContext.getString("theme")); final var themeSeparator = NodeBuilder.separator(); @@ -51,6 +54,7 @@ public final class OptionsPopup extends Popup { optionsContainer.addNodes(languageHeader, languageChoiceBox(), languageSeparator); optionsContainer.addNodes(volumeHeader, volumeSlider(), volumeSeparator); optionsContainer.addNodes(fxVolumeHeader, fxVolumeSlider(), fxVolumeSeparator); + optionsContainer.addNodes(musicVolumeHeader, musicVolumeSlider(), musicVolumeSeparator); optionsContainer.addNodes(themeHeader, themeChoiceBox(), themeSeparator); optionsContainer.addNodes(layoutSizeHeader, layoutSizeChoiceBox(), layoutSizeSeparator); optionsContainer.addNodes(fullscreenToggle()); @@ -115,6 +119,13 @@ public final class OptionsPopup extends Popup { }); } + private Slider musicVolumeSlider() { + return NodeBuilder.slider(100, settings.getMusicVolume(), (volume) -> { + settings.setMusicVolume(volume); + new EventFlow().addPostEvent(new AudioEvents.ChangeMusicVolume(volume.doubleValue())).asyncPostEvent(); + }); + } + private Label fullscreenToggle() { return NodeBuilder.toggle(AppContext.getString("windowed"), AppContext.getString("fullscreen"), !isWindowed, (fullscreen) -> { diff --git a/app/src/main/java/org/toop/local/AppSettings.java b/app/src/main/java/org/toop/local/AppSettings.java index ebff381..59ec622 100644 --- a/app/src/main/java/org/toop/local/AppSettings.java +++ b/app/src/main/java/org/toop/local/AppSettings.java @@ -1,5 +1,6 @@ package org.toop.local; +import jdk.jfr.Event; import org.toop.app.App; import org.toop.framework.asset.resources.SettingsAsset; import org.toop.framework.audio.events.AudioEvents; @@ -23,6 +24,8 @@ public class AppSettings { AppContext.setLocale(Locale.of(settingsData.locale)); App.setFullscreen(settingsData.fullScreen); new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(settingsData.volume)).asyncPostEvent(); + new EventFlow().addPostEvent(new AudioEvents.ChangeFxVolume(settingsData.fxVolume)).asyncPostEvent(); + new EventFlow().addPostEvent(new AudioEvents.ChangeMusicVolume(settingsData.musicVolume)).asyncPostEvent(); App.setStyle(settingsAsset.getTheme(), settingsAsset.getLayoutSize()); } diff --git a/app/src/main/resources/assets/localization/localization_en.properties b/app/src/main/resources/assets/localization/localization_en.properties index 387d741..e70320a 100644 --- a/app/src/main/resources/assets/localization/localization_en.properties +++ b/app/src/main/resources/assets/localization/localization_en.properties @@ -17,6 +17,7 @@ deny=Deny developers=Developers drawText=The game ended in a draw effectsVolume=Effects Volume +musicVolume=Music Volume fullscreen=Fullscreen gameIsText=To a game of goodGameText=Good game. Well played. @@ -47,7 +48,7 @@ small=Small start=Start theme=Theme tictactoe=Tic Tac Toe -volume=Volume +volume=Master Volume windowed=Windowed yes=Yes diff --git a/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java index 76b503e..c496213 100644 --- a/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java +++ b/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java @@ -20,6 +20,10 @@ public class SettingsAsset extends JsonAsset { return getContent().fxVolume; } + public int getMusicVolume() { + return getContent().musicVolume; + } + public Locale getLocale() { return Locale.forLanguageTag(getContent().locale); } @@ -46,6 +50,11 @@ public class SettingsAsset extends JsonAsset { save(); } + public void setMusicVolume(int musicVolume) { + getContent().musicVolume = musicVolume; + save(); + } + public void setLocale(String locale) { getContent().locale = locale; save(); diff --git a/framework/src/main/java/org/toop/framework/audio/AudioVolumeManager.java b/framework/src/main/java/org/toop/framework/audio/AudioVolumeManager.java index 0d94d04..7d256cc 100644 --- a/framework/src/main/java/org/toop/framework/audio/AudioVolumeManager.java +++ b/framework/src/main/java/org/toop/framework/audio/AudioVolumeManager.java @@ -1,5 +1,6 @@ package org.toop.framework.audio; +import com.sun.scenario.Settings; import javafx.scene.media.MediaPlayer; import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.eventbus.EventFlow; @@ -12,6 +13,7 @@ public class AudioVolumeManager { private double volume = 1.0; private double fxVolume = 1.0; + private double musicVolume = 1.0; public AudioVolumeManager(SoundManager soundManager){ this.sM = soundManager; @@ -19,12 +21,15 @@ public class AudioVolumeManager { new EventFlow() .listen(this::handleVolumeChange) .listen(this::handleFxVolumeChange) + .listen(this::handleMusicVolumeChange) .listen(this::handleGetCurrentVolume) - .listen(this::handleGetCurrentFxVolume); + .listen(this::handleGetCurrentFxVolume) + .listen(this::handleGetCurrentMusicVolume); + } public void updateMusicVolume(MediaPlayer mediaPlayer){ - mediaPlayer.setVolume(this.volume); + mediaPlayer.setVolume(this.musicVolume * this.volume); } public void updateSoundEffectVolume(Clip clip){ @@ -32,7 +37,7 @@ public class AudioVolumeManager { FloatControl volumeControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); float min = volumeControl.getMinimum(); float max = volumeControl.getMaximum(); - float dB = (float) (Math.log10(Math.max(fxVolume, 0.0001)) * 20.0); // convert linear to dB + float dB = (float) (Math.log10(Math.max(this.fxVolume * this.volume, 0.0001)) * 20.0); // convert linear to dB dB = Math.max(min, Math.min(max, dB)); volumeControl.setValue(dB); } @@ -55,6 +60,18 @@ public class AudioVolumeManager { for (MediaPlayer mediaPlayer : sM.getActiveMusic()) { this.updateMusicVolume(mediaPlayer); } + for (Clip clip : sM.getActiveSoundEffects().values()){ + updateSoundEffectVolume(clip); + } + } + + private void handleMusicVolumeChange(AudioEvents.ChangeMusicVolume event){ + this.musicVolume = limitVolume(event.newVolume() / 100); + System.out.println(this.musicVolume); + System.out.println(this.volume); + for (MediaPlayer mediaPlayer : sM.getActiveMusic()){ + this.updateMusicVolume(mediaPlayer); + } } private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) { @@ -66,4 +83,9 @@ public class AudioVolumeManager { new EventFlow().addPostEvent(new AudioEvents.GetCurrentFxVolumeResponse(fxVolume * 100, event.snowflakeId())) .asyncPostEvent(); } + + private void handleGetCurrentMusicVolume(AudioEvents.GetCurrentMusicVolume event){ + new EventFlow().addPostEvent(new AudioEvents.GetCurrentMusicVolumeResponse(musicVolume * 100, event.snowflakeId())) + .asyncPostEvent(); + } } diff --git a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java index 978ed4a..5cb596d 100644 --- a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java +++ b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java @@ -16,6 +16,8 @@ public class AudioEvents extends EventsBase { public record StartBackgroundMusic() implements EventWithoutSnowflake {} public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {} public record ChangeFxVolume(double newVolume) implements EventWithoutSnowflake {} + public record ChangeMusicVolume(double newVolume) implements EventWithoutSnowflake {} + public record GetCurrentVolume(long snowflakeId) implements EventWithSnowflake { @Override public Map result() { @@ -51,6 +53,18 @@ public class AudioEvents extends EventsBase { } } + public record GetCurrentMusicVolume(long snowflakeId) implements EventWithSnowflake { + @Override + public Map result() { + return Map.of(); + } + + @Override + public long eventSnowflake() { + return this.snowflakeId; + } + } + public record GetCurrentFxVolumeResponse(double currentVolume, long snowflakeId) implements EventWithSnowflake { @Override public Map result() { @@ -63,5 +77,18 @@ public class AudioEvents extends EventsBase { } } + public record GetCurrentMusicVolumeResponse(double currentVolume, long snowflakeId) implements EventWithSnowflake { + @Override + public Map result() { + return Map.of(); + } + + @Override + public long eventSnowflake() { + return this.snowflakeId; + } + } + public record ClickButton() implements EventWithoutSnowflake {} -} + + } diff --git a/framework/src/main/java/org/toop/framework/settings/Settings.java b/framework/src/main/java/org/toop/framework/settings/Settings.java index 4150e6c..b1ed334 100644 --- a/framework/src/main/java/org/toop/framework/settings/Settings.java +++ b/framework/src/main/java/org/toop/framework/settings/Settings.java @@ -5,6 +5,7 @@ public class Settings { public String locale = "en"; public String theme = "dark"; public String layoutSize = "medium"; - public int volume = 15; + public int volume = 100; public int fxVolume = 20; + public int musicVolume = 15; }