Compare commits

...

2 Commits

Author SHA1 Message Date
Martin Prokoph
0a2294cd3d ui(settings): add volume sliders 2025-06-29 14:30:09 +02:00
Martin Prokoph
b5f65bd2bb feat: add collision handling to rotation 2025-06-29 14:29:38 +02:00
4 changed files with 50 additions and 7 deletions

View File

@@ -50,7 +50,7 @@ public class Tetris {
@Override @Override
public void run() { public void run() {
if (space.getCurrentTetromino() != null) { if (space.getCurrentTetromino() != null) {
space.getCurrentTetromino().fall(1); space.getCurrentTetromino().fall();
ui.getGamePanel().repaint(); ui.getGamePanel().repaint();
} }
} }

View File

@@ -18,8 +18,8 @@ public class Tetromino {
this.centerPos = Vec2i.of(2, 0); this.centerPos = Vec2i.of(2, 0);
} }
public void fall(int length) { public boolean fall() {
Vec2i newPos = centerPos.offset(Vec2i.of(0, length)); Vec2i newPos = centerPos.offset(Vec2i.of(0, 1));
if (collidesVertically(newPos)) { if (collidesVertically(newPos)) {
SoundEffect.BEEP.play(); SoundEffect.BEEP.play();
int[] affectedLines = new int[this.collision.length]; int[] affectedLines = new int[this.collision.length];
@@ -32,9 +32,11 @@ public class Tetromino {
Tetris.getSpace().increaseScore(20-fallLength); Tetris.getSpace().increaseScore(20-fallLength);
if (fallLength >= 1) Tetris.getSpace().spawnTetromino(); if (fallLength >= 1) Tetris.getSpace().spawnTetromino();
else Tetris.stopGame(); else Tetris.stopGame();
return false;
} }
fallLength += 1; fallLength += 1;
centerPos = newPos; centerPos = newPos;
return true;
} }
public void move(int xOffset) { public void move(int xOffset) {
@@ -68,8 +70,8 @@ public class Tetromino {
boolean collides = newPos.getX() < 0 || newPos.getX() + collision[0].length > Tetris.getSpace().getMapWidth(); // Side check boolean collides = newPos.getX() < 0 || newPos.getX() + collision[0].length > Tetris.getSpace().getMapWidth(); // Side check
if (!collides) { // Check for other tetrominos if (!collides) { // Check for other tetrominos
for (int i = 0; i < collision.length; i++) { for (int i = 0; i < collision.length; i++) {
int maxCollisionX = xOffset > 0 ? collision[i].length - 1 : 0; int maxCollisionX = xOffset >= 0 ? collision[i].length - 1 : 0;
while (collision[i][maxCollisionX] == 0) maxCollisionX += xOffset > 0 ? -1 : 1; // Figure out the collision box's bounding while (collision[i][maxCollisionX] == 0) maxCollisionX += xOffset >= 0 ? -1 : 1; // Figure out the collision box's bounding
if (newPos.getY()+maxCollisionX >= Tetris.getSpace().getMapHeight()) continue; if (newPos.getY()+maxCollisionX >= Tetris.getSpace().getMapHeight()) continue;
collides |= Tetris.getSpace().getGameMap()[newPos.getY() + i][newPos.getX() + maxCollisionX] != null; collides |= Tetris.getSpace().getGameMap()[newPos.getY() + i][newPos.getX() + maxCollisionX] != null;
@@ -88,7 +90,14 @@ public class Tetromino {
newCollision[j][M-i-1] = collision[i][j]; newCollision[j][M-i-1] = collision[i][j];
} }
} }
int[][] prevCollision = this.collision;
this.collision = newCollision; this.collision = newCollision;
int offset = 0;
for (int i = 0; i < 4; i++) {
if (collidesHorizontally(this.centerPos.offset(Vec2i.of(offset, 0)), -i)) offset = -i;
}
if (collidesVertically(this.centerPos.offset(Vec2i.of(offset, 0))) || collidesHorizontally(this.centerPos.offset(Vec2i.of(offset, 0)), offset)) this.collision = prevCollision;
else this.centerPos = centerPos.offset(Vec2i.of(offset, 0));
} }
public Color[] getLine(int line) { public Color[] getLine(int line) {
@@ -103,4 +112,10 @@ public class Tetromino {
} }
return l; return l;
} }
public void fallToBottom() {
while (true) {
if (!fall()) break;
}
}
} }

View File

@@ -3,6 +3,10 @@ package eu.midnightdust.yaytris.ui;
import eu.midnightdust.yaytris.Settings; import eu.midnightdust.yaytris.Settings;
import javax.swing.*; import javax.swing.*;
import java.awt.*;
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
import static eu.midnightdust.yaytris.ui.TetrisUI.setFontScale;
public class SettingsMenu extends AbstractMenu { public class SettingsMenu extends AbstractMenu {
final TetrisUI ui; final TetrisUI ui;
@@ -12,6 +16,23 @@ public class SettingsMenu extends AbstractMenu {
this.setBounds(x, y, width, height); this.setBounds(x, y, width, height);
this.setLayout(null); this.setLayout(null);
this.add(new JLabel("Musik-Lautstärke:"));
JSlider musicVolumeSlider = new JSlider(0, 100, Settings.musicVolume);
musicVolumeSlider.addChangeListener(change -> {
Settings.musicVolume = musicVolumeSlider.getValue();
Settings.write();
});
this.add(musicVolumeSlider);
this.add(new JLabel("Sound-Lautstärke:"));
JSlider soundVolumeSlider = new JSlider(0, 100, Settings.soundVolume);
soundVolumeSlider.addChangeListener(change -> {
Settings.soundVolume = soundVolumeSlider.getValue();
Settings.write();
});
this.add(soundVolumeSlider);
this.add(new JLabel("Skalierung:"));
JSlider scaleSlider = new JSlider(100, 500, (int) (Settings.guiScale * 100)); JSlider scaleSlider = new JSlider(100, 500, (int) (Settings.guiScale * 100));
scaleSlider.addChangeListener(change -> { scaleSlider.addChangeListener(change -> {
Settings.guiScale = scaleSlider.getValue() / 100f; Settings.guiScale = scaleSlider.getValue() / 100f;
@@ -23,4 +44,11 @@ public class SettingsMenu extends AbstractMenu {
backButton.addActionListener(ui::openMainMenu); backButton.addActionListener(ui::openMainMenu);
this.add(backButton); this.add(backButton);
} }
@Override
public Component add(Component comp) {
Component ret = super.add(comp);
if (comp instanceof JLabel) comp.setBounds(scale(60), scale(40+23*(this.getComponentCount()-1)), scale(100), scale(10));
return ret;
}
} }

View File

@@ -163,10 +163,10 @@ public class TetrisUI extends JFrame implements KeyListener {
break; break;
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
case KeyEvent.VK_S: case KeyEvent.VK_S:
Tetris.getSpace().getCurrentTetromino().fall(1); Tetris.getSpace().getCurrentTetromino().fall();
break; break;
case KeyEvent.VK_SPACE: case KeyEvent.VK_SPACE:
Tetris.getSpace().getCurrentTetromino().fall(12); Tetris.getSpace().getCurrentTetromino().fallToBottom();
break; break;
} }
gamePanel.repaint(); gamePanel.repaint();