notworking: Idk

This commit is contained in:
2025-03-28 08:17:13 +01:00
parent 433dbf6f96
commit a8e80c405d
34 changed files with 120 additions and 45 deletions

View File

@ -15,6 +15,7 @@ import cz.jzitnik.game.annotations.AutoTransient;
import cz.jzitnik.game.annotations.WalkSound;
import cz.jzitnik.game.annotations.BreaksByPlace;
import cz.jzitnik.game.annotations.MineSound;
import cz.jzitnik.game.annotations.MiningSound;
import cz.jzitnik.game.annotations.PlaceSound;
import cz.jzitnik.game.blocks.Chest;
import cz.jzitnik.game.blocks.Furnace;
@ -199,9 +200,19 @@ public class Game extends AutoTransientSupport {
double hardness = world[y][x].stream().filter(block -> !block.getBlockId().equals("air")).toList().getFirst()
.calculateHardness(inventory);
var blocks = world[y][x];
this.mining = true;
new Thread(() -> {
for (Block block : blocks) {
if (block.getClass().isAnnotationPresent(MiningSound.class)) {
new Thread(() -> {
gameStates.dependencies.sound.playSound(configuration,
block.getClass().getAnnotation(MiningSound.class).value());
}).start();
}
}
try {
Thread.sleep((long) (hardness * 166));
} catch (InterruptedException e) {
@ -209,7 +220,14 @@ public class Game extends AutoTransientSupport {
}
breakingBlock.setSpriteState(Breaking.BreakingState.SECOND);
screenRenderer.render(this);
for (Block block : blocks) {
if (block.getClass().isAnnotationPresent(MiningSound.class)) {
new Thread(() -> {
gameStates.dependencies.sound.playSound(configuration,
block.getClass().getAnnotation(MiningSound.class).value());
}).start();
}
}
try {
Thread.sleep((long) (hardness * 166));
} catch (InterruptedException e) {
@ -217,7 +235,14 @@ public class Game extends AutoTransientSupport {
}
breakingBlock.setSpriteState(Breaking.BreakingState.THIRD);
screenRenderer.render(this);
for (Block block : blocks) {
if (block.getClass().isAnnotationPresent(MiningSound.class)) {
new Thread(() -> {
gameStates.dependencies.sound.playSound(configuration,
block.getClass().getAnnotation(MiningSound.class).value());
}).start();
}
}
try {
Thread.sleep((long) (hardness * 166));
} catch (InterruptedException e) {
@ -282,7 +307,6 @@ public class Game extends AutoTransientSupport {
gameStates.dependencies.eventHandlerProvider.handleMine(screenRenderer, this, x, y);
for (Block block : blocksCopy) {
if (block.getClass().isAnnotationPresent(MineSound.class)) {
var key = block.getClass().getAnnotation(MineSound.class).value();
@ -478,10 +502,10 @@ public class Game extends AutoTransientSupport {
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
player.getPlayerBlock1().setSpriteState(SteveState.FIRST);
player.getPlayerBlock2().setSpriteState(SteveState.SECOND);
@ -490,7 +514,7 @@ public class Game extends AutoTransientSupport {
}
private void playMovePlayerSound(int x, int y) {
var blocks = world[y+1][x];
var blocks = world[y + 1][x];
for (Block block : blocks) {
if (block.getClass().isAnnotationPresent(WalkSound.class)) {

View File

@ -6,10 +6,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundKey;
import cz.jzitnik.game.core.sound.SoundType;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@RequireAnnotation(BlockRegistry.class)
@SoundTypeSet(SoundType.BLOCK)
public @interface MineSound {
SoundKey value();
}

View File

@ -0,0 +1,17 @@
package cz.jzitnik.game.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundKey;
import cz.jzitnik.game.core.sound.SoundType;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@RequireAnnotation(BlockRegistry.class)
@SoundTypeSet(SoundType.MINING)
public @interface MiningSound {
SoundKey value();
}

View File

@ -6,10 +6,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundKey;
import cz.jzitnik.game.core.sound.SoundType;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@RequireAnnotation(BlockRegistry.class)
@SoundTypeSet(SoundType.BLOCK)
public @interface PlaceSound {
SoundKey value();
}

View File

@ -5,7 +5,6 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundKey;
import cz.jzitnik.game.core.sound.SoundType;
import java.lang.annotation.ElementType;
@ -13,6 +12,5 @@ import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME)
public @interface SoundRegistry {
SoundKey key();
SoundType type();
String[] resourceLocation();
}

View File

@ -0,0 +1,15 @@
package cz.jzitnik.game.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundType;
import java.lang.annotation.ElementType;
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SoundTypeSet {
SoundType value();
}

View File

@ -6,10 +6,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cz.jzitnik.game.core.sound.SoundKey;
import cz.jzitnik.game.core.sound.SoundType;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@RequireAnnotation(BlockRegistry.class)
@SoundTypeSet(SoundType.WALKING)
public @interface WalkSound {
SoundKey value();
}

View File

@ -11,6 +11,7 @@ import javax.sound.sampled.UnsupportedAudioFileException;
import org.reflections.Reflections;
import cz.jzitnik.game.annotations.SoundRegistry;
import cz.jzitnik.game.annotations.SoundTypeSet;
import cz.jzitnik.game.config.Configuration;
import cz.jzitnik.tui.SoundPlayer;
import lombok.extern.slf4j.Slf4j;
@ -38,20 +39,23 @@ public class Sound {
public void playSound(Configuration configuration, SoundKey soundKey) {
var volume = configuration.getSoundVolume();
var annotation = map.get(soundKey);
var resources = annotation.resourceLocation();
var resource = resources[random.nextInt(resources.length)];
var typeVolue = annotation.type().getVolume();
int totalVolume = (int) ((volume + typeVolue) * 100) / 200;
var typeVolume = annotation.getClass().isAnnotationPresent(SoundTypeSet.class)
? annotation.getClass().getAnnotation(SoundTypeSet.class).value().getVolume()
: 0;
log.debug("Type volume: {}", typeVolume);
log.debug("Config volume: {}", volume);
new Thread(() -> {
try {
SoundPlayer.playSound(resource);
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException | InterruptedException e) {
SoundPlayer.playSound(resource, typeVolume, volume);
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

View File

@ -4,7 +4,9 @@ import lombok.Getter;
@Getter
public enum SoundType {
BLOCK(100);
BLOCK(0),
WALKING(100),
MINING(100);
// TODO: Volume is not currently used but will be probably used in future to better normalize the sound volume
private final int volume;

View File

@ -2,13 +2,12 @@ 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.GRASS, resourceLocation = {
"grass/grass1.ogg",
"grass/grass2.ogg",
"grass/grass3.ogg",
"grass/grass4.ogg"
}, type = SoundType.BLOCK)
})
public class GrassSound {
}

View File

@ -2,7 +2,6 @@ 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.GRASS_WALKING, resourceLocation = {
"grass/walk1.ogg",
@ -11,6 +10,6 @@ import cz.jzitnik.game.core.sound.SoundType;
"grass/walk4.ogg",
"grass/walk5.ogg",
"grass/walk6.ogg",
}, type = SoundType.BLOCK)
})
public class GrassWalkingSound {
}

View File

@ -2,13 +2,12 @@ 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.GRAVEL, resourceLocation = {
"gravel/gravel1.wav",
"gravel/gravel2.wav",
"gravel/gravel3.wav",
"gravel/gravel4.wav"
}, type = SoundType.BLOCK)
"gravel/gravel1.ogg",
"gravel/gravel2.ogg",
"gravel/gravel3.ogg",
"gravel/gravel4.ogg"
})
public class GravelSound {
}

View File

@ -2,13 +2,12 @@ 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.GRAVEL_WALKING, resourceLocation = {
"gravel/step1.wav",
"gravel/step2.wav",
"gravel/step3.wav",
"gravel/step4.wav",
}, type = SoundType.BLOCK)
"gravel/step1.ogg",
"gravel/step2.ogg",
"gravel/step3.ogg",
"gravel/step4.ogg",
})
public class GravelWalkingSound {
}

View File

@ -2,10 +2,9 @@ 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 {
}

View File

@ -3,6 +3,7 @@ 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.MineSound;
import cz.jzitnik.game.annotations.MiningSound;
import cz.jzitnik.game.annotations.PlaceSound;
import cz.jzitnik.game.annotations.ResetDataOnMine;
import cz.jzitnik.game.annotations.WalkSound;
@ -16,6 +17,7 @@ import java.util.ArrayList;
@PlaceSound(SoundKey.GRAVEL)
@MineSound(SoundKey.GRAVEL)
@WalkSound(SoundKey.GRAVEL_WALKING)
@MiningSound(SoundKey.GRAVEL_WALKING)
@ResetDataOnMine
@BlockRegistry("dirt")
public class DirtBlock extends Block {

View File

@ -3,6 +3,7 @@ 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.MineSound;
import cz.jzitnik.game.annotations.MiningSound;
import cz.jzitnik.game.annotations.PlaceSound;
import cz.jzitnik.game.annotations.ResetDataOnMine;
import cz.jzitnik.game.annotations.WalkSound;
@ -16,6 +17,7 @@ import java.util.ArrayList;
@MineSound(SoundKey.GRASS)
@PlaceSound(SoundKey.GRASS)
@WalkSound(SoundKey.GRASS_WALKING)
@MiningSound(SoundKey.GRASS_WALKING)
@ResetDataOnMine
@BlockRegistry(value = "grass", drops = "dirt")
public class GrassBlock extends Block {

View File

@ -4,6 +4,7 @@ import cz.jzitnik.game.SpriteLoader;
import cz.jzitnik.game.annotations.BlockRegistry;
import cz.jzitnik.game.annotations.FallingBlock;
import cz.jzitnik.game.annotations.MineSound;
import cz.jzitnik.game.annotations.MiningSound;
import cz.jzitnik.game.annotations.PlaceSound;
import cz.jzitnik.game.annotations.WalkSound;
import cz.jzitnik.game.core.sound.SoundKey;
@ -15,6 +16,7 @@ import java.util.ArrayList;
@PlaceSound(SoundKey.GRAVEL)
@MineSound(SoundKey.GRAVEL)
@WalkSound(SoundKey.GRAVEL_WALKING)
@MiningSound(SoundKey.GRAVEL_WALKING)
@FallingBlock
@BlockRegistry("gravel")
public class GravelBlock extends Block {

View File

@ -7,19 +7,17 @@ import java.io.IOException;
@Slf4j
public class SoundPlayer {
public static void playSound(String filePath)
throws LineUnavailableException, IOException, UnsupportedAudioFileException, InterruptedException {
if (!filePath.endsWith(".ogg")) {
return;
public static void playSound(String filePath, int backendVolume, int masterVolume)
throws LineUnavailableException, IOException, UnsupportedAudioFileException {
if (!filePath.endsWith(".ogg") || masterVolume == 0) {
return; // No sound if master volume is 0
}
log.info("Loading resource: {}", "sounds/" + filePath);
var file = SoundPlayer.class.getClassLoader().getResourceAsStream("sounds/" + filePath);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(file);
AudioFormat baseFormat = audioStream.getFormat();
// Convert the audio format to PCM_SIGNED
AudioFormat targetFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
@ -30,10 +28,9 @@ public class SoundPlayer {
false
);
// Apply the format change to the stream
AudioInputStream dataIn = AudioSystem.getAudioInputStream(targetFormat, audioStream);
byte[] buffer = new byte[8192]; // Larger buffer to reduce read/write operations
byte[] buffer = new byte[8192];
DataLine.Info info = new DataLine.Info(SourceDataLine.class, targetFormat);
try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {
@ -41,18 +38,29 @@ public class SoundPlayer {
line.open(targetFormat);
line.start();
float finalVolume = (backendVolume / 100.0f) * (masterVolume / 100.0f);
log.info("Applying volume: {} (backend: {}, master: {})", finalVolume, backendVolume, masterVolume);
int bytesRead;
while ((bytesRead = dataIn.read(buffer, 0, buffer.length)) != -1) {
applyVolume(buffer, bytesRead, finalVolume);
line.write(buffer, 0, bytesRead);
}
// Ensure the line is fully flushed before stopping
line.drain();
}
}
// Close streams after use
dataIn.close();
audioStream.close();
}
private static void applyVolume(byte[] buffer, int bytesRead, float volume) {
for (int i = 0; i < bytesRead; i += 2) { // 16-bit PCM samples are 2 bytes each
int sample = (buffer[i] & 0xFF) | (buffer[i + 1] << 8);
sample = (int) (sample * volume);
buffer[i] = (byte) (sample & 0xFF);
buffer[i + 1] = (byte) ((sample >> 8) & 0xFF);
}
}
}