diff --git a/app/src/main/java/org/toop/Main.java b/app/src/main/java/org/toop/Main.java index 03205ed..1f91081 100644 --- a/app/src/main/java/org/toop/Main.java +++ b/app/src/main/java/org/toop/Main.java @@ -1,7 +1,7 @@ package org.toop; import org.toop.app.gui.LocalServerSelector; -import org.toop.framework.audio.AudioFiles; +import org.toop.framework.assets.AssetManager; import org.toop.framework.audio.SoundManager; import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.eventbus.EventFlow; @@ -9,18 +9,24 @@ import org.toop.framework.networking.NetworkingClientManager; import org.toop.framework.networking.NetworkingInitializationException; import javax.sound.sampled.*; +import java.io.File; import java.io.IOException; import java.nio.file.NotDirectoryException; public class Main { static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException { - initSystems(); - new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu", true)).asyncPostEvent(); + var a = new AssetManager(new File("app/src/main/resources/assets")); + var b = new NetworkingClientManager(); + var c = new SoundManager(a); + +// IO.println(a.getAssets()); + IO.println(c.getClips()); + + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("mainmenu.wav", true)).asyncPostEvent(); + new EventFlow().addPostEvent(new AudioEvents.PlayAudio("sadtrombone.wav", true)).asyncPostEvent(); + javax.swing.SwingUtilities.invokeLater(LocalServerSelector::new); } - private static void initSystems() throws NetworkingInitializationException, NotDirectoryException { - new NetworkingClientManager(); - new SoundManager(new AudioFiles("app/src/main/resources/audio/")); - } + private static void initSystems() throws NetworkingInitializationException, NotDirectoryException {} } diff --git a/app/src/main/resources/audio/dramatic.wav b/app/src/main/resources/assets/audio/dramatic.wav similarity index 100% rename from app/src/main/resources/audio/dramatic.wav rename to app/src/main/resources/assets/audio/dramatic.wav diff --git a/app/src/main/resources/audio/hitsound0.wav b/app/src/main/resources/assets/audio/hitsound0.wav similarity index 100% rename from app/src/main/resources/audio/hitsound0.wav rename to app/src/main/resources/assets/audio/hitsound0.wav diff --git a/app/src/main/resources/audio/hitsound1.wav b/app/src/main/resources/assets/audio/hitsound1.wav similarity index 100% rename from app/src/main/resources/audio/hitsound1.wav rename to app/src/main/resources/assets/audio/hitsound1.wav diff --git a/app/src/main/resources/audio/mainmenu.wav b/app/src/main/resources/assets/audio/mainmenu.wav similarity index 100% rename from app/src/main/resources/audio/mainmenu.wav rename to app/src/main/resources/assets/audio/mainmenu.wav diff --git a/app/src/main/resources/audio/sadtrombone.wav b/app/src/main/resources/assets/audio/sadtrombone.wav similarity index 100% rename from app/src/main/resources/audio/sadtrombone.wav rename to app/src/main/resources/assets/audio/sadtrombone.wav diff --git a/app/src/main/resources/audio/scawymusic.wav b/app/src/main/resources/assets/audio/scawymusic.wav similarity index 100% rename from app/src/main/resources/audio/scawymusic.wav rename to app/src/main/resources/assets/audio/scawymusic.wav diff --git a/app/src/main/resources/audio/suspensful.wav b/app/src/main/resources/assets/audio/suspensful.wav similarity index 100% rename from app/src/main/resources/audio/suspensful.wav rename to app/src/main/resources/assets/audio/suspensful.wav diff --git a/app/src/main/resources/audio/testsound.wav b/app/src/main/resources/assets/audio/testsound.wav similarity index 100% rename from app/src/main/resources/audio/testsound.wav rename to app/src/main/resources/assets/audio/testsound.wav diff --git a/app/src/main/resources/audio/winsound.wav b/app/src/main/resources/assets/audio/winsound.wav similarity index 100% rename from app/src/main/resources/audio/winsound.wav rename to app/src/main/resources/assets/audio/winsound.wav diff --git a/app/src/main/resources/image/background.jpg b/app/src/main/resources/assets/image/background.jpg similarity index 100% rename from app/src/main/resources/image/background.jpg rename to app/src/main/resources/assets/image/background.jpg diff --git a/app/src/main/resources/image/icon.png b/app/src/main/resources/assets/image/icon.png similarity index 100% rename from app/src/main/resources/image/icon.png rename to app/src/main/resources/assets/image/icon.png diff --git a/framework/pom.xml b/framework/pom.xml index 4356334..ae47b55 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -96,6 +96,12 @@ 4.0.0 + + org.openjfx + javafx-controls + 25 + + diff --git a/framework/src/main/java/org/toop/framework/assets/Asset.java b/framework/src/main/java/org/toop/framework/assets/Asset.java index f3b9815..77db13d 100644 --- a/framework/src/main/java/org/toop/framework/assets/Asset.java +++ b/framework/src/main/java/org/toop/framework/assets/Asset.java @@ -1,24 +1,29 @@ package org.toop.framework.assets; import org.toop.framework.SnowflakeGenerator; +import org.toop.framework.assets.resources.Resource; -import java.nio.file.Path; +public class Asset { + private final Long id; // IS this needed? + private final String name; + private final T resource; -public class Asset { - private Long id; // IS this needed? - private String name; - private Path assetPath; - private String asset; - - public Asset(String name, Path assetPath) { + public Asset(String name, T resource) { this.id = new SnowflakeGenerator().nextId(); this.name = name; - this.assetPath = assetPath; + this.resource = resource; } - private void loadAsset() { - java.nio.file.Path - this.asset = this.assetPath; + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public T getResource() { + return this.resource; } } diff --git a/framework/src/main/java/org/toop/framework/assets/AssetLoader.java b/framework/src/main/java/org/toop/framework/assets/AssetLoader.java new file mode 100644 index 0000000..65d8f5b --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/AssetLoader.java @@ -0,0 +1,64 @@ +package org.toop.framework.assets; + +import org.toop.framework.assets.resources.AudioResource; +import org.toop.framework.assets.resources.FontResource; +import org.toop.framework.assets.resources.ImageResource; +import org.toop.framework.assets.resources.Resource; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Objects; + +public class AssetLoader { + private final File rootFolder; + private final ArrayList> assets = new ArrayList<>(); + + public AssetLoader(File rootFolder) { + this.rootFolder = rootFolder; + fileSearcher(rootFolder); + } + + public File getRootFolder() { + return this.rootFolder; + } + + public ArrayList> getAssets() { + return this.assets; + } + + private Resource resourceMapper(File file) throws FileNotFoundException { + return switch (getExtension(file.getName())) { + case "wav" -> new AudioResource(file).load(); + case "png" -> new ImageResource(file).load(); + default -> null; + }; + } + + public static String getExtension(String name) { + String extension = ""; + + int i = name.lastIndexOf('.'); + if (i > 0) { + extension = name.substring(i+1); + } + return extension; + } + + private void fileSearcher(final File folder) { + for (final File fileEntry : Objects.requireNonNull(folder.listFiles())) { + if (fileEntry.isDirectory()) { + fileSearcher(fileEntry); + } else { + try { + this.assets.add( + new Asset<>(fileEntry.getName(), this.resourceMapper(fileEntry)) + ); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + } + } + +} diff --git a/framework/src/main/java/org/toop/framework/assets/AssetManager.java b/framework/src/main/java/org/toop/framework/assets/AssetManager.java index 04b9c87..15d9376 100644 --- a/framework/src/main/java/org/toop/framework/assets/AssetManager.java +++ b/framework/src/main/java/org/toop/framework/assets/AssetManager.java @@ -1,12 +1,38 @@ package org.toop.framework.assets; +import org.apache.maven.surefire.shared.io.function.IOBaseStream; +import org.toop.framework.assets.resources.Resource; + +import java.io.File; +import java.nio.file.Path; import java.util.HashMap; public class AssetManager { - private HashMap assets = new HashMap<>(); - - public AssetManager() { + private final HashMap> assets = new HashMap<>(); + public AssetManager(File rootFolder) { + for (Asset x : new AssetLoader(rootFolder).getAssets()) { + this.assets.put(x.getName(), x); + } } + + public HashMap> getAllResourceOfType(Class resourceClass) { + HashMap> a = new HashMap<>(); + for (Asset b : this.assets.values()) { + if (resourceClass.isInstance(b.getResource())) { + a.put(b.getName(), (Asset) b); + } + } + return a; + } + + public HashMap> getAssets() { + return this.assets; + } + + public Asset getAsset(String assetName) { + return assets.get(assetName); + } + } diff --git a/framework/src/main/java/org/toop/framework/assets/resources/AudioResource.java b/framework/src/main/java/org/toop/framework/assets/resources/AudioResource.java new file mode 100644 index 0000000..f46557b --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/resources/AudioResource.java @@ -0,0 +1,35 @@ +package org.toop.framework.assets.resources; + +import javax.sound.sampled.*; +import java.io.*; + +public class AudioResource extends Resource { + private AudioInputStream audioInputStream = null; + private Clip clip = null; + public AudioResource(File audioFile) { + super(audioFile); + } + + public AudioInputStream getAudioStream(){ + return this.audioInputStream; + } + + public Clip getClip() { + return this.clip; + } + + @Override + public Resource load() { + try { + this.audioInputStream = AudioSystem.getAudioInputStream(this.stream); + Clip clip = AudioSystem.getClip(); + clip.open(this.audioInputStream); + this.clip = clip; + } catch (UnsupportedAudioFileException | LineUnavailableException e) { + throw new RuntimeException(e); + } catch (IOException e) { // TODO: Error handling + throw new RuntimeException(e); + } + return this; + } +} diff --git a/framework/src/main/java/org/toop/framework/assets/resources/FontResource.java b/framework/src/main/java/org/toop/framework/assets/resources/FontResource.java new file mode 100644 index 0000000..1ae4802 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/resources/FontResource.java @@ -0,0 +1,9 @@ +package org.toop.framework.assets.resources; + +import java.io.File; + +public class FontResource extends Resource { + public FontResource(File fontFile) { + super(fontFile); + } +} diff --git a/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java b/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java new file mode 100644 index 0000000..8f5bf05 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/resources/ImageResource.java @@ -0,0 +1,26 @@ +package org.toop.framework.assets.resources; + +import javafx.scene.image.Image; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public class ImageResource extends Resource { + + private Image image = null; + + public ImageResource(File imageFile) { + super(imageFile); + } + + public Image getImage() { + return this.image; + } + + @Override + public Resource load() { + this.image = new Image(this.stream); + return this; + } +} diff --git a/framework/src/main/java/org/toop/framework/assets/resources/Resource.java b/framework/src/main/java/org/toop/framework/assets/resources/Resource.java new file mode 100644 index 0000000..8c3cd19 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/assets/resources/Resource.java @@ -0,0 +1,29 @@ +package org.toop.framework.assets.resources; + +import java.io.*; + +public abstract class Resource { + final InputStream stream; + final File file; + + Resource(final File file) { + this.file = file; + try { + this.stream = new BufferedInputStream(new FileInputStream(file)); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + public Resource load() { + return this; + } + + public InputStream getInputStream() { + return this.stream; + } + + public File getFile() { + return this.file; + } +} diff --git a/framework/src/main/java/org/toop/framework/audio/AudioFiles.java b/framework/src/main/java/org/toop/framework/audio/AudioFiles.java deleted file mode 100644 index 6a1af3a..0000000 --- a/framework/src/main/java/org/toop/framework/audio/AudioFiles.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.toop.framework.audio; - -import java.io.IOException; -import java.nio.file.*; -import java.util.HashSet; -import java.util.Set; - -public class AudioFiles { - - private Set audioFiles; - private String audioDirectory; - - public AudioFiles(String audioDirectory) throws NotDirectoryException { - if (!audioDirectory.endsWith("/") && !audioDirectory.endsWith("\\")) { - throw new NotDirectoryException(audioDirectory); - } - this.audioFiles = AudioFiles.getAudioFiles(audioDirectory); - this.audioDirectory = audioDirectory; - } - - public Set getAudioFiles() { - return this.audioFiles; - } - - public String getAudioDirectory() { - return this.audioDirectory; - } - - public String getAudioFile(String file) { - if (!audioFiles.contains(file)) { - return null; - } - return audioDirectory + file; - } - - public static String removeAllKeepOnlyName(String fileDirectoryNameExtension) { - String withoutExtensionAndDirectory = ""; - - int i = fileDirectoryNameExtension.lastIndexOf('.'); - if (i > 0) { - withoutExtensionAndDirectory = fileDirectoryNameExtension.substring(0, i); - } - int y = withoutExtensionAndDirectory.lastIndexOf("/"); - int k = withoutExtensionAndDirectory.lastIndexOf("\\"); - if (y > 0) { - withoutExtensionAndDirectory = withoutExtensionAndDirectory.substring(y+1); - } else if (k > 0) { - withoutExtensionAndDirectory = withoutExtensionAndDirectory.substring(k+1); - } - return withoutExtensionAndDirectory; - } - - private static Set getAudioFiles(String audioDirectory) { - Set fileSet = new HashSet<>(); - try (DirectoryStream stream = Files.newDirectoryStream(Paths.get(audioDirectory))) { - for (Path path : stream) { - if (!Files.isDirectory(path)) { - String extension = ""; - - int i = path.getFileName().toString().lastIndexOf('.'); - if (i > 0) { - extension = path.getFileName().toString().substring(i+1); - } - if (extension.equalsIgnoreCase("wave") || extension.equalsIgnoreCase("wav") - || extension.equalsIgnoreCase("mp3")) - fileSet.add(path.getFileName() - .toString()); - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - return fileSet; - } -} diff --git a/framework/src/main/java/org/toop/framework/audio/SoundManager.java b/framework/src/main/java/org/toop/framework/audio/SoundManager.java index 3ef9be4..939e8c8 100644 --- a/framework/src/main/java/org/toop/framework/audio/SoundManager.java +++ b/framework/src/main/java/org/toop/framework/audio/SoundManager.java @@ -1,5 +1,9 @@ package org.toop.framework.audio; +import org.toop.framework.assets.Asset; +import org.toop.framework.assets.AssetManager; +import org.toop.framework.assets.resources.AudioResource; +import org.toop.framework.assets.resources.Resource; import org.toop.framework.audio.events.AudioEvents; import org.toop.framework.eventbus.EventFlow; @@ -12,22 +16,22 @@ public class SoundManager { private final Map activeClips = new HashMap<>(); private HashMap clips = new HashMap<>(); - private AudioFiles audioFiles; + private AssetManager assetManager; private Vector afs; private Vector sizes; private Vector infos; private Vector audios; private int num=0; - public SoundManager(AudioFiles audioFiles) { + public SoundManager(AssetManager ass) { afs=new Vector(); sizes=new Vector(); infos=new Vector(); audios=new Vector(); - this.audioFiles = audioFiles; - for (var file : audioFiles.getAudioFiles()) { + this.assetManager = ass; + for (Asset resource : ass.getAllResourceOfType(AudioResource.class).values()) { try { - addClip(audioFiles.getAudioDirectory() + file); + addClip(resource); } catch (IOException e) { throw new RuntimeException(e); } catch (UnsupportedAudioFileException e) { @@ -42,33 +46,27 @@ public class SoundManager { } private void handlePlaySound(AudioEvents.PlayAudio event) { - try { - this.playSound(event.fileNameNoExtensionAndNoDirectory(), event.loop()); - } catch (UnsupportedAudioFileException e) { - throw new RuntimeException(e); - } catch (LineUnavailableException e) { - throw new RuntimeException(e); - } + this.playSound(event.fileNameNoExtensionAndNoDirectory(), event.loop()); } private void handleStopSound(AudioEvents.StopAudio event) { this.stopSound(event.fileNameNoExtensionAndNoDirectory()); } - private void addClip(String s) + private void addClip(Asset audiol) throws IOException, UnsupportedAudioFileException, LineUnavailableException { - AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(s)); - AudioFormat af = audioInputStream.getFormat(); - int size = (int) (af.getFrameSize() * audioInputStream.getFrameLength()); + AudioResource ad = audiol.getResource(); + AudioFormat af = ad.getAudioStream().getFormat(); + int size = (int) (af.getFrameSize() * ad.getAudioStream().getFrameLength()); byte[] audio = new byte[size]; DataLine.Info info = new DataLine.Info(Clip.class, af, size); - audioInputStream.read(audio, 0, size); + ad.getInputStream().read(audio, 0, size); afs.add(af); sizes.add(new Integer(size)); infos.add(info); audios.add(audio); - this.clips.put(AudioFiles.removeAllKeepOnlyName(s), this.audios.size()-1); + this.clips.put(audiol.getName(), this.audios.size()-1); num++; } @@ -87,30 +85,39 @@ public class SoundManager { return new ByteArrayInputStream(data); } - private void playSound(String audioFileName, boolean loop) - throws UnsupportedAudioFileException, LineUnavailableException { - int x = clips.get(audioFileName); - if (x > num) { - System.out.println("playSound: sample nr[" + x + "] is not available"); - } else { - Clip clip = (Clip) AudioSystem.getLine((DataLine.Info) infos.elementAt(x)); - clip.open((AudioFormat) afs.elementAt(x), (byte[]) audios.elementAt(x), - 0, ((Integer) sizes.elementAt(x)).intValue()); + private void playSound(String audioFileName, boolean loop) { + var b = this.assetManager.getAllResourceOfType(AudioResource.class); + b.get(audioFileName).getResource().getClip().start(); + } - clip.start(); - if (loop) clip.loop(Clip.LOOP_CONTINUOUSLY); +// private void playSound(String audioFileName, boolean loop) +// throws UnsupportedAudioFileException, LineUnavailableException { +// int x = clips.get(audioFileName); +// if (x > num) { +// System.out.println("playSound: sample nr[" + x + "] is not available"); +// } else { +// Clip clip = (Clip) AudioSystem.getLine((DataLine.Info) infos.elementAt(x)); +//// clip.open((AudioFormat) afs.elementAt(x), (byte[]) audios.elementAt(x), +//// 0, ((Integer) sizes.elementAt(x)).intValue()); +// +// clip.start(); +// if (loop) clip.loop(Clip.LOOP_CONTINUOUSLY); +// +// // store it so we can stop it later +// activeClips.put(audioFileName, clip); // TODO: Do on snowflake for specific sound to stop +// +// // remove when finished (only for non-looping sounds) +// clip.addLineListener(event -> { +// if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) { +// activeClips.remove(audioFileName); +// clip.close(); +// } +// }); +// } +// } - // store it so we can stop it later - activeClips.put(audioFileName, clip); // TODO: Do on snowflake for specific sound to stop - - // remove when finished (only for non-looping sounds) - clip.addLineListener(event -> { - if (event.getType() == LineEvent.Type.STOP && !clip.isRunning()) { - activeClips.remove(audioFileName); - clip.close(); - } - }); - } + public HashMap getClips() { + return this.clips; } public void stopSound(String audioFileName) {