diff --git a/src/main/java/eu/midnightdust/yaytris/Tetris.java b/src/main/java/eu/midnightdust/yaytris/Tetris.java
index 93c4d99..9f2b9e5 100644
--- a/src/main/java/eu/midnightdust/yaytris/Tetris.java
+++ b/src/main/java/eu/midnightdust/yaytris/Tetris.java
@@ -3,7 +3,8 @@ package eu.midnightdust.yaytris;
import eu.midnightdust.yaytris.game.Space;
import eu.midnightdust.yaytris.ui.ScoreMenu;
import eu.midnightdust.yaytris.ui.TetrisUI;
-import eu.midnightdust.yaytris.util.SoundUtil;
+import eu.midnightdust.yaytris.util.GravityTimerTask;
+import eu.midnightdust.yaytris.util.sound.SoundUtil;
import javax.swing.*;
import java.time.LocalTime;
@@ -48,6 +49,15 @@ public class Tetris {
return space;
}
+ /**
+ * Get the ui instance
+ *
+ * @see TetrisUI
+ */
+ public static TetrisUI getUi() {
+ return ui;
+ }
+
/**
* Resets the game space, preparing it for a new game.
*
@@ -127,17 +137,4 @@ public class Tetris {
}
}
- /**
- * Defines our custom timer task that handles falling pieces.
- */
- public static class GravityTimerTask extends TimerTask {
- @Override
- public void run() {
- if (space.getCurrentTetromino() != null) {
- updateTime();
- space.getCurrentTetromino().fall();
- ui.getGamePanel().repaint();
- }
- }
- }
}
diff --git a/src/main/java/eu/midnightdust/yaytris/util/GravityTimerTask.java b/src/main/java/eu/midnightdust/yaytris/util/GravityTimerTask.java
new file mode 100644
index 0000000..2aed805
--- /dev/null
+++ b/src/main/java/eu/midnightdust/yaytris/util/GravityTimerTask.java
@@ -0,0 +1,19 @@
+package eu.midnightdust.yaytris.util;
+
+import eu.midnightdust.yaytris.Tetris;
+
+import java.util.TimerTask;
+
+/**
+ * Defines our custom timer task that handles falling pieces.
+ */
+public class GravityTimerTask extends TimerTask {
+ @Override
+ public void run() {
+ if (Tetris.getSpace().getCurrentTetromino() != null) {
+ Tetris.updateTime();
+ Tetris.getSpace().getCurrentTetromino().fall();
+ Tetris.getUi().getGamePanel().repaint();
+ }
+ }
+}
diff --git a/src/main/java/eu/midnightdust/yaytris/util/SoundEffect.java b/src/main/java/eu/midnightdust/yaytris/util/SoundEffect.java
index 63a987e..425cc40 100644
--- a/src/main/java/eu/midnightdust/yaytris/util/SoundEffect.java
+++ b/src/main/java/eu/midnightdust/yaytris/util/SoundEffect.java
@@ -1,5 +1,7 @@
package eu.midnightdust.yaytris.util;
+import eu.midnightdust.yaytris.util.sound.SoundUtil;
+
public enum SoundEffect {
BOOP("/sounds/boop.wav"), LINE_COMPLETED("/sounds/line-completed.wav");
diff --git a/src/main/java/eu/midnightdust/yaytris/util/sound/LineUpdateListener.java b/src/main/java/eu/midnightdust/yaytris/util/sound/LineUpdateListener.java
new file mode 100644
index 0000000..eea3738
--- /dev/null
+++ b/src/main/java/eu/midnightdust/yaytris/util/sound/LineUpdateListener.java
@@ -0,0 +1,13 @@
+package eu.midnightdust.yaytris.util.sound;
+
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+
+public class LineUpdateListener implements LineListener {
+ @Override
+ public void update(LineEvent event) {
+ if (LineEvent.Type.STOP == event.getType()) {
+ event.getLine().close();
+ }
+ }
+}
diff --git a/src/main/java/eu/midnightdust/yaytris/util/sound/MusicThread.java b/src/main/java/eu/midnightdust/yaytris/util/sound/MusicThread.java
new file mode 100644
index 0000000..31b8ae4
--- /dev/null
+++ b/src/main/java/eu/midnightdust/yaytris/util/sound/MusicThread.java
@@ -0,0 +1,70 @@
+package eu.midnightdust.yaytris.util.sound;
+
+import eu.midnightdust.yaytris.Settings;
+
+import javax.sound.sampled.*;
+import java.io.IOException;
+
+/**
+ * Handle music in separate threads to not interrupt the main game
+ */
+public class MusicThread extends Thread {
+ private static final int BUFFER_SIZE = 8192;
+ private final boolean looped;
+ private final String fileLocation;
+ private boolean playing;
+
+ public MusicThread(String fileLocation, boolean looped) {
+ this.fileLocation = fileLocation;
+ this.looped = looped;
+ this.playing = true;
+ }
+
+ public void stopMusic() {
+ this.playing = false;
+ }
+
+ @Override
+ public void run() {
+ do {
+ playMusic(fileLocation);
+ } while (looped && playing);
+ }
+
+ /**
+ * INTERNAL!
+ * Play the long audio file found at the specified location.
+ * Fades out after calling {@link #stopMusic()}.
+ * Adapted from: Baeldung
+ *
+ * @see SoundUtil#playMusic(String, boolean)
+ */
+ private void playMusic(String fileLocation) {
+ try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.getResource(fileLocation))) {
+ AudioFormat format = stream.getFormat();
+ DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
+
+ SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
+ sourceDataLine.open(format);
+ sourceDataLine.start();
+ SoundUtil.setVolume(sourceDataLine, Settings.musicVolume);
+ float fadeOut = 1.0f;
+
+ byte[] bufferBytes = new byte[BUFFER_SIZE];
+ int readBytes;
+ while ((readBytes = stream.read(bufferBytes)) != -1) {
+ if (!playing) {
+ fadeOut = (float) Math.sin(fadeOut - 0.01f); // Sinus fade-out
+ SoundUtil.setVolume(sourceDataLine, (int) (fadeOut * Settings.musicVolume));
+ if (fadeOut <= 0) break;
+ }
+ sourceDataLine.write(bufferBytes, 0, readBytes);
+ }
+
+ sourceDataLine.drain();
+ sourceDataLine.close();
+ } catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java b/src/main/java/eu/midnightdust/yaytris/util/sound/SoundUtil.java
similarity index 51%
rename from src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java
rename to src/main/java/eu/midnightdust/yaytris/util/sound/SoundUtil.java
index 3f9013f..ad8f066 100644
--- a/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java
+++ b/src/main/java/eu/midnightdust/yaytris/util/sound/SoundUtil.java
@@ -1,4 +1,4 @@
-package eu.midnightdust.yaytris.util;
+package eu.midnightdust.yaytris.util.sound;
import eu.midnightdust.yaytris.Settings;
@@ -55,7 +55,7 @@ public class SoundUtil {
}
}
- private static URL getResource(String fileLocation) {
+ protected static URL getResource(String fileLocation) {
return SoundUtil.class.getResource(fileLocation);
}
@@ -66,80 +66,10 @@ public class SoundUtil {
* @param line the DataLine responsible for audio playback
* @param volume the requested volume in percent (0-100%)
*/
- private static void setVolume(Line line, int volume) {
+ protected static void setVolume(Line line, int volume) {
if (volume < 0 || volume > 100)
throw new IllegalArgumentException("Volume not valid: " + volume);
FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(20f * (float) Math.log10(volume/100f));
}
-
- /**
- * Handle music in separate threads to not interrupt the main game
- */
- public static class MusicThread extends Thread {
- private static final int BUFFER_SIZE = 8192;
- private final boolean looped;
- private final String fileLocation;
- private boolean playing;
-
- MusicThread(String fileLocation, boolean looped) {
- this.fileLocation = fileLocation;
- this.looped = looped;
- this.playing = true;
- }
-
- public void stopMusic() {
- this.playing = false;
- }
-
- @Override
- public void run() {
- do {playMusic(fileLocation);} while (looped && playing);
- }
-
- /**
- * INTERNAL!
- * Play the long audio file found at the specified location.
- * Fades out after calling {@link #stopMusic()}.
- * Adapted from: Baeldung
- * @see SoundUtil#playMusic(String, boolean)
- */
- private void playMusic(String fileLocation) {
- try (AudioInputStream stream = AudioSystem.getAudioInputStream(getResource(fileLocation))) {
- AudioFormat format = stream.getFormat();
- DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
-
- SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
- sourceDataLine.open(format);
- sourceDataLine.start();
- setVolume(sourceDataLine, Settings.musicVolume);
- float fadeOut = 1.0f;
-
- byte[] bufferBytes = new byte[BUFFER_SIZE];
- int readBytes;
- while ((readBytes = stream.read(bufferBytes)) != -1) {
- if (!playing) {
- fadeOut = (float) Math.sin(fadeOut-0.01f); // Sinus fade-out
- setVolume(sourceDataLine, (int) (fadeOut * Settings.musicVolume));
- if (fadeOut <= 0) break;
- }
- sourceDataLine.write(bufferBytes, 0, readBytes);
- }
-
- sourceDataLine.drain();
- sourceDataLine.close();
- } catch (LineUnavailableException | IOException | UnsupportedAudioFileException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public static class LineUpdateListener implements LineListener {
- @Override
- public void update(LineEvent event) {
- if (LineEvent.Type.STOP == event.getType()) {
- event.getLine().close();
- }
- }
- }
}