clean code: extract inner classes
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: <a href="https://www.baeldung.com/java-play-sound">Baeldung</a>
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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: <a href="https://www.baeldung.com/java-play-sound">Baeldung</a>
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user