feat: preview of next shape
This commit is contained in:
@@ -16,23 +16,27 @@ public class Space {
|
|||||||
|
|
||||||
public Space() {
|
public Space() {
|
||||||
gameMap = new Color[14][8];
|
gameMap = new Color[14][8];
|
||||||
nextShape = getNextShape();
|
nextShape = generateNextShape();
|
||||||
score = 0;
|
score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawnTetromino() {
|
public void spawnTetromino() {
|
||||||
currentTetromino = new Tetromino(nextShape);
|
currentTetromino = new Tetromino(nextShape);
|
||||||
nextShape = getNextShape();
|
nextShape = generateNextShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tetromino getCurrentTetromino() {
|
public Tetromino getCurrentTetromino() {
|
||||||
return currentTetromino;
|
return currentTetromino;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TetrominoShape getNextShape() {
|
public TetrominoShape generateNextShape() {
|
||||||
return TetrominoShape.values()[random.nextInt(TetrominoShape.values().length)];
|
return TetrominoShape.values()[random.nextInt(TetrominoShape.values().length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TetrominoShape getNextShape() {
|
||||||
|
return nextShape;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMapWidth() {
|
public int getMapWidth() {
|
||||||
return gameMap[0].length;
|
return gameMap[0].length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,17 @@ public enum TetrominoShape {
|
|||||||
|
|
||||||
final int[][] boundary;
|
final int[][] boundary;
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
||||||
TetrominoShape(int[][] boundary, Color color) {
|
TetrominoShape(int[][] boundary, Color color) {
|
||||||
this.boundary = boundary;
|
this.boundary = boundary;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int[][] getBoundary() {
|
||||||
|
return boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/main/java/eu/midnightdust/yaytris/ui/PreviewCanvas.java
Normal file
44
src/main/java/eu/midnightdust/yaytris/ui/PreviewCanvas.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
package eu.midnightdust.yaytris.ui;
|
package eu.midnightdust.yaytris.ui;
|
||||||
|
|
||||||
|
import eu.midnightdust.yaytris.util.CatppuccinColor;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
import java.awt.*;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
|
||||||
|
|
||||||
public class ScoreMenu extends AbstractMenu {
|
public class ScoreMenu extends AbstractMenu {
|
||||||
final TetrisUI ui;
|
final TetrisUI ui;
|
||||||
|
final PreviewCanvas previewCanvas;
|
||||||
final JLabel gameOverLabel;
|
final JLabel gameOverLabel;
|
||||||
final JLabel currentScoreLabel;
|
final JLabel currentScoreLabel;
|
||||||
final JLabel currentTimeLabel;
|
final JLabel currentTimeLabel;
|
||||||
@@ -15,6 +22,12 @@ public class ScoreMenu extends AbstractMenu {
|
|||||||
this.setBounds(x, y, width, height);
|
this.setBounds(x, y, width, height);
|
||||||
this.setLayout(null);
|
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.gameOverLabel = new JLabel();
|
||||||
this.add(gameOverLabel);
|
this.add(gameOverLabel);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class SettingsMenu extends JPanel {
|
|||||||
});
|
});
|
||||||
this.add(musicVolumeSlider);
|
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);
|
JSlider soundVolumeSlider = new JSlider(0, 100, Settings.soundVolume);
|
||||||
soundVolumeSlider.addChangeListener(change -> {
|
soundVolumeSlider.addChangeListener(change -> {
|
||||||
Settings.soundVolume = soundVolumeSlider.getValue();
|
Settings.soundVolume = soundVolumeSlider.getValue();
|
||||||
@@ -33,8 +33,8 @@ public class SettingsMenu extends JPanel {
|
|||||||
});
|
});
|
||||||
this.add(soundVolumeSlider);
|
this.add(soundVolumeSlider);
|
||||||
|
|
||||||
this.add(new JLabel("Skalierung:"));
|
this.add(new JLabel("Fenster-Skalierung:"));
|
||||||
JSlider scaleSlider = new JSlider(100, 500, (int) (Settings.guiScale * 100));
|
JSlider scaleSlider = new JSlider(100, 600, (int) (Settings.guiScale * 100));
|
||||||
scaleSlider.addChangeListener(change -> {
|
scaleSlider.addChangeListener(change -> {
|
||||||
Settings.guiScale = scaleSlider.getValue() / 100f;
|
Settings.guiScale = scaleSlider.getValue() / 100f;
|
||||||
Settings.write();
|
Settings.write();
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ public class TetrisUI extends JFrame implements KeyListener {
|
|||||||
JPanel menuPanel;
|
JPanel menuPanel;
|
||||||
|
|
||||||
public TetrisUI() {
|
public TetrisUI() {
|
||||||
Space space = new Space();
|
|
||||||
this.setLayout(null);
|
this.setLayout(null);
|
||||||
this.setTitle("Tetris");
|
this.setTitle("Tetris");
|
||||||
this.setSize((int) (400 * guiScale), (int) (300 * guiScale));
|
this.setSize((int) (400 * guiScale), (int) (300 * guiScale));
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
package eu.midnightdust.yaytris.util;
|
package eu.midnightdust.yaytris.util;
|
||||||
|
|
||||||
public enum Difficulty {
|
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 int timerPeriod;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
Difficulty(int timerPeriod) {
|
Difficulty(int timerPeriod) {
|
||||||
this.timerPeriod = 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() {
|
public int getTimerPeriod() {
|
||||||
return timerPeriod;
|
return timerPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import eu.midnightdust.yaytris.Settings;
|
|||||||
|
|
||||||
import javax.sound.sampled.*;
|
import javax.sound.sampled.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ public class SoundUtil {
|
|||||||
|
|
||||||
// Adapted from: https://www.baeldung.com/java-play-sound
|
// Adapted from: https://www.baeldung.com/java-play-sound
|
||||||
public static void playSoundClip(String fileLocation) {
|
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();
|
AudioFormat format = stream.getFormat();
|
||||||
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
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
|
// Adapted from: https://stackoverflow.com/a/40698149
|
||||||
private static void setVolume(Line line, int volume) {
|
private static void setVolume(Line line, int volume) {
|
||||||
if (volume < 0 || volume > 100)
|
if (volume < 0 || volume > 100)
|
||||||
@@ -68,7 +73,7 @@ public class SoundUtil {
|
|||||||
|
|
||||||
// Adapted from: https://www.baeldung.com/java-play-sound
|
// Adapted from: https://www.baeldung.com/java-play-sound
|
||||||
private void playMusic(String fileLocation) {
|
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();
|
AudioFormat format = stream.getFormat();
|
||||||
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
|
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"musicVolume": 50,
|
"musicVolume": 100,
|
||||||
"soundVolume": 100,
|
"soundVolume": 100,
|
||||||
"guiScale": 5.0,
|
"guiScale": 6.0,
|
||||||
"difficulty": "NORMAL"
|
"difficulty": "Normal"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user