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.game.Space;
|
||||||
import eu.midnightdust.yaytris.ui.ScoreMenu;
|
import eu.midnightdust.yaytris.ui.ScoreMenu;
|
||||||
import eu.midnightdust.yaytris.ui.TetrisUI;
|
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 javax.swing.*;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
@@ -48,6 +49,15 @@ public class Tetris {
|
|||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ui instance
|
||||||
|
*
|
||||||
|
* @see TetrisUI
|
||||||
|
*/
|
||||||
|
public static TetrisUI getUi() {
|
||||||
|
return ui;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the game space, preparing it for a new game.
|
* 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;
|
package eu.midnightdust.yaytris.util;
|
||||||
|
|
||||||
|
import eu.midnightdust.yaytris.util.sound.SoundUtil;
|
||||||
|
|
||||||
public enum SoundEffect {
|
public enum SoundEffect {
|
||||||
BOOP("/sounds/boop.wav"), LINE_COMPLETED("/sounds/line-completed.wav");
|
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;
|
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);
|
return SoundUtil.class.getResource(fileLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,80 +66,10 @@ public class SoundUtil {
|
|||||||
* @param line the DataLine responsible for audio playback
|
* @param line the DataLine responsible for audio playback
|
||||||
* @param volume the requested volume in percent (0-100%)
|
* @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)
|
if (volume < 0 || volume > 100)
|
||||||
throw new IllegalArgumentException("Volume not valid: " + volume);
|
throw new IllegalArgumentException("Volume not valid: " + volume);
|
||||||
FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
|
FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
|
||||||
gainControl.setValue(20f * (float) Math.log10(volume/100f));
|
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