diff --git a/src/main/java/eu/midnightdust/yaytris/game/Space.java b/src/main/java/eu/midnightdust/yaytris/game/Space.java index 665a18d..ba268cd 100644 --- a/src/main/java/eu/midnightdust/yaytris/game/Space.java +++ b/src/main/java/eu/midnightdust/yaytris/game/Space.java @@ -16,23 +16,27 @@ public class Space { public Space() { gameMap = new Color[14][8]; - nextShape = getNextShape(); + nextShape = generateNextShape(); score = 0; } public void spawnTetromino() { currentTetromino = new Tetromino(nextShape); - nextShape = getNextShape(); + nextShape = generateNextShape(); } public Tetromino getCurrentTetromino() { return currentTetromino; } - public TetrominoShape getNextShape() { + public TetrominoShape generateNextShape() { return TetrominoShape.values()[random.nextInt(TetrominoShape.values().length)]; } + public TetrominoShape getNextShape() { + return nextShape; + } + public int getMapWidth() { return gameMap[0].length; } diff --git a/src/main/java/eu/midnightdust/yaytris/game/TetrominoShape.java b/src/main/java/eu/midnightdust/yaytris/game/TetrominoShape.java index 40721ff..d16a106 100644 --- a/src/main/java/eu/midnightdust/yaytris/game/TetrominoShape.java +++ b/src/main/java/eu/midnightdust/yaytris/game/TetrominoShape.java @@ -41,8 +41,17 @@ public enum TetrominoShape { final int[][] boundary; final Color color; + TetrominoShape(int[][] boundary, Color color) { this.boundary = boundary; this.color = color; } + + public int[][] getBoundary() { + return boundary; + } + + public Color getColor() { + return color; + } } diff --git a/src/main/java/eu/midnightdust/yaytris/ui/PreviewCanvas.java b/src/main/java/eu/midnightdust/yaytris/ui/PreviewCanvas.java new file mode 100644 index 0000000..36bdd32 --- /dev/null +++ b/src/main/java/eu/midnightdust/yaytris/ui/PreviewCanvas.java @@ -0,0 +1,44 @@ +package eu.midnightdust.yaytris.ui; + +import eu.midnightdust.yaytris.Tetris; +import eu.midnightdust.yaytris.game.Tetromino; +import eu.midnightdust.yaytris.game.TetrominoShape; +import eu.midnightdust.yaytris.util.FileUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; + +import static eu.midnightdust.yaytris.game.TetrominoShape.T; + +public class PreviewCanvas extends JPanel { + final TetrisUI ui; + final BufferedImage texture; + + PreviewCanvas(TetrisUI ui) { + this.ui = ui; + this.texture = FileUtil.loadImage("/textures/tetromino.png"); + } + + public void paintComponent(Graphics graphics) { + super.paintComponent(graphics); + if (graphics == null) return; + + TetrominoShape nextShape = Tetris.getSpace().getNextShape(); + for (int y = 0; y < nextShape.getBoundary().length; y++) { + for (int x = 0; x < nextShape.getBoundary()[0].length; x++) { + Color color = nextShape.getBoundary()[y][x] == 0 ? null : nextShape.getColor(); // Get the color of the blob at these coordinates + if (color == null) continue; // Ignore empty cells + int blockSize = (int) Math.ceil((float) (this.getWidth() - this.getInsets().left - this.getInsets().right) / 4); + int startX = x * blockSize + getInsets().left + ((blockSize / 2) * (4 - nextShape.getBoundary()[0].length)); + graphics.drawImage(texture, startX, y*blockSize + getInsets().top, blockSize, blockSize, color, this); // Draw out (grayscale) texture + graphics.setColor(withAlpha(color, 120)); // Overlay the texture with the blobs color + graphics.fillRect(startX, y*blockSize + getInsets().top, blockSize, blockSize); + } + } + } + + public static Color withAlpha(Color color, int alpha) { + return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha); + } +} diff --git a/src/main/java/eu/midnightdust/yaytris/ui/ScoreMenu.java b/src/main/java/eu/midnightdust/yaytris/ui/ScoreMenu.java index 818d11a..8e70399 100644 --- a/src/main/java/eu/midnightdust/yaytris/ui/ScoreMenu.java +++ b/src/main/java/eu/midnightdust/yaytris/ui/ScoreMenu.java @@ -1,11 +1,18 @@ package eu.midnightdust.yaytris.ui; +import eu.midnightdust.yaytris.util.CatppuccinColor; + import javax.swing.*; +import javax.swing.border.LineBorder; +import java.awt.*; import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import static eu.midnightdust.yaytris.ui.TetrisUI.scale; + public class ScoreMenu extends AbstractMenu { final TetrisUI ui; + final PreviewCanvas previewCanvas; final JLabel gameOverLabel; final JLabel currentScoreLabel; final JLabel currentTimeLabel; @@ -15,6 +22,12 @@ public class ScoreMenu extends AbstractMenu { this.setBounds(x, y, width, height); this.setLayout(null); + this.previewCanvas = new PreviewCanvas(ui); + this.previewCanvas.setBounds(scale(92), scale(4), scale(40), scale(40)); + this.previewCanvas.setBackground(Color.BLACK); + this.previewCanvas.setBorder(new LineBorder(CatppuccinColor.SURFACE0.getColor())); + this.add(previewCanvas, 0); + this.gameOverLabel = new JLabel(); this.add(gameOverLabel); diff --git a/src/main/java/eu/midnightdust/yaytris/ui/SettingsMenu.java b/src/main/java/eu/midnightdust/yaytris/ui/SettingsMenu.java index cb9a4ef..dce21d0 100644 --- a/src/main/java/eu/midnightdust/yaytris/ui/SettingsMenu.java +++ b/src/main/java/eu/midnightdust/yaytris/ui/SettingsMenu.java @@ -25,7 +25,7 @@ public class SettingsMenu extends JPanel { }); this.add(musicVolumeSlider); - this.add(new JLabel("Sound-Lautstärke:")); + this.add(new JLabel("Effekt-Lautstärke:")); JSlider soundVolumeSlider = new JSlider(0, 100, Settings.soundVolume); soundVolumeSlider.addChangeListener(change -> { Settings.soundVolume = soundVolumeSlider.getValue(); @@ -33,8 +33,8 @@ public class SettingsMenu extends JPanel { }); this.add(soundVolumeSlider); - this.add(new JLabel("Skalierung:")); - JSlider scaleSlider = new JSlider(100, 500, (int) (Settings.guiScale * 100)); + this.add(new JLabel("Fenster-Skalierung:")); + JSlider scaleSlider = new JSlider(100, 600, (int) (Settings.guiScale * 100)); scaleSlider.addChangeListener(change -> { Settings.guiScale = scaleSlider.getValue() / 100f; Settings.write(); diff --git a/src/main/java/eu/midnightdust/yaytris/ui/TetrisUI.java b/src/main/java/eu/midnightdust/yaytris/ui/TetrisUI.java index f762113..c67c02f 100644 --- a/src/main/java/eu/midnightdust/yaytris/ui/TetrisUI.java +++ b/src/main/java/eu/midnightdust/yaytris/ui/TetrisUI.java @@ -21,7 +21,6 @@ public class TetrisUI extends JFrame implements KeyListener { JPanel menuPanel; public TetrisUI() { - Space space = new Space(); this.setLayout(null); this.setTitle("Tetris"); this.setSize((int) (400 * guiScale), (int) (300 * guiScale)); diff --git a/src/main/java/eu/midnightdust/yaytris/util/Difficulty.java b/src/main/java/eu/midnightdust/yaytris/util/Difficulty.java index a145c09..429dc17 100644 --- a/src/main/java/eu/midnightdust/yaytris/util/Difficulty.java +++ b/src/main/java/eu/midnightdust/yaytris/util/Difficulty.java @@ -1,14 +1,26 @@ package eu.midnightdust.yaytris.util; public enum Difficulty { - NOOB(2000), EASY(1200), NORMAL(1000), HARD(500), EXTREME(100), WTF(30); + NOOB(2000), EASY(1200), NORMAL(1000), HARD(500), EXTREME(100), WTF(30, "WTF"); private final int timerPeriod; + private final String name; Difficulty(int timerPeriod) { this.timerPeriod = timerPeriod; + this.name = this.name().charAt(0) + this.name().substring(1).toLowerCase(); + } + + Difficulty(int timerPeriod, String name) { + this.timerPeriod = timerPeriod; + this.name = name; } public int getTimerPeriod() { return timerPeriod; } + + @Override + public String toString() { + return this.name; + } } diff --git a/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java b/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java index b0015c4..727765c 100644 --- a/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java +++ b/src/main/java/eu/midnightdust/yaytris/util/SoundUtil.java @@ -4,6 +4,7 @@ import eu.midnightdust.yaytris.Settings; import javax.sound.sampled.*; import java.io.IOException; +import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -23,7 +24,7 @@ public class SoundUtil { // Adapted from: https://www.baeldung.com/java-play-sound public static void playSoundClip(String fileLocation) { - try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.class.getResource(fileLocation))) { // FIXME: Support audio files from JAR. File streams won't work here for some reason. + try (AudioInputStream stream = AudioSystem.getAudioInputStream(getResource(fileLocation))) { // FIXME: Support audio files from JAR. File streams won't work here for some reason. AudioFormat format = stream.getFormat(); DataLine.Info info = new DataLine.Info(Clip.class, format); @@ -37,6 +38,10 @@ public class SoundUtil { } } + private static URL getResource(String fileLocation) { + return SoundUtil.class.getResource(fileLocation); + } + // Adapted from: https://stackoverflow.com/a/40698149 private static void setVolume(Line line, int volume) { if (volume < 0 || volume > 100) @@ -68,7 +73,7 @@ public class SoundUtil { // Adapted from: https://www.baeldung.com/java-play-sound private void playMusic(String fileLocation) { - try (AudioInputStream stream = AudioSystem.getAudioInputStream(SoundUtil.class.getResource(fileLocation))) { + try (AudioInputStream stream = AudioSystem.getAudioInputStream(getResource(fileLocation))) { AudioFormat format = stream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); diff --git a/tetris_settings.json5 b/tetris_settings.json5 index 3303d9b..e0ab6d7 100644 --- a/tetris_settings.json5 +++ b/tetris_settings.json5 @@ -1,6 +1,6 @@ { - "musicVolume": 50, + "musicVolume": 100, "soundVolume": 100, - "guiScale": 5.0, - "difficulty": "NORMAL" + "guiScale": 6.0, + "difficulty": "Normal" } \ No newline at end of file