From 2afe7f0e42ee339afdaa2068ec0df529a55a0579 Mon Sep 17 00:00:00 2001
From: jg175 <jg175@hdm-stuttgart.de>
Date: Fri, 26 Jan 2024 15:23:13 +0100
Subject: [PATCH] UPDATE: playing music automatically according to Gamestate

---
 .../Controller/Enum/GameState.java            |   1 +
 .../Controller/GameSceneController.java       |   6 +-
 .../battlearena/Model/Entity/Player.java      |   8 +-
 .../battlearena/Model/Map/TileManager.java    |  30 ++---
 .../battlearena/Model/Sound/MusicPlayer.java  | 117 +++++++++++-------
 .../battlearena/Model/Sound/SoundEffects.java |  38 ++++--
 .../Model/Sound/SoundFileManager.java         |  39 ++++++
 7 files changed, 166 insertions(+), 73 deletions(-)
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundFileManager.java

diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
index 946a857e..c45a5fd2 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
@@ -1,6 +1,7 @@
 package de.hdm_stuttgart.battlearena.Controller.Enum;
 
 public enum GameState {
+    NONE(""),
     MENU("src/main/resources/sound/music/menu"),
     PAUSE("src/main/resources/sound/music/game"),
     PLAYING("src/main/resources/sound/music/game"),
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
index 298e2a4a..e0deff2b 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
@@ -194,7 +194,7 @@ public class GameSceneController implements Initializable {
 
         SoundEffects soundEffects = new SoundEffects();
         try {
-            soundEffects.playSoundEffect(this);
+            soundEffects.playSoundEffect(this, inputHandler);
         } catch (IOException e) {
             throw new RuntimeException(e);
         } catch (InterruptedException e) {
@@ -267,4 +267,8 @@ public class GameSceneController implements Initializable {
     public int getScaledTileSize() {
         return scaledTileSize;
     }
+
+    public InputHandler getInputHandler(){
+        return inputHandler;
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
index b20727ef..07a125c8 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
@@ -113,22 +113,22 @@ class Player implements IEntity {
             maxPlayerHealth = 50;
             health = 50;
             damage = 5;
-            playerSpeed = 5; //5
+            playerSpeed = 1; //5
         } else if (entityClass == EntityClass.HIGH_BORN) {
             maxPlayerHealth = 100;
             health = 75;
             damage = 2;
-            playerSpeed = 3; //3
+            playerSpeed = 1; //3
         } else if (entityClass == EntityClass.LOW_BORN) {
             maxPlayerHealth = 10;
             health = 10;
             damage = 10;
-            playerSpeed = 7; //7
+            playerSpeed = 1; //7
         } else {
             maxPlayerHealth = 40;
             health = 15;
             damage = 7;
-            playerSpeed = 5; //5
+            playerSpeed = 1; //5
         }
     }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
index 2d32d92f..533ab0f0 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
@@ -39,13 +39,13 @@ public class TileManager {
             try {
                 //Textures of walkable tiles
                 tileSet[0] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand00.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand00.png"))), SFXLoop.GRASS);
                 tileSet[1] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand01.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand01.png"))), SFXLoop.GRASS);
                 tileSet[2] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassPathGrassLand02.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassPathGrassLand02.png"))), SFXLoop.GRASS);
                 tileSet[3] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand03.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand03.png"))), SFXLoop.GRASS);
                 tileSet[4] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
                         new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
                 tileSet[5] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
@@ -60,25 +60,25 @@ public class TileManager {
                         new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
                 //Textures of solid tiles + non destructible
                 tileSet[10] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGrassLand00.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGrassLand00.png"))), SFXLoop.GRASS);
                 tileSet[11] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneEndLeftGrassLand01.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneEndLeftGrassLand01.png"))), SFXLoop.GRASS);
                 tileSet[12] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneEndRightGrassLand02.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneEndRightGrassLand02.png"))), SFXLoop.GRASS);
                 tileSet[13] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneWindowGrassLand03.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneWindowGrassLand03.png"))), SFXLoop.GRASS);
                 tileSet[14] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGateGrassLand04.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGateGrassLand04.png"))), SFXLoop.GRASS);
                 tileSet[15] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGrassLand05.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/building/StoneGrassLand05.png"))), SFXLoop.GRASS);
                 tileSet[16] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand04.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/grass_biom/ground/GrassGrassLand04.png"))), SFXLoop.GRASS);
                 tileSet[17] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.GRASS);
                 tileSet[18] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.GRASS);
                 tileSet[19] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
-                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
+                        new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.GRASS);
                 //Testures of destructible tiles
                 tileSet[20] = TileFactory.createTile(TileType.NON_WALKABLE,TileType.NON_DESTRUCTIBLE,
                         new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/NoTexture.png"))), SFXLoop.NONE);
@@ -175,7 +175,7 @@ public class TileManager {
                 try {
                     //Textures of walkable tiles
                     tileSet[0] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
-                            new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/bomberman/ground/GrassBombLand00.png"))),SFXLoop.NONE);
+                            new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/bomberman/ground/GrassBombLand00.png"))),SFXLoop.GRASS);
                     tileSet[1] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
                             new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/bomberman/ground/GrassBombLand01.png"))), SFXLoop.NONE);
                     tileSet[2] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
index 8305eac0..d0e80a6a 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
@@ -1,7 +1,11 @@
 package de.hdm_stuttgart.battlearena.Model.Sound;
 
 
+import de.hdm_stuttgart.battlearena.Controller.Enum.GameState;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.AppSettings;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Persistence;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
+import javafx.application.Platform;
 import javafx.fxml.Initializable;
 import javafx.scene.media.Media;
 import javafx.scene.media.MediaPlayer;
@@ -17,74 +21,103 @@ import java.nio.file.Paths;
 import java.util.List;
 import java.util.Random;
 import java.util.ResourceBundle;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-public class MusicPlayer {
+public class MusicPlayer implements Initializable{
+
+
+
     private static final Logger log = LogManager.getLogger(MusicPlayer.class);
+
+    private static final MusicPlayer  musicPlayerSingleton = new MusicPlayer();
+
+    private AppSettings settings = Persistence.getInstance().getSettings();
     private MediaPlayer mediaPlayer;
-    private RuntimeInfo runtimeInfo;
+    private GameState currentGameState;
+    private SoundFileManager fileManager;
 
-        //Runtime
+    public MusicPlayer(){}
 
 
-    public void playGameMusic(MusicType musicType) throws IOException {
-        Path pathTypeOfMusic = Paths.get(musicType.getPath());
-        List<Path> musicPaths = getFilePathsFromResources(pathTypeOfMusic);
-        String randomPath = getRandomFilePath(musicPaths);
-        String resource = convertPathToResourcePath(randomPath);
-        setVolume(runtimeInfo.getMusicVolume());
-        playMusicLoop(resource);
+    @Override
+    public void initialize(URL url, ResourceBundle resourceBundle) {
+        currentGameState = GameState.NONE;
+        startGameStateMonitoring();
     }
 
-    protected void playMusicLoop(String path){
-        Thread thread = new Thread(() -> {
-            Media media = new Media(getClass().getResource(path).toExternalForm());
-            mediaPlayer = new MediaPlayer(media);
-            mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
-            mediaPlayer.play();
-            log.info("Music is playing");
-        });
-        thread.setDaemon(true);
-        thread.start();
+
+    private void startGameStateMonitoring(){
+        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
+        scheduler.scheduleAtFixedRate(()->{
+           GameState newGameState = RuntimeInfo.getInstance().getGameState();
+           if(currentGameState != newGameState){
+               currentGameState = newGameState;
+               Platform.runLater(()-> updateMusic());
+           }
+        },0,1, TimeUnit.SECONDS);
     }
 
-    public void setVolume(int volume){
-        mediaPlayer.setVolume(volume / 100);
+
+
+    private void updateMusic(){
+        stopMusic();
+        playRandomMusic();
     }
 
-    public int getVolume(){
-        return (int) mediaPlayer.getVolume() * 100;
+    private void playRandomMusic() {
+        String path = currentGameState.getPath();
+        if(!path.isEmpty()) {
+            Path pathTypeOfMusic = Paths.get(path);
+
+            List<Path> musicPaths;
+            try {
+                musicPaths = fileManager.getFilePathsFromResources(pathTypeOfMusic);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+
+            String randomPath = fileManager.getRandomFilePath(musicPaths);
+            String resource = fileManager.convertPathToResourcePath(randomPath);
+
+            Thread thread = new Thread(() -> {
+                Media media = new Media(getClass().getResource(resource).toExternalForm());
+                mediaPlayer = new MediaPlayer(media);
+                mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE);
+                mediaPlayer.setVolume((double) settings.getMusicVolume() / 100);
+                mediaPlayer.play();
+                log.info("Music is playing");
+            });
+            thread.setDaemon(true);
+            thread.start();
+        }
     }
 
+
     public void stopMusic(){
         if (mediaPlayer != null) {
             mediaPlayer.dispose(); // Dispose of the MediaPlayer instance
         }
     }
 
-    protected List<Path> getFilePathsFromResources(Path folderPath) throws IOException {
-        List<Path> result;
-        try (Stream<Path> walk = Files.walk(folderPath)) {
-            result = walk.filter(Files::isRegularFile)
-                    .collect(Collectors.toList());
-        }
-        return result;
+    private void setMediaPlayer(MediaPlayer mediaPlayer){
+        this.mediaPlayer = mediaPlayer;
     }
 
-    protected String getRandomFilePath(List<Path> paths){
-        Random random = new Random();
-        int min = 0;
-        int max = paths.size() - 1;
-        int randomIndex = random.nextInt(max - min + 1 ) + min;
-        String randomPath = paths.get(randomIndex).toString();
-        return randomPath;
+    public void setVolume(int volume){
+        Persistence.getInstance().getSettings().setMusicVolume(volume);
+        mediaPlayer.setVolume(volume / 100);
     }
-    protected String convertPathToResourcePath(String randomPath){
-        String normalizedPath = Paths.get(randomPath).toString().replace('\\', '/');
-        String resource = normalizedPath.substring(18); //18 = Begins at a at resourceFolder Level
-        return resource;
+
+    public int getVolume(){
+        return Persistence.getInstance().getSettings().getMusicVolume();
     }
 
 
+    public MusicPlayer getInstance(){return musicPlayerSingleton;}
+
+
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
index f3e3a5bc..379e46d7 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
@@ -1,6 +1,7 @@
 package de.hdm_stuttgart.battlearena.Model.Sound;
 
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Persistence;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
 import de.hdm_stuttgart.battlearena.Model.Entity.IEntity;
 import de.hdm_stuttgart.battlearena.Model.Inputs.InputHandler;
@@ -23,13 +24,14 @@ public class SoundEffects {
     private int sfxVolume;
 
     private RuntimeInfo runtimeInfo;
+    SoundFileManager fileManager = new SoundFileManager();
     GameSceneController gameSceneController;
 
 
 
-    public void playSoundEffect(GameSceneController gameSceneController) throws IOException, InterruptedException {
+    public void playSoundEffect(GameSceneController gameSceneController, InputHandler inputHandler) throws IOException, InterruptedException {
         MusicPlayer musicPlayer = new MusicPlayer();
-        InputHandler inputhandler = InputHandler.getInstance();
+        log.info(inputHandler);
         TileManager tileManager = gameSceneController.getTileManager();// TODO Find out why tileManager is null
         log.info(tileManager);
         IEntity player = gameSceneController.getPlayer();
@@ -39,21 +41,24 @@ public class SoundEffects {
         int playerPosY;
         int mapTile;
 
-        while(inputhandler.isMoveDown() || inputhandler.isMoveUp() || inputhandler.isMoveLeft() || inputhandler.isMoveRight()){
+
+        System.out.println(inputHandler.isMoveUp());
+        while(inputHandler.isMoveDown() || inputHandler.isMoveUp() || inputHandler.isMoveLeft() || inputHandler.isMoveRight()){
             playerPosX = player.getMapPosX();
             playerPosY = player.getMapPosY();
             mapTile = map[playerPosX][playerPosY];
             System.out.println(mapTile);
             SFXLoop sfx = tileSet[mapTile].getSoundeffect();
-            if(!(sfx == SFXLoop.NONE)) {
+            System.out.println(playerPosX);
+           if(!(sfx == SFXLoop.NONE)) {
                 Path path = Paths.get(sfx.getPath());
-                List<Path> sfxPaths = musicPlayer.getFilePathsFromResources(path);
-                String randomPath = musicPlayer.getRandomFilePath(sfxPaths);
-                String resource = musicPlayer.convertPathToResourcePath(randomPath);
+                List<Path> sfxPaths = fileManager.getFilePathsFromResources(path);
+                String randomPath = fileManager.getRandomFilePath(sfxPaths);
+                String resource = fileManager.convertPathToResourcePath(randomPath);
                 Thread sfxLoop = new Thread(() -> {
                     AudioClip effect = new AudioClip(resource);
-                    effect.setVolume(runtimeInfo.getSfxVolume());
-                    effect.setVolume((double) sfxVolume / 100); //TODO Replace with own Method
+                    effect.setVolume((double) Persistence.getInstance().getSettings().getSfxVolume() /100);
+                    effect.setVolume(0.5); //TODO Replace with own Method
                     effect.play();
                 });
                 sfxLoop.setDaemon(true);
@@ -63,8 +68,11 @@ public class SoundEffects {
             }
         }
 
-    }
 
+            System.out.println("hallo");
+
+
+    }
 
 
     public void playSoundEffectOnce(SFX soundEffect){
@@ -73,14 +81,22 @@ public class SoundEffects {
         Thread sfx = new Thread(()->{
             AudioClip audioClip = new AudioClip(getClass().getResource(resource).toExternalForm());
             audioClip.play();
+            audioClip.setVolume((double) Persistence.getInstance().getSettings().getSfxVolume() /100);
         });
         sfx.setDaemon(true);
         sfx.start();
+
+
     }
 
 
-    private void playSFXFile(String soundEffect){
+    public void setSfxVolume(int volume){
+        Persistence.getInstance().getSettings().setSfxVolume(volume);
+        //Set Volume for One Time sound effects and Loops
+    }
 
+    public int getVolume(){
+        return Persistence.getInstance().getSettings().getMusicVolume();
     }
 
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundFileManager.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundFileManager.java
new file mode 100644
index 00000000..8aa62452
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundFileManager.java
@@ -0,0 +1,39 @@
+package de.hdm_stuttgart.battlearena.Model.Sound;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class SoundFileManager {
+    private static final Logger log = LogManager.getLogger(SoundFileManager.class);
+    protected List<Path> getFilePathsFromResources(Path folderPath) throws IOException {
+        List<Path> result;
+        try (Stream<Path> walk = Files.walk(folderPath)) {
+            result = walk.filter(Files::isRegularFile)
+                    .collect(Collectors.toList());
+        }
+        return result;
+    }
+
+    protected String getRandomFilePath(List<Path> paths){
+        Random random = new Random();
+        int min = 0;
+        int max = paths.size() - 1;
+        int randomIndex = random.nextInt(max - min + 1 ) + min;
+        String randomPath = paths.get(randomIndex).toString();
+        return randomPath;
+    }
+    protected String convertPathToResourcePath(String randomPath){
+        String normalizedPath = Paths.get(randomPath).toString().replace('\\', '/');
+        String resource = normalizedPath.substring(18); //18 = Begins at a at resourceFolder Level
+        return resource;
+    }
+}
-- 
GitLab