mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Added MusicAsset, renamed SoundAsset to be SoundEffectAsset. Created new directories for fx and music types of sound. (#105)
This commit is contained in:
committed by
GitHub
parent
2003fcbf5b
commit
fb0e16acc2
@@ -10,10 +10,12 @@ import javafx.scene.Scene;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.toop.framework.asset.AssetManager;
|
import org.toop.framework.asset.AssetManager;
|
||||||
import org.toop.framework.asset.resources.LocalizationAsset;
|
import org.toop.framework.asset.resources.LocalizationAsset;
|
||||||
|
import org.toop.framework.audio.SoundManager;
|
||||||
|
import org.toop.framework.audio.events.AudioEvents;
|
||||||
|
import org.toop.framework.eventbus.EventFlow;
|
||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
private static Stage stage;
|
private static Stage stage;
|
||||||
@@ -49,6 +51,9 @@ public class App extends Application {
|
|||||||
App.stage = stage;
|
App.stage = stage;
|
||||||
App.scene = scene;
|
App.scene = scene;
|
||||||
App.root = root;
|
App.root = root;
|
||||||
|
|
||||||
|
new EventFlow().addPostEvent(new AudioEvents.StartBackgroundMusic()).postEvent();
|
||||||
|
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(0.3)).postEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void activate(Menu menu) {
|
public static void activate(Menu menu) {
|
||||||
|
|||||||
BIN
app/src/main/resources/assets/audio/music/damned.mp3
Normal file
BIN
app/src/main/resources/assets/audio/music/damned.mp3
Normal file
Binary file not shown.
BIN
app/src/main/resources/assets/audio/music/extraction-point.mp3
Normal file
BIN
app/src/main/resources/assets/audio/music/extraction-point.mp3
Normal file
Binary file not shown.
@@ -102,6 +102,14 @@
|
|||||||
<version>25</version>
|
<version>25</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JavaFX Media -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-media</artifactId>
|
||||||
|
<version>25</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
|
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.reflections</groupId>
|
<groupId>org.reflections</groupId>
|
||||||
@@ -122,24 +130,6 @@
|
|||||||
<target>25</target>
|
<target>25</target>
|
||||||
<release>25</release>
|
<release>25</release>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
<!-- <compilerArgs>-->
|
|
||||||
<!-- <arg>-XDcompilePolicy=simple</arg>-->
|
|
||||||
<!-- <arg>--should-stop=ifError=FLOW</arg>-->
|
|
||||||
<!-- <arg>-Xplugin:ErrorProne</arg>-->
|
|
||||||
<!-- </compilerArgs>-->
|
|
||||||
<!-- <annotationProcessorPaths>-->
|
|
||||||
<!-- <path>-->
|
|
||||||
<!-- <groupId>com.google.errorprone</groupId>-->
|
|
||||||
<!-- <artifactId>error_prone_core</artifactId>-->
|
|
||||||
<!-- <version>2.42.0</version>-->
|
|
||||||
<!-- </path>-->
|
|
||||||
<!-- <!– Other annotation processors go here.-->
|
|
||||||
|
|
||||||
<!-- If 'annotationProcessorPaths' is set, processors will no longer be-->
|
|
||||||
<!-- discovered on the regular -classpath; see also 'Using Error Prone-->
|
|
||||||
<!-- together with other annotation processors' below. –>-->
|
|
||||||
<!-- </annotationProcessorPaths>-->
|
|
||||||
<!-- <fork>true</fork>-->
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -242,4 +242,4 @@ public class AssetLoader {
|
|||||||
int i = name.lastIndexOf('.');
|
int i = name.lastIndexOf('.');
|
||||||
return (i > 0) ? name.substring(i + 1) : "";
|
return (i > 0) ? name.substring(i + 1) : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,4 +147,4 @@ public class AssetManager {
|
|||||||
public static void addAsset(Asset<? extends BaseResource> asset) {
|
public static void addAsset(Asset<? extends BaseResource> asset) {
|
||||||
assets.put(asset.getName(), asset);
|
assets.put(asset.getName(), asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.toop.framework.asset.resources;
|
||||||
|
|
||||||
|
import javafx.scene.media.Media;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
@FileExtension({"mp3"})
|
||||||
|
public class MusicAsset extends BaseResource implements LoadableResource {
|
||||||
|
private Media media;
|
||||||
|
|
||||||
|
public MusicAsset(final File audioFile) {
|
||||||
|
super(audioFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Media getMedia() {
|
||||||
|
if (media == null) {
|
||||||
|
media = new Media(file.toURI().toString());
|
||||||
|
}
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load() {
|
||||||
|
if (media == null) media = new Media(file.toURI().toString());
|
||||||
|
this.isLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unload() {
|
||||||
|
media = null;
|
||||||
|
isLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoaded() {
|
||||||
|
return isLoaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
package org.toop.framework.asset.resources;
|
package org.toop.framework.asset.resources;
|
||||||
|
|
||||||
|
import javafx.scene.media.Media;
|
||||||
|
|
||||||
import javax.sound.sampled.*;
|
import javax.sound.sampled.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
@FileExtension({"wav"})
|
@FileExtension({"wav"})
|
||||||
public class AudioAsset extends BaseResource implements LoadableResource {
|
public class SoundEffectAsset extends BaseResource implements LoadableResource {
|
||||||
|
|
||||||
public AudioAsset(final File audioFile) {
|
public SoundEffectAsset(final File audioFile) {
|
||||||
super(audioFile);
|
super(audioFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.toop.framework.audio;
|
package org.toop.framework.audio;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.scene.media.MediaPlayer;
|
||||||
import org.toop.framework.SnowflakeGenerator;
|
import org.toop.framework.SnowflakeGenerator;
|
||||||
import org.toop.framework.asset.Asset;
|
import org.toop.framework.asset.Asset;
|
||||||
import org.toop.framework.asset.AssetManager;
|
import org.toop.framework.asset.AssetManager;
|
||||||
import org.toop.framework.asset.resources.AudioAsset;
|
import org.toop.framework.asset.resources.MusicAsset;
|
||||||
|
import org.toop.framework.asset.resources.SoundEffectAsset;
|
||||||
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;
|
||||||
|
|
||||||
@@ -12,13 +15,17 @@ import java.util.*;
|
|||||||
import javax.sound.sampled.*;
|
import javax.sound.sampled.*;
|
||||||
|
|
||||||
public class SoundManager {
|
public class SoundManager {
|
||||||
private final Map<Long, Clip> activeClips = new HashMap<>();
|
private final List<MediaPlayer> activeMusic = new ArrayList<>();
|
||||||
private final HashMap<String, AudioAsset> audioResources = new HashMap<>();
|
private final Queue<MusicAsset> backgroundMusicQueue = new LinkedList<>();
|
||||||
|
private final Map<Long, Clip> activeSoundEffects = new HashMap<>();
|
||||||
|
private final HashMap<String, SoundEffectAsset> audioResources = new HashMap<>();
|
||||||
private final SnowflakeGenerator idGenerator = new SnowflakeGenerator(); // TODO: Don't create a new generator
|
private final SnowflakeGenerator idGenerator = new SnowflakeGenerator(); // TODO: Don't create a new generator
|
||||||
|
|
||||||
|
private double volume = 1.0;
|
||||||
|
|
||||||
public SoundManager() {
|
public SoundManager() {
|
||||||
// Get all Audio Resources and add them to a list.
|
// Get all Audio Resources and add them to a list.
|
||||||
for (Asset<AudioAsset> asset : AssetManager.getAllOfType(AudioAsset.class)) {
|
for (Asset<SoundEffectAsset> asset : AssetManager.getAllOfType(SoundEffectAsset.class)) {
|
||||||
try {
|
try {
|
||||||
this.addAudioResource(asset);
|
this.addAudioResource(asset);
|
||||||
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
|
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
|
||||||
@@ -27,7 +34,9 @@ public class SoundManager {
|
|||||||
}
|
}
|
||||||
new EventFlow()
|
new EventFlow()
|
||||||
.listen(this::handlePlaySound)
|
.listen(this::handlePlaySound)
|
||||||
.listen(this::handleStopSound);
|
.listen(this::handleStopSound)
|
||||||
|
.listen(this::handleMusicStart)
|
||||||
|
.listen(this::handleVolumeChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePlaySound(AudioEvents.PlayAudio event) {
|
private void handlePlaySound(AudioEvents.PlayAudio event) {
|
||||||
@@ -42,14 +51,70 @@ public class SoundManager {
|
|||||||
this.stopSound(event.clipId());
|
this.stopSound(event.clipId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAudioResource(Asset<AudioAsset> audioAsset)
|
private void addAudioResource(Asset<SoundEffectAsset> audioAsset)
|
||||||
throws IOException, UnsupportedAudioFileException, LineUnavailableException {
|
throws IOException, UnsupportedAudioFileException, LineUnavailableException {
|
||||||
|
|
||||||
this.audioResources.put(audioAsset.getName(), audioAsset.getResource());
|
this.audioResources.put(audioAsset.getName(), audioAsset.getResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleVolumeChange(AudioEvents.ChangeVolume event) {
|
||||||
|
if (event.newVolume() > 1.0) this.volume = 1.0;
|
||||||
|
else this.volume = Math.max(event.newVolume(), 0.0);
|
||||||
|
for (MediaPlayer mediaPlayer : this.activeMusic) {
|
||||||
|
mediaPlayer.setVolume(this.volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMusicStart(AudioEvents.StartBackgroundMusic e) {
|
||||||
|
backgroundMusicQueue.clear();
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
backgroundMusicQueue.addAll(
|
||||||
|
AssetManager.getAllOfType(MusicAsset.class).stream()
|
||||||
|
.map(Asset::getResource)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
|
backgroundMusicPlayer();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBackgroundMusic(MusicAsset musicAsset) {
|
||||||
|
backgroundMusicQueue.add(musicAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backgroundMusicPlayer() {
|
||||||
|
MusicAsset ma = backgroundMusicQueue.poll();
|
||||||
|
if (ma == null) return;
|
||||||
|
|
||||||
|
MediaPlayer mediaPlayer = new MediaPlayer(ma.getMedia());
|
||||||
|
|
||||||
|
mediaPlayer.setOnEndOfMedia(() -> {
|
||||||
|
addBackgroundMusic(ma);
|
||||||
|
activeMusic.remove(mediaPlayer);
|
||||||
|
mediaPlayer.dispose();
|
||||||
|
ma.unload();
|
||||||
|
backgroundMusicPlayer(); // play next
|
||||||
|
});
|
||||||
|
|
||||||
|
mediaPlayer.setOnStopped(() -> {
|
||||||
|
addBackgroundMusic(ma);
|
||||||
|
activeMusic.remove(mediaPlayer);
|
||||||
|
ma.unload();
|
||||||
|
});
|
||||||
|
|
||||||
|
mediaPlayer.setOnError(() -> {
|
||||||
|
addBackgroundMusic(ma);
|
||||||
|
activeMusic.remove(mediaPlayer);
|
||||||
|
ma.unload();
|
||||||
|
});
|
||||||
|
|
||||||
|
mediaPlayer.setVolume(this.volume);
|
||||||
|
mediaPlayer.play();
|
||||||
|
activeMusic.add(mediaPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
private long playSound(String audioFileName, boolean loop) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
||||||
AudioAsset asset = audioResources.get(audioFileName);
|
SoundEffectAsset asset = audioResources.get(audioFileName);
|
||||||
|
|
||||||
// Return -1 which indicates resource wasn't available
|
// Return -1 which indicates resource wasn't available
|
||||||
if (asset == null){
|
if (asset == null){
|
||||||
@@ -71,12 +136,12 @@ public class SoundManager {
|
|||||||
long clipId = idGenerator.nextId();
|
long clipId = idGenerator.nextId();
|
||||||
|
|
||||||
// store it so we can stop it later
|
// store it so we can stop it later
|
||||||
activeClips.put(clipId, clip); // TODO: Do on snowflake for specific sound to stop
|
activeSoundEffects.put(clipId, clip); // TODO: Do on snowflake for specific sound to stop
|
||||||
|
|
||||||
// remove when finished (only for non-looping sounds)
|
// remove when finished (only for non-looping sounds)
|
||||||
clip.addLineListener(event -> {
|
clip.addLineListener(event -> {
|
||||||
if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) {
|
if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) {
|
||||||
activeClips.remove(clipId);
|
activeSoundEffects.remove(clipId);
|
||||||
clip.close();
|
clip.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -86,7 +151,7 @@ public class SoundManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stopSound(long clipId) {
|
public void stopSound(long clipId) {
|
||||||
Clip clip = activeClips.get(clipId);
|
Clip clip = activeSoundEffects.get(clipId);
|
||||||
|
|
||||||
if (clip == null) {
|
if (clip == null) {
|
||||||
return;
|
return;
|
||||||
@@ -94,14 +159,14 @@ public class SoundManager {
|
|||||||
|
|
||||||
clip.stop();
|
clip.stop();
|
||||||
clip.close();
|
clip.close();
|
||||||
activeClips.remove(clipId);
|
activeSoundEffects.remove(clipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopAllSounds() {
|
public void stopAllSounds() {
|
||||||
for (Clip clip : activeClips.values()) {
|
for (Clip clip : activeSoundEffects.values()) {
|
||||||
clip.stop();
|
clip.stop();
|
||||||
clip.close();
|
clip.close();
|
||||||
}
|
}
|
||||||
activeClips.clear();
|
activeSoundEffects.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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.EventWithoutSnowflake;
|
import org.toop.framework.eventbus.events.EventWithoutSnowflake;
|
||||||
import org.toop.framework.eventbus.events.EventsBase;
|
import org.toop.framework.eventbus.events.EventsBase;
|
||||||
|
|
||||||
@@ -9,4 +10,8 @@ public class AudioEvents extends EventsBase {
|
|||||||
implements EventWithoutSnowflake {}
|
implements EventWithoutSnowflake {}
|
||||||
|
|
||||||
public record StopAudio(long clipId) implements EventWithoutSnowflake {}
|
public record StopAudio(long clipId) implements EventWithoutSnowflake {}
|
||||||
|
|
||||||
|
public record StartBackgroundMusic() implements EventWithoutSnowflake {}
|
||||||
|
public record ChangeVolume(double newVolume) implements EventWithoutSnowflake {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user