Merge remote-tracking branch 'origin/UI' into UI

# Conflicts:
#	app/src/main/java/org/toop/app/menu/CreditsMenu.java
#	app/src/main/java/org/toop/app/menu/MainMenu.java
#	app/src/main/java/org/toop/app/menu/OptionsMenu.java
This commit is contained in:
ramollia
2025-10-04 15:16:39 +02:00
12 changed files with 405 additions and 252 deletions

View File

@@ -1,32 +1,100 @@
// package org.toop.app.menu; package org.toop.app.menu;
//
// import javafx.application.Platform; import javafx.animation.Interpolator;
// import org.toop.framework.asset.ResourceManager; import javafx.animation.PauseTransition;
// import org.toop.framework.asset.resources.LocalizationAsset; import javafx.animation.TranslateTransition;
// import org.toop.framework.eventbus.EventFlow; import javafx.application.Platform;
// import org.toop.local.AppContext; import javafx.geometry.Pos;
// import javafx.scene.control.Button;
// import java.util.Locale; import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane;
// public final class CreditsMenu extends Menu { import javafx.scene.layout.VBox;
// private Locale currentLocale = AppContext.getLocale(); import javafx.util.Duration;
// private LocalizationAsset loc = ResourceManager.get("localization_en_us.properties"); import org.toop.app.App;
// public CreditsMenu() { import org.toop.framework.asset.ResourceManager;
// try { import org.toop.framework.asset.resources.LocalizationAsset;
// new EventFlow() import org.toop.framework.eventbus.EventFlow;
// .listen(this::handleChangeLanguage); import org.toop.local.AppContext;
// import org.toop.local.LocalizationEvents;
// }catch (Exception e){
// System.out.println("Something went wrong while trying to change the language."); import java.util.Locale;
// throw e;
// } public final class CreditsMenu extends Menu { ;
// private Locale currentLocale = AppContext.getLocale();
// } private LocalizationAsset loc = ResourceManager.get("localization_en_us.properties");
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// Platform.runLater(() -> { String[] credits = {
// currentLocale = AppContext.getLocale(); "Scrum Master: Stef",
// //credits.setText(loc.getString("credits",currentLocale)); "Product Owner: Omar",
// }); "Merge Commander: Bas",
// "Localization: Ticho",
// } "AI: Michiel",
// } "Developers: Michiel, Bas, Stef, Omar, Ticho",
"Moral Support: Wesley (voor 1 week)",
"OpenGL: Omar"
};
double scrollDuration = 20.0;
double lineHeight = 40.0;
public CreditsMenu() {
VBox creditsBox = new VBox(lineHeight / 2);
for (int i = credits.length - 1; i >= 0; i--) {
creditsBox.getChildren().add(createText(credits[i]));
creditsBox.setAlignment(Pos.CENTER);
}
Button exit = new Button("<");
exit.setStyle(
"-fx-background-color: transparent;" +
"-fx-text-fill: white;" +
"-fx-font-size: 72px;" +
"-fx-padding: 10 20 10 20;"
);
exit.setOnAction(e -> App.pop());
final Region background = createBackground();
StackPane.setAlignment(exit, Pos.TOP_LEFT);
pane = new StackPane(background, creditsBox, exit);
Platform.runLater(() -> playCredits(creditsBox, 800));
try {
new EventFlow()
.listen(this::handleChangeLanguage);
}catch (Exception e){
System.out.println("Something went wrong while trying to change the language.");
throw e;
}
}
public void playCredits(VBox creditsBox, double sceneLength) {
double height = (credits.length * lineHeight);
double startY = -sceneLength;
double endY = height;
creditsBox.setTranslateY(startY);
TranslateTransition scrollCredits = new TranslateTransition();
scrollCredits.setNode(creditsBox);
scrollCredits.setFromY(startY);
scrollCredits.setToY(endY / 2 - 200);
scrollCredits.setDuration(Duration.seconds(scrollDuration));
scrollCredits.setInterpolator(Interpolator.LINEAR);
scrollCredits.setOnFinished(e -> {
PauseTransition pauseCredits = new PauseTransition(Duration.seconds(5));
pauseCredits.setOnFinished(a -> playCredits(creditsBox, sceneLength));
pauseCredits.play();
});
scrollCredits.play();
}
private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
Platform.runLater(() -> {
currentLocale = AppContext.getLocale();
//credits.setText(loc.getString("credits",currentLocale));
});
}
}

View File

@@ -1,65 +1,69 @@
// package org.toop.app.menu; package org.toop.app.menu;
//
// import javafx.application.Platform; import javafx.application.Platform;
// import org.toop.app.App; import org.toop.app.App;
// import org.toop.app.GameType; import org.toop.app.GameType;
//
// import javafx.geometry.Pos; import javafx.geometry.Pos;
// import javafx.scene.control.Button; import javafx.scene.control.Button;
// import javafx.scene.layout.*; import javafx.scene.layout.*;
// import org.toop.framework.asset.ResourceManager; import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset; import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext; import org.toop.game.tictactoe.TicTacToe;
// import org.toop.local.AppContext;
// import java.util.Locale; import org.toop.local.LocalizationEvents;
//
// public final class MainMenu extends Menu { import java.util.Locale;
// private Locale currentLocale = AppContext.getLocale();
// private final LocalizationAsset loc = ResourceManager.get("localization"); public final class MainMenu extends Menu {
// private final Button tictactoe,reversi,credits,options,quit; private Locale currentLocale = AppContext.getLocale();
// public MainMenu() { private final LocalizationAsset loc = ResourceManager.get("localization");
// final Region background = createBackground(); private final Button tictactoe,reversi,credits,options,quit;
// public MainMenu() {
// tictactoe = createButton(loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); }); final Region background = createBackground();
// reversi = createButton(loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); });
// tictactoe = createButton(
// final VBox gamesBox = new VBox(10, tictactoe, reversi); loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); });
// gamesBox.setAlignment(Pos.TOP_LEFT); reversi = createButton(
// gamesBox.setPickOnBounds(false); loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); });
// gamesBox.setTranslateY(50);
// gamesBox.setTranslateX(25); final VBox gamesBox = new VBox(10, tictactoe, reversi);
// gamesBox.setAlignment(Pos.TOP_LEFT);
// credits = createButton(loc.getString("mainMenuSelectCredits",currentLocale), () -> { App.push(new CreditsMenu()); }); gamesBox.setPickOnBounds(false);
// options = createButton(loc.getString("mainMenuSelectOptions",currentLocale), () -> { App.push(new OptionsMenu()); }); gamesBox.setTranslateY(50);
// quit = createButton(loc.getString("mainMenuSelectQuit",currentLocale), () -> { App.quitPopup(); }); gamesBox.setTranslateX(25);
//
// final VBox controlBox = new VBox(10, credits, options, quit); credits = createButton(loc.getString("mainMenuSelectCredits",currentLocale), () -> { App.push(new CreditsMenu()); });
// controlBox.setAlignment(Pos.BOTTOM_LEFT); options = createButton(loc.getString("mainMenuSelectOptions",currentLocale), () -> { App.push(new OptionsMenu()); });
// controlBox.setPickOnBounds(false); quit = createButton(loc.getString("mainMenuSelectQuit",currentLocale), () -> { App.quitPopup(); });
// controlBox.setTranslateY(-50);
// controlBox.setTranslateX(25); final VBox controlBox = new VBox(10, credits, options, quit);
// controlBox.setAlignment(Pos.BOTTOM_LEFT);
// pane = new StackPane(background, gamesBox, controlBox); controlBox.setPickOnBounds(false);
// try { controlBox.setTranslateY(-50);
// new EventFlow() controlBox.setTranslateX(25);
// .listen(this::handleChangeLanguage);
// pane = new StackPane(background, gamesBox, controlBox);
// }catch (Exception e){ try {
// System.out.println("Something went wrong while trying to change the language."); new EventFlow()
// throw e; .listen(this::handleChangeLanguage);
// }
// }catch (Exception e){
// } System.out.println("Something went wrong while trying to change the language.");
// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) { throw e;
// Platform.runLater(() -> { }
// currentLocale = AppContext.getLocale();
// tictactoe.setText(loc.getString("mainMenuSelectTicTacToe",currentLocale)); }
// reversi.setText(loc.getString("mainMenuSelectReversi",currentLocale)); private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) {
// credits.setText(loc.getString("mainMenuSelectCredits",currentLocale)); Platform.runLater(() -> {
// options.setText(loc.getString("mainMenuSelectOptions",currentLocale)); currentLocale = AppContext.getLocale();
// quit.setText(loc.getString("mainMenuSelectQuit",currentLocale)); tictactoe.setText(loc.getString("mainMenuSelectTicTacToe",currentLocale));
// }); reversi.setText(loc.getString("mainMenuSelectReversi",currentLocale));
// credits.setText(loc.getString("mainMenuSelectCredits",currentLocale));
// } options.setText(loc.getString("mainMenuSelectOptions",currentLocale));
// } quit.setText(loc.getString("mainMenuSelectQuit",currentLocale));
});
}
}

View File

@@ -4,6 +4,8 @@ import javafx.scene.control.Button;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import org.toop.framework.audio.events.AudioEvents;
import org.toop.framework.eventbus.EventFlow;
public abstract class Menu { public abstract class Menu {
protected Pane pane; protected Pane pane;
@@ -34,7 +36,10 @@ public abstract class Menu {
public Button createButton(String css, String x, Runnable runnable) { public Button createButton(String css, String x, Runnable runnable) {
final Button button = new Button(x); final Button button = new Button(x);
button.setOnAction(_ -> runnable.run()); button.setOnAction(_ -> {
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
runnable.run();
});
button.getStyleClass().add(css); button.getStyleClass().add(css);
return button; return button;

View File

@@ -1,142 +1,174 @@
// package org.toop.app.menu; package org.toop.app.menu;
//
// import javafx.geometry.Pos; import javafx.geometry.Pos;
// import javafx.scene.control.*; import javafx.scene.control.*;
// import javafx.scene.control.Button; import javafx.scene.control.Button;
// import javafx.scene.control.Label; import javafx.scene.control.Label;
// import javafx.scene.layout.Region; import javafx.scene.layout.Region;
// import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
// import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
// import org.toop.app.App; import org.toop.app.App;
// import org.toop.framework.asset.ResourceManager; import org.toop.framework.asset.ResourceManager;
// import org.toop.framework.asset.resources.LocalizationAsset; import org.toop.framework.asset.resources.LocalizationAsset;
// import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.audio.events.AudioEvents;
// import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
// import org.toop.local.AppContext; import org.toop.local.AppContext;
//
// import java.awt.*; import java.awt.*;
// import java.util.Locale; import java.util.Locale;
//
// public final class OptionsMenu extends Menu { public final class OptionsMenu extends Menu {
// private Locale currentLocale = AppContext.getLocale(); private Locale currentLocale = AppContext.getLocale();
// private LocalizationAsset loc = ResourceManager.get("localization"); private LocalizationAsset loc = ResourceManager.get("localization");
// private GraphicsDevice currentScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0]; private GraphicsDevice currentScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0];
//
// public OptionsMenu() { public OptionsMenu() {
// final Label selectLanguageLabel = new Label( final Label selectLanguageLabel = new Label(
// loc.getString("optionsMenuLabelSelectLanguage", currentLocale) loc.getString("optionsMenuLabelSelectLanguage", currentLocale)
// ); );
//
// final Button exitOptionsButton = createButton("Exit Options", () -> { App.pop(); } ); final Button exitOptionsButton = createButton("Exit Options", () -> { App.pop(); } );
//
// final VBox optionsBox = new VBox(10, final VBox optionsBox = new VBox(10,
// selectLanguageLabel, selectLanguageLabel,
// languageSelectorCreation(), languageSelectorCreation(),
// screenDeviceSelectorCreation(), screenDeviceSelectorCreation(),
// displayModeSelectorCreation(), displayModeSelectorCreation(),
// selectFullscreenCreation(), selectFullscreenCreation(),
// volumeSelectorCreation(), volumeSelectorCreation(),
// exitOptionsButton); exitOptionsButton);
//
// optionsBox.setAlignment(Pos.CENTER); optionsBox.setAlignment(Pos.CENTER);
// optionsBox.setPickOnBounds(false); optionsBox.setPickOnBounds(false);
// optionsBox.setTranslateY(50); optionsBox.setTranslateY(50);
// optionsBox.setTranslateX(25); optionsBox.setTranslateX(25);
//
// pane = new StackPane(optionsBox); pane = new StackPane(optionsBox);
//
// } }
//
// private ChoiceBox<Locale> languageSelectorCreation() { private ChoiceBox<Locale> languageSelectorCreation() {
// final ChoiceBox<Locale> selectLanguage = new ChoiceBox<>(); final ChoiceBox<Locale> selectLanguage = new ChoiceBox<>();
// selectLanguage.setValue(currentLocale); selectLanguage.setValue(currentLocale);
//
// for (Locale locFile : loc.getAvailableLocales()) { for (Locale locFile : loc.getAvailableLocales()) {
// selectLanguage.getItems().add(locFile); selectLanguage.getItems().add(locFile);
// } }
//
// selectLanguage.setConverter(new javafx.util.StringConverter<Locale>() { selectLanguage.setConverter(new javafx.util.StringConverter<>() {
// @Override @Override
// public String toString(Locale locale) { public String toString(Locale locale) {
// return locale.getDisplayName(); return locale.getDisplayName();
// } }
//
// @Override @Override
// public Locale fromString(String string) { public Locale fromString(String string) {
// return null; return null;
// } }
// }); });
//
// selectLanguage.setOnAction(event -> { selectLanguage.setOnShowing(event -> {
// Locale selectedLocale = selectLanguage.getSelectionModel().getSelectedItem(); new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// if (selectedLocale != null) { });
// AppContext.setLocale(selectedLocale);
// App.pop(); selectLanguage.setOnAction(event -> {
// App.push(new OptionsMenu()); new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// } Locale selectedLocale = selectLanguage.getSelectionModel().getSelectedItem();
// }); if (selectedLocale != null) {
// AppContext.setLocale(selectedLocale);
// return selectLanguage; App.pop();
// } App.push(new OptionsMenu());
// }
// private ChoiceBox<GraphicsDevice> screenDeviceSelectorCreation() { });
// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice[] devices = ge.getScreenDevices(); return selectLanguage;
// final ChoiceBox<GraphicsDevice> selectScreen = new ChoiceBox<>(); }
// for (GraphicsDevice screen : devices) {
// selectScreen.getItems().add(screen); private ChoiceBox<GraphicsDevice> screenDeviceSelectorCreation() {
// } GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice[] devices = ge.getScreenDevices();
// selectScreen.setOnAction(event -> { final ChoiceBox<GraphicsDevice> selectScreen = new ChoiceBox<>();
// int selectedIndex = selectScreen.getSelectionModel().getSelectedIndex(); for (GraphicsDevice screen : devices) {
// Object selectedItem = selectScreen.getSelectionModel().getSelectedItem(); selectScreen.getItems().add(screen);
// }
// System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
// System.out.println(" ChoiceBox.getValue(): " + selectScreen.getValue()); selectScreen.setOnShowing(event -> {
// }); new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// return selectScreen; });
// }
// selectScreen.setOnAction(event -> {
// private ChoiceBox<DisplayMode> displayModeSelectorCreation() { new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// final ChoiceBox<DisplayMode> selectWindowSize = new ChoiceBox<>(); int selectedIndex = selectScreen.getSelectionModel().getSelectedIndex();
// for (DisplayMode displayMode : currentScreenDevice.getDisplayModes()) { Object selectedItem = selectScreen.getSelectionModel().getSelectedItem();
// selectWindowSize.getItems().add(displayMode);
// } System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
// return selectWindowSize; System.out.println(" ChoiceBox.getValue(): " + selectScreen.getValue());
// } });
// return selectScreen;
// private CheckBox selectFullscreenCreation() { }
// final CheckBox setFullscreen = new CheckBox("Fullscreen");
// setFullscreen.setSelected(App.isFullscreen()); private ChoiceBox<DisplayMode> displayModeSelectorCreation() {
// setFullscreen.setOnAction(event -> { final ChoiceBox<DisplayMode> selectWindowSize = new ChoiceBox<>();
// boolean isSelected = setFullscreen.isSelected(); for (DisplayMode displayMode : currentScreenDevice.getDisplayModes()) {
// App.setFullscreen(isSelected); selectWindowSize.getItems().add(displayMode);
// }); }
// return setFullscreen; selectWindowSize.setOnShowing(event -> {
// } new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// });
// private Slider volumeSelectorCreation() { selectWindowSize.setOnAction(event -> {
// Slider volumeSlider = new Slider(0, 100, 50); new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// new EventFlow() int selectedIndex = selectWindowSize.getSelectionModel().getSelectedIndex();
// .addPostEvent(AudioEvents.GetCurrentVolume.class) Object selectedItem = selectWindowSize.getSelectionModel().getSelectedItem();
// .onResponse(AudioEvents.GetCurrentVolumeReponse.class, event -> {
// volumeSlider.setValue(event.currentVolume() * 100); System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
// }).asyncPostEvent(); System.out.println(" ChoiceBox.getValue(): " + selectWindowSize.getValue());
// volumeSlider.setShowTickLabels(true); });
// volumeSlider.setShowTickMarks(true); return selectWindowSize;
// volumeSlider.setMajorTickUnit(25); }
// volumeSlider.setMinorTickCount(4);
// volumeSlider.setBlockIncrement(5); private CheckBox selectFullscreenCreation() {
// volumeSlider.setMaxWidth(225); final CheckBox setFullscreen = new CheckBox("Fullscreen");
// setFullscreen.setSelected(App.isFullscreen());
// Label valueLabel = new Label(String.valueOf((int) volumeSlider.getValue())); setFullscreen.setOnAction(event -> {
// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
// volumeSlider.valueProperty().addListener((obs, oldVal, newVal) -> { boolean isSelected = setFullscreen.isSelected();
// valueLabel.setText(String.valueOf(newVal.intValue())); App.setFullscreen(isSelected);
// new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newVal.doubleValue()/100.0)) });
// .asyncPostEvent(); return setFullscreen;
// }); }
// return volumeSlider;
// } private Slider volumeSelectorCreation() {
// Slider volumeSlider = new Slider(0, 100, 50);
// } new EventFlow()
.addPostEvent(AudioEvents.GetCurrentVolume.class)
.onResponse(AudioEvents.GetCurrentVolumeReponse.class, event -> {
volumeSlider.setValue(event.currentVolume() * 100);
}, true).asyncPostEvent();
volumeSlider.setShowTickLabels(true);
volumeSlider.setShowTickMarks(true);
volumeSlider.setMajorTickUnit(25);
volumeSlider.setMinorTickCount(4);
volumeSlider.setBlockIncrement(5);
volumeSlider.setMaxWidth(225);
Label valueLabel = new Label(String.valueOf((int) volumeSlider.getValue()));
final long[] lastPlayed = {0};
final long cooldown = 50;
volumeSlider.valueProperty().addListener((obs, oldVal, newVal) -> {
long now = System.currentTimeMillis();
if (now - lastPlayed[0] >= cooldown) {
lastPlayed[0] = now;
// new EventFlow().addPostEvent(new AudioEvents.clickButton())
// .asyncPostEvent(); // TODO: creates double sound bug, WHYYY????
}
valueLabel.setText(String.valueOf(newVal.intValue()));
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newVal.doubleValue()/100.0))
.asyncPostEvent();
});
return volumeSlider;
}
}

View File

@@ -0,0 +1,18 @@
.credit-text {
-fx-fill: #ffffff;
-fx-font-size: 24px;
-fx-font-family: "Arial";
-fx-font-weight: bold;
-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.7), 4, 0, 2, 2);
}
.button.exit-button {
-fx-background-color: #3498db;
-fx-text-fill: white;
-fx-font-size: 72px;
-fx-padding: 10 20 10 20;
-fx-background-radius: 5;
}
.button.exit-button:hover {
-fx-background-color: #2980b9;
}

View File

@@ -1,5 +1,7 @@
package org.toop.framework.asset; package org.toop.framework.asset;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.asset.resources.*; import org.toop.framework.asset.resources.*;
import java.util.*; import java.util.*;
@@ -46,6 +48,7 @@ import java.util.concurrent.ConcurrentHashMap;
* </ul> * </ul>
*/ */
public class ResourceManager { public class ResourceManager {
private static final Logger logger = LogManager.getLogger(ResourceManager.class);
private static final ResourceManager INSTANCE = new ResourceManager(); private static final ResourceManager INSTANCE = new ResourceManager();
private static final Map<String, ResourceMeta<? extends BaseResource>> assets = new ConcurrentHashMap<>(); private static final Map<String, ResourceMeta<? extends BaseResource>> assets = new ConcurrentHashMap<>();

View File

@@ -23,7 +23,10 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
Clip clip = AudioSystem.getClip(); Clip clip = AudioSystem.getClip();
// Insert a new audio stream into the clip // Insert a new audio stream into the clip
clip.open(this.getAudioStream()); AudioInputStream inputStream = this.getAudioStream();
AudioFormat baseFormat = inputStream.getFormat();
if (baseFormat.getSampleSizeInBits() > 16) inputStream = downSampleAudio(inputStream, baseFormat);
clip.open(inputStream); // ^ Clip can only run 16 bit and lower, thus downsampling necessary.
return clip; return clip;
} }
@@ -32,6 +35,20 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
return AudioSystem.getAudioInputStream(this.file); return AudioSystem.getAudioInputStream(this.file);
} }
private AudioInputStream downSampleAudio(AudioInputStream audioInputStream, AudioFormat baseFormat) {
AudioFormat decodedFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16, // force 16-bit
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false // little-endian
);
return AudioSystem.getAudioInputStream(decodedFormat, audioInputStream);
}
@Override @Override
public void load() { public void load() {
try { try {

View File

@@ -1,5 +1,7 @@
package org.toop.framework.audio; package org.toop.framework.audio;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.toop.framework.SnowflakeGenerator; import org.toop.framework.SnowflakeGenerator;
import org.toop.framework.asset.ResourceManager; import org.toop.framework.asset.ResourceManager;
import org.toop.framework.asset.ResourceMeta; import org.toop.framework.asset.ResourceMeta;
@@ -15,6 +17,7 @@ import java.util.*;
import javax.sound.sampled.*; import javax.sound.sampled.*;
public class SoundManager { public class SoundManager {
private static final Logger logger = LogManager.getLogger(SoundManager.class);
private final List<MediaPlayer> activeMusic = new ArrayList<>(); private final List<MediaPlayer> activeMusic = new ArrayList<>();
private final Queue<MusicAsset> backgroundMusicQueue = new LinkedList<>(); private final Queue<MusicAsset> backgroundMusicQueue = new LinkedList<>();
private final Map<Long, Clip> activeSoundEffects = new HashMap<>(); private final Map<Long, Clip> activeSoundEffects = new HashMap<>();
@@ -38,16 +41,16 @@ public class SoundManager {
.listen(this::handleMusicStart) .listen(this::handleMusicStart)
.listen(this::handleVolumeChange) .listen(this::handleVolumeChange)
.listen(this::handleGetCurrentVolume) .listen(this::handleGetCurrentVolume)
.listen(AudioEvents.playOnClickButton.class, _ -> { .listen(AudioEvents.clickButton.class, _ -> {
try { try {
playSound("hitsound0.wav", false); playSound("medium-button-click.wav", false);
} catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) { } catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
throw new RuntimeException(e); logger.error(e);
} }
}); });
} }
private void handlePlaySound(AudioEvents.PlayAudio event) { private void handlePlaySound(AudioEvents.PlayEffect event) {
try { try {
this.playSound(event.fileName(), event.loop()); this.playSound(event.fileName(), event.loop());
} catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) { } catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) {
@@ -55,7 +58,7 @@ public class SoundManager {
} }
} }
private void handleStopSound(AudioEvents.StopAudio event) { private void handleStopSound(AudioEvents.StopEffect event) {
this.stopSound(event.clipId()); this.stopSound(event.clipId());
} }
@@ -71,7 +74,6 @@ public class SoundManager {
for (MediaPlayer mediaPlayer : this.activeMusic) { for (MediaPlayer mediaPlayer : this.activeMusic) {
mediaPlayer.setVolume(this.volume); mediaPlayer.setVolume(this.volume);
} }
IO.println("Volume: " + this.volume);
} }
private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) { private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) {
@@ -125,6 +127,8 @@ public class SoundManager {
mediaPlayer.setVolume(this.volume); mediaPlayer.setVolume(this.volume);
mediaPlayer.play(); mediaPlayer.play();
activeMusic.add(mediaPlayer); activeMusic.add(mediaPlayer);
logger.info("Playing background music: {}", ma.getFile().getName());
logger.info("Background music next in line: {}", backgroundMusicQueue.peek().getFile().getName());
} }
private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException { private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
@@ -132,6 +136,7 @@ public class SoundManager {
// Return -1 which indicates resource wasn't available // Return -1 which indicates resource wasn't available
if (asset == null) { if (asset == null) {
logger.warn("Unable to load audio asset: {}", audioFileName);
return -1; return -1;
} }
@@ -146,6 +151,8 @@ public class SoundManager {
clip.start(); clip.start();
} }
logger.debug("Playing sound: {}", asset.getFile().getName());
// Generate id for clip // Generate id for clip
long clipId = idGenerator.nextId(); long clipId = idGenerator.nextId();

View File

@@ -1,6 +1,5 @@
package org.toop.framework.audio.events; package org.toop.framework.audio.events;
import org.toop.framework.asset.resources.MusicAsset;
import org.toop.framework.eventbus.events.EventWithSnowflake; import org.toop.framework.eventbus.events.EventWithSnowflake;
import org.toop.framework.eventbus.events.EventWithoutSnowflake; import org.toop.framework.eventbus.events.EventWithoutSnowflake;
import org.toop.framework.eventbus.events.EventsBase; import org.toop.framework.eventbus.events.EventsBase;
@@ -9,10 +8,10 @@ import java.util.Map;
public class AudioEvents extends EventsBase { public class AudioEvents extends EventsBase {
/** Starts playing a sound. */ /** Starts playing a sound. */
public record PlayAudio(String fileName, boolean loop) public record PlayEffect(String fileName, boolean loop)
implements EventWithoutSnowflake {} implements EventWithoutSnowflake {}
public record StopAudio(long clipId) implements EventWithoutSnowflake {} public record StopEffect(long clipId) implements EventWithoutSnowflake {}
public record StartBackgroundMusic() implements EventWithoutSnowflake {} public record StartBackgroundMusic() implements EventWithoutSnowflake {}
public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {} public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {}
@@ -38,5 +37,5 @@ public class AudioEvents extends EventsBase {
return snowflakeId; return snowflakeId;
} }
} }
public record playOnClickButton() implements EventWithoutSnowflake {} public record clickButton() implements EventWithoutSnowflake {}
} }