notworking: Idk

This commit is contained in:
Jakub Žitník 2025-03-28 08:17:13 +01:00
parent 433dbf6f96
commit a8e80c405d
Signed by: jzitnik
GPG Key ID: C577A802A6AF4EF3
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;
@ -44,14 +45,17 @@ public class Sound {
var resources = annotation.resourceLocation();
var resource = resources[random.nextInt(resources.length)];
var typeVolue = annotation.type().getVolume();
var typeVolume = annotation.getClass().isAnnotationPresent(SoundTypeSet.class)
? annotation.getClass().getAnnotation(SoundTypeSet.class).value().getVolume()
: 0;
int totalVolume = (int) ((volume + typeVolue) * 100) / 200;
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);
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.