diff --git a/pom.xml b/pom.xml index f143849..83841bc 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,11 @@ logback-classic 1.5.18 + + com.github.trilarion + java-vorbis-support + 1.2.1 + diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index 6cd4a69..e951bdd 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -282,7 +282,6 @@ public class Game extends AutoTransientSupport { gameStates.dependencies.eventHandlerProvider.handleMine(screenRenderer, this, x, y); - screenRenderer.render(this); for (Block block : blocksCopy) { if (block.getClass().isAnnotationPresent(MineSound.class)) { @@ -294,6 +293,8 @@ public class Game extends AutoTransientSupport { } } + screenRenderer.render(this); + update(screenRenderer); } diff --git a/src/main/java/cz/jzitnik/game/config/Configuration.java b/src/main/java/cz/jzitnik/game/config/Configuration.java index dfca34c..c8f8153 100644 --- a/src/main/java/cz/jzitnik/game/config/Configuration.java +++ b/src/main/java/cz/jzitnik/game/config/Configuration.java @@ -1,10 +1,12 @@ package cz.jzitnik.game.config; +import java.io.Serializable; + import lombok.Getter; import lombok.Setter; @Getter @Setter -public class Configuration { +public class Configuration implements Serializable { private int soundVolume = 100; // 0-100 } diff --git a/src/main/java/cz/jzitnik/game/core/sound/Sound.java b/src/main/java/cz/jzitnik/game/core/sound/Sound.java index 8166f9b..523ff0b 100644 --- a/src/main/java/cz/jzitnik/game/core/sound/Sound.java +++ b/src/main/java/cz/jzitnik/game/core/sound/Sound.java @@ -38,17 +38,23 @@ public class Sound { public void playSound(Configuration configuration, SoundKey soundKey) { var volume = configuration.getSoundVolume(); - + var annotation = map.get(soundKey); - try { - var resources = annotation.resourceLocation(); + var resources = annotation.resourceLocation(); + var resource = resources[random.nextInt(resources.length)]; - var resource = resources[random.nextInt(resources.length)]; - SoundPlayer.playSound(resource, volume); - } catch (LineUnavailableException | IOException | UnsupportedAudioFileException | InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + var typeVolue = annotation.type().getVolume(); + + int totalVolume = (int) ((volume + typeVolue) * 100) / 200; + + new Thread(() -> { + try { + SoundPlayer.playSound(resource); + } catch (LineUnavailableException | IOException | UnsupportedAudioFileException | InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }).start(); } } diff --git a/src/main/java/cz/jzitnik/game/core/sound/SoundKey.java b/src/main/java/cz/jzitnik/game/core/sound/SoundKey.java index 6e155b6..b376eb0 100644 --- a/src/main/java/cz/jzitnik/game/core/sound/SoundKey.java +++ b/src/main/java/cz/jzitnik/game/core/sound/SoundKey.java @@ -5,5 +5,7 @@ public enum SoundKey { GRASS_WALKING, GRAVEL, - GRAVEL_WALKING + GRAVEL_WALKING, + + WOOD, } diff --git a/src/main/java/cz/jzitnik/game/core/sound/SoundType.java b/src/main/java/cz/jzitnik/game/core/sound/SoundType.java index 66d4077..c46a1bf 100644 --- a/src/main/java/cz/jzitnik/game/core/sound/SoundType.java +++ b/src/main/java/cz/jzitnik/game/core/sound/SoundType.java @@ -1,5 +1,15 @@ package cz.jzitnik.game.core.sound; +import lombok.Getter; + +@Getter public enum SoundType { - BLOCK + BLOCK(100); + + // TODO: Volume is not currently used but will be probably used in future to better normalize the sound volume + private final int volume; + + SoundType(int volume) { + this.volume = volume; + } } diff --git a/src/main/java/cz/jzitnik/game/core/sound/registry/GrassSound.java b/src/main/java/cz/jzitnik/game/core/sound/registry/GrassSound.java index 4ea6e39..65f6165 100644 --- a/src/main/java/cz/jzitnik/game/core/sound/registry/GrassSound.java +++ b/src/main/java/cz/jzitnik/game/core/sound/registry/GrassSound.java @@ -5,10 +5,10 @@ import cz.jzitnik.game.core.sound.SoundKey; import cz.jzitnik.game.core.sound.SoundType; @SoundRegistry(key = SoundKey.GRASS, resourceLocation = { - "grass/grass1.wav", - "grass/grass2.wav", - "grass/grass3.wav", - "grass/grass4.wav" + "grass/grass1.ogg", + "grass/grass2.ogg", + "grass/grass3.ogg", + "grass/grass4.ogg" }, type = SoundType.BLOCK) public class GrassSound { } diff --git a/src/main/java/cz/jzitnik/game/core/sound/registry/GrassWalkingSound.java b/src/main/java/cz/jzitnik/game/core/sound/registry/GrassWalkingSound.java index 5f9b1ce..a98d9c4 100644 --- a/src/main/java/cz/jzitnik/game/core/sound/registry/GrassWalkingSound.java +++ b/src/main/java/cz/jzitnik/game/core/sound/registry/GrassWalkingSound.java @@ -5,12 +5,12 @@ import cz.jzitnik.game.core.sound.SoundKey; import cz.jzitnik.game.core.sound.SoundType; @SoundRegistry(key = SoundKey.GRASS_WALKING, resourceLocation = { - "grass/walk1.wav", - "grass/walk2.wav", - "grass/walk3.wav", - "grass/walk4.wav", - "grass/walk5.wav", - "grass/walk6.wav", + "grass/walk1.ogg", + "grass/walk2.ogg", + "grass/walk3.ogg", + "grass/walk4.ogg", + "grass/walk5.ogg", + "grass/walk6.ogg", }, type = SoundType.BLOCK) public class GrassWalkingSound { } diff --git a/src/main/java/cz/jzitnik/game/core/sound/registry/WoodSound.java b/src/main/java/cz/jzitnik/game/core/sound/registry/WoodSound.java new file mode 100644 index 0000000..ca113db --- /dev/null +++ b/src/main/java/cz/jzitnik/game/core/sound/registry/WoodSound.java @@ -0,0 +1,11 @@ +package cz.jzitnik.game.core.sound.registry; + +import cz.jzitnik.game.annotations.SoundRegistry; +import cz.jzitnik.game.core.sound.SoundKey; +import cz.jzitnik.game.core.sound.SoundType; + +@SoundRegistry(key = SoundKey.WOOD, resourceLocation = { + "wood/wood1.ogg", +}, type = SoundType.BLOCK) +public class WoodSound { +} diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/blocks/OakLogBlock.java b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/blocks/OakLogBlock.java index 9b3de3c..15d17b1 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/blocks/OakLogBlock.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/blocks/OakLogBlock.java @@ -3,11 +3,16 @@ package cz.jzitnik.game.entities.items.registry.blocks.blocks; import cz.jzitnik.game.SpriteLoader; import cz.jzitnik.game.annotations.BlockRegistry; import cz.jzitnik.game.annotations.Flamable; +import cz.jzitnik.game.annotations.MineSound; +import cz.jzitnik.game.annotations.PlaceSound; +import cz.jzitnik.game.core.sound.SoundKey; import cz.jzitnik.game.entities.Block; import cz.jzitnik.game.entities.items.ItemType; import java.util.ArrayList; +@MineSound(SoundKey.WOOD) +@PlaceSound(SoundKey.WOOD) @Flamable @BlockRegistry("oak_log") public class OakLogBlock extends Block { diff --git a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java index be1d5b1..7574419 100644 --- a/src/main/java/cz/jzitnik/tui/ScreenRenderer.java +++ b/src/main/java/cz/jzitnik/tui/ScreenRenderer.java @@ -5,7 +5,6 @@ import cz.jzitnik.game.entities.SteveData; import cz.jzitnik.game.Game; import cz.jzitnik.game.sprites.Air; import cz.jzitnik.game.sprites.SimpleSprite; -import cz.jzitnik.game.sprites.Steve; import cz.jzitnik.game.blocks.Chest; import cz.jzitnik.game.blocks.Furnace; import cz.jzitnik.game.ui.Escape; diff --git a/src/main/java/cz/jzitnik/tui/SoundPlayer.java b/src/main/java/cz/jzitnik/tui/SoundPlayer.java index adb77c7..d51ca04 100644 --- a/src/main/java/cz/jzitnik/tui/SoundPlayer.java +++ b/src/main/java/cz/jzitnik/tui/SoundPlayer.java @@ -1,32 +1,58 @@ package cz.jzitnik.tui; -import javax.sound.sampled.*; - import lombok.extern.slf4j.Slf4j; +import javax.sound.sampled.*; import java.io.IOException; @Slf4j public class SoundPlayer { - public static Clip playSound(String filePath, int volume) + public static void playSound(String filePath) throws LineUnavailableException, IOException, UnsupportedAudioFileException, InterruptedException { + if (!filePath.endsWith(".ogg")) { + return; + } + log.info("Loading resource: {}", "sounds/" + filePath); - var soundFile = SoundPlayer.class.getClassLoader().getResourceAsStream("sounds/" + filePath); - AudioInputStream audioStream = AudioSystem.getAudioInputStream(soundFile); - Clip clip = AudioSystem.getClip(); - clip.open(audioStream); - FloatControl volumeControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); - float min = volumeControl.getMinimum(); - float max = volumeControl.getMaximum(); - float gain = min + (max - min) * (volume / 100.0f); - volumeControl.setValue(gain); + var file = SoundPlayer.class.getClassLoader().getResourceAsStream("sounds/" + filePath); + AudioInputStream audioStream = AudioSystem.getAudioInputStream(file); + AudioFormat baseFormat = audioStream.getFormat(); - log.info("Starting to play {}", filePath); - clip.start(); + // Convert the audio format to PCM_SIGNED + AudioFormat targetFormat = new AudioFormat( + AudioFormat.Encoding.PCM_SIGNED, + baseFormat.getSampleRate(), + 16, + baseFormat.getChannels(), + baseFormat.getChannels() * 2, + baseFormat.getSampleRate(), + false + ); - // Thread.sleep(clip.getMicrosecondLength() / 1000); + // Apply the format change to the stream + AudioInputStream dataIn = AudioSystem.getAudioInputStream(targetFormat, audioStream); - return clip; + byte[] buffer = new byte[8192]; // Larger buffer to reduce read/write operations + DataLine.Info info = new DataLine.Info(SourceDataLine.class, targetFormat); + + try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) { + if (line != null) { + line.open(targetFormat); + line.start(); + + int bytesRead; + while ((bytesRead = dataIn.read(buffer, 0, buffer.length)) != -1) { + line.write(buffer, 0, bytesRead); + } + + // Ensure the line is fully flushed before stopping + line.drain(); + } + } + + // Close streams after use + dataIn.close(); + audioStream.close(); } } diff --git a/src/main/resources/sounds/grass/grass1.ogg b/src/main/resources/sounds/grass/grass1.ogg new file mode 100644 index 0000000..d0edd4e Binary files /dev/null and b/src/main/resources/sounds/grass/grass1.ogg differ diff --git a/src/main/resources/sounds/grass/grass1.wav b/src/main/resources/sounds/grass/grass1.wav deleted file mode 100644 index 79a61df..0000000 Binary files a/src/main/resources/sounds/grass/grass1.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/grass2.ogg b/src/main/resources/sounds/grass/grass2.ogg new file mode 100644 index 0000000..55df526 Binary files /dev/null and b/src/main/resources/sounds/grass/grass2.ogg differ diff --git a/src/main/resources/sounds/grass/grass2.wav b/src/main/resources/sounds/grass/grass2.wav deleted file mode 100644 index 3b60874..0000000 Binary files a/src/main/resources/sounds/grass/grass2.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/grass3.ogg b/src/main/resources/sounds/grass/grass3.ogg new file mode 100644 index 0000000..153edca Binary files /dev/null and b/src/main/resources/sounds/grass/grass3.ogg differ diff --git a/src/main/resources/sounds/grass/grass3.wav b/src/main/resources/sounds/grass/grass3.wav deleted file mode 100644 index 9893223..0000000 Binary files a/src/main/resources/sounds/grass/grass3.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/grass4.ogg b/src/main/resources/sounds/grass/grass4.ogg new file mode 100644 index 0000000..e6462a3 Binary files /dev/null and b/src/main/resources/sounds/grass/grass4.ogg differ diff --git a/src/main/resources/sounds/grass/grass4.wav b/src/main/resources/sounds/grass/grass4.wav deleted file mode 100644 index 5fb8414..0000000 Binary files a/src/main/resources/sounds/grass/grass4.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk1.ogg b/src/main/resources/sounds/grass/walk1.ogg new file mode 100644 index 0000000..52c6fdd Binary files /dev/null and b/src/main/resources/sounds/grass/walk1.ogg differ diff --git a/src/main/resources/sounds/grass/walk1.wav b/src/main/resources/sounds/grass/walk1.wav deleted file mode 100644 index f155ea9..0000000 Binary files a/src/main/resources/sounds/grass/walk1.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk2.ogg b/src/main/resources/sounds/grass/walk2.ogg new file mode 100644 index 0000000..96eab92 Binary files /dev/null and b/src/main/resources/sounds/grass/walk2.ogg differ diff --git a/src/main/resources/sounds/grass/walk2.wav b/src/main/resources/sounds/grass/walk2.wav deleted file mode 100644 index be550df..0000000 Binary files a/src/main/resources/sounds/grass/walk2.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk3.ogg b/src/main/resources/sounds/grass/walk3.ogg new file mode 100644 index 0000000..089284c Binary files /dev/null and b/src/main/resources/sounds/grass/walk3.ogg differ diff --git a/src/main/resources/sounds/grass/walk3.wav b/src/main/resources/sounds/grass/walk3.wav deleted file mode 100644 index c5a0d4c..0000000 Binary files a/src/main/resources/sounds/grass/walk3.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk4.ogg b/src/main/resources/sounds/grass/walk4.ogg new file mode 100644 index 0000000..8435a71 Binary files /dev/null and b/src/main/resources/sounds/grass/walk4.ogg differ diff --git a/src/main/resources/sounds/grass/walk4.wav b/src/main/resources/sounds/grass/walk4.wav deleted file mode 100644 index ab03a43..0000000 Binary files a/src/main/resources/sounds/grass/walk4.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk5.ogg b/src/main/resources/sounds/grass/walk5.ogg new file mode 100644 index 0000000..fb2bba1 Binary files /dev/null and b/src/main/resources/sounds/grass/walk5.ogg differ diff --git a/src/main/resources/sounds/grass/walk5.wav b/src/main/resources/sounds/grass/walk5.wav deleted file mode 100644 index b22db89..0000000 Binary files a/src/main/resources/sounds/grass/walk5.wav and /dev/null differ diff --git a/src/main/resources/sounds/grass/walk6.ogg b/src/main/resources/sounds/grass/walk6.ogg new file mode 100644 index 0000000..b8e3cda Binary files /dev/null and b/src/main/resources/sounds/grass/walk6.ogg differ diff --git a/src/main/resources/sounds/grass/walk6.wav b/src/main/resources/sounds/grass/walk6.wav deleted file mode 100644 index 424011a..0000000 Binary files a/src/main/resources/sounds/grass/walk6.wav and /dev/null differ diff --git a/src/main/resources/sounds/wood/wood1.ogg b/src/main/resources/sounds/wood/wood1.ogg new file mode 100644 index 0000000..a5cdda3 Binary files /dev/null and b/src/main/resources/sounds/wood/wood1.ogg differ