mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Working sound effect for clicking, bug when using audio volume changer (changes some sounds to be wrong)
This commit is contained in:
@@ -23,8 +23,10 @@ public final class MainMenu extends Menu {
|
||||
public MainMenu() {
|
||||
final Region background = createBackground();
|
||||
|
||||
tictactoe = createButton(loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); });
|
||||
reversi = createButton(loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); });
|
||||
tictactoe = createButton(
|
||||
loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); });
|
||||
reversi = createButton(
|
||||
loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); });
|
||||
|
||||
final VBox gamesBox = new VBox(10, tictactoe, reversi);
|
||||
gamesBox.setAlignment(Pos.TOP_LEFT);
|
||||
|
||||
@@ -4,6 +4,8 @@ import javafx.scene.control.Button;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.text.Text;
|
||||
import org.toop.framework.audio.events.AudioEvents;
|
||||
import org.toop.framework.eventbus.EventFlow;
|
||||
|
||||
public abstract class Menu {
|
||||
protected Pane pane;
|
||||
@@ -34,7 +36,10 @@ public abstract class Menu {
|
||||
|
||||
public Button createButton(String css, String x, Runnable runnable) {
|
||||
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);
|
||||
|
||||
return button;
|
||||
|
||||
@@ -55,7 +55,7 @@ public final class OptionsMenu extends Menu {
|
||||
selectLanguage.getItems().add(locFile);
|
||||
}
|
||||
|
||||
selectLanguage.setConverter(new javafx.util.StringConverter<Locale>() {
|
||||
selectLanguage.setConverter(new javafx.util.StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Locale locale) {
|
||||
return locale.getDisplayName();
|
||||
@@ -67,7 +67,12 @@ public final class OptionsMenu extends Menu {
|
||||
}
|
||||
});
|
||||
|
||||
selectLanguage.setOnShowing(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
});
|
||||
|
||||
selectLanguage.setOnAction(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
Locale selectedLocale = selectLanguage.getSelectionModel().getSelectedItem();
|
||||
if (selectedLocale != null) {
|
||||
AppContext.setLocale(selectedLocale);
|
||||
@@ -87,7 +92,12 @@ public final class OptionsMenu extends Menu {
|
||||
selectScreen.getItems().add(screen);
|
||||
}
|
||||
|
||||
selectScreen.setOnShowing(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
});
|
||||
|
||||
selectScreen.setOnAction(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
int selectedIndex = selectScreen.getSelectionModel().getSelectedIndex();
|
||||
Object selectedItem = selectScreen.getSelectionModel().getSelectedItem();
|
||||
|
||||
@@ -102,6 +112,17 @@ public final class OptionsMenu extends Menu {
|
||||
for (DisplayMode displayMode : currentScreenDevice.getDisplayModes()) {
|
||||
selectWindowSize.getItems().add(displayMode);
|
||||
}
|
||||
selectWindowSize.setOnShowing(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
});
|
||||
selectWindowSize.setOnAction(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
int selectedIndex = selectWindowSize.getSelectionModel().getSelectedIndex();
|
||||
Object selectedItem = selectWindowSize.getSelectionModel().getSelectedItem();
|
||||
|
||||
System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem);
|
||||
System.out.println(" ChoiceBox.getValue(): " + selectWindowSize.getValue());
|
||||
});
|
||||
return selectWindowSize;
|
||||
}
|
||||
|
||||
@@ -109,6 +130,7 @@ public final class OptionsMenu extends Menu {
|
||||
final CheckBox setFullscreen = new CheckBox("Fullscreen");
|
||||
setFullscreen.setSelected(App.isFullscreen());
|
||||
setFullscreen.setOnAction(event -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent();
|
||||
boolean isSelected = setFullscreen.isSelected();
|
||||
App.setFullscreen(isSelected);
|
||||
});
|
||||
@@ -131,11 +153,24 @@ public final class OptionsMenu extends Menu {
|
||||
|
||||
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;
|
||||
|
||||
int value = newVal.intValue();
|
||||
valueLabel.setText(String.valueOf(value));
|
||||
|
||||
new EventFlow().addPostEvent(new AudioEvents.PlayEffect("soft-button-click.wav", false)).asyncPostEvent();
|
||||
}
|
||||
valueLabel.setText(String.valueOf(newVal.intValue()));
|
||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newVal.doubleValue()/100.0))
|
||||
.asyncPostEvent();
|
||||
});
|
||||
|
||||
return volumeSlider;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.toop.framework.asset;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.toop.framework.asset.resources.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -46,6 +48,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* </ul>
|
||||
*/
|
||||
public class ResourceManager {
|
||||
private static final Logger logger = LogManager.getLogger(ResourceManager.class);
|
||||
private static final ResourceManager INSTANCE = new ResourceManager();
|
||||
private static final Map<String, ResourceMeta<? extends BaseResource>> assets = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
@@ -23,7 +23,10 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
|
||||
Clip clip = AudioSystem.getClip();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -32,6 +35,20 @@ public class SoundEffectAsset extends BaseResource implements LoadableResource {
|
||||
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
|
||||
public void load() {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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.asset.ResourceManager;
|
||||
import org.toop.framework.asset.ResourceMeta;
|
||||
@@ -15,6 +17,7 @@ import java.util.*;
|
||||
import javax.sound.sampled.*;
|
||||
|
||||
public class SoundManager {
|
||||
private static final Logger logger = LogManager.getLogger(SoundManager.class);
|
||||
private final List<MediaPlayer> activeMusic = new ArrayList<>();
|
||||
private final Queue<MusicAsset> backgroundMusicQueue = new LinkedList<>();
|
||||
private final Map<Long, Clip> activeSoundEffects = new HashMap<>();
|
||||
@@ -38,16 +41,16 @@ public class SoundManager {
|
||||
.listen(this::handleMusicStart)
|
||||
.listen(this::handleVolumeChange)
|
||||
.listen(this::handleGetCurrentVolume)
|
||||
.listen(AudioEvents.playOnClickButton.class, _ -> {
|
||||
.listen(AudioEvents.clickButton.class, _ -> {
|
||||
try {
|
||||
playSound("hitsound0.wav", false);
|
||||
playSound("medium-button-click.wav", false);
|
||||
} 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 {
|
||||
this.playSound(event.fileName(), event.loop());
|
||||
} 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());
|
||||
}
|
||||
|
||||
@@ -71,7 +74,6 @@ public class SoundManager {
|
||||
for (MediaPlayer mediaPlayer : this.activeMusic) {
|
||||
mediaPlayer.setVolume(this.volume);
|
||||
}
|
||||
IO.println("Volume: " + this.volume);
|
||||
}
|
||||
|
||||
private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) {
|
||||
@@ -125,13 +127,15 @@ public class SoundManager {
|
||||
mediaPlayer.setVolume(this.volume);
|
||||
mediaPlayer.play();
|
||||
activeMusic.add(mediaPlayer);
|
||||
logger.info("Playing background music: {}", ma.getFile().getName());
|
||||
}
|
||||
|
||||
private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
||||
SoundEffectAsset asset = audioResources.get(audioFileName);
|
||||
|
||||
// Return -1 which indicates resource wasn't available
|
||||
if (asset == null){
|
||||
if (asset == null) {
|
||||
logger.warn("Unable to load audio asset: {}", audioFileName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -146,6 +150,8 @@ public class SoundManager {
|
||||
clip.start();
|
||||
}
|
||||
|
||||
logger.info("Playing sound: {}", asset.getFile().getName());
|
||||
|
||||
// Generate id for clip
|
||||
long clipId = idGenerator.nextId();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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.EventWithoutSnowflake;
|
||||
import org.toop.framework.eventbus.events.EventsBase;
|
||||
@@ -9,10 +8,10 @@ import java.util.Map;
|
||||
|
||||
public class AudioEvents extends EventsBase {
|
||||
/** Starts playing a sound. */
|
||||
public record PlayAudio(String fileName, boolean loop)
|
||||
public record PlayEffect(String fileName, boolean loop)
|
||||
implements EventWithoutSnowflake {}
|
||||
|
||||
public record StopAudio(long clipId) implements EventWithoutSnowflake {}
|
||||
public record StopEffect(long clipId) implements EventWithoutSnowflake {}
|
||||
|
||||
public record StartBackgroundMusic() implements EventWithoutSnowflake {}
|
||||
public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {}
|
||||
@@ -38,5 +37,5 @@ public class AudioEvents extends EventsBase {
|
||||
return snowflakeId;
|
||||
}
|
||||
}
|
||||
public record playOnClickButton() implements EventWithoutSnowflake {}
|
||||
public record clickButton() implements EventWithoutSnowflake {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user