feat: check for collisions with other tetrominos

This commit is contained in:
Martin Prokoph
2025-06-28 19:32:26 +02:00
parent 41af446f94
commit 7aa1b0e73c
6 changed files with 39 additions and 17 deletions

View File

@@ -15,16 +15,6 @@ public class Space {
gameMap = new Color[12][7]; gameMap = new Color[12][7];
nextShape = getNextShape(); nextShape = getNextShape();
score = 0; score = 0;
Tetromino mino = new Tetromino(TetrominoShape.T);
mino.move(-2);
mino.fall(10);
onLinesChanged(mino, 9, 10, 11);
Tetromino mina = new Tetromino(TetrominoShape.LINE);
mina.move(1);
mina.rotate();
mina.fall(11);
onLinesChanged(mina, 9, 10, 11);
} }
public void spawnTetromino() { public void spawnTetromino() {

View File

@@ -9,6 +9,7 @@ public class Tetromino {
private final TetrominoShape shape; private final TetrominoShape shape;
private int[][] collision; private int[][] collision;
private Vec2i centerPos; private Vec2i centerPos;
private int fallLength = 0;
public Tetromino(TetrominoShape shape) { public Tetromino(TetrominoShape shape) {
this.shape = shape; this.shape = shape;
@@ -18,7 +19,8 @@ public class Tetromino {
public void fall(int length) { public void fall(int length) {
Vec2i newPos = centerPos.offset(Vec2i.of(0, length)); Vec2i newPos = centerPos.offset(Vec2i.of(0, length));
if (Tetris.space != null && newPos.getY()+this.collision.length > Tetris.space.getMapHeight()) { if (collidesVertically(newPos)) {
if (fallLength < 1) System.out.println("Game over!");
int[] affectedLines = new int[this.collision.length]; int[] affectedLines = new int[this.collision.length];
int line = centerPos.getY(); int line = centerPos.getY();
for (int i = 0; i < this.collision.length; i++) { for (int i = 0; i < this.collision.length; i++) {
@@ -28,17 +30,46 @@ public class Tetromino {
Tetris.space.onLinesChanged(this, affectedLines); Tetris.space.onLinesChanged(this, affectedLines);
Tetris.space.spawnTetromino(); Tetris.space.spawnTetromino();
} }
fallLength += 1;
centerPos = newPos; centerPos = newPos;
} }
private boolean collidesVertically(Vec2i newPos) {
if (Tetris.space == null) return false;
boolean collides = newPos.getY() + this.collision.length > Tetris.space.getMapHeight(); // Bottom check
if (!collides) {
for (int i = 0; i < collision[0].length; i++) {
int maxCollisionY = collision.length - 1;
while (collision[maxCollisionY][i] == 0) maxCollisionY--;
if (newPos.getY()+maxCollisionY >= Tetris.space.getGameMap().length) continue;
collides |= Tetris.space.getGameMap()[newPos.getY() + maxCollisionY][newPos.getX() + i] != null; // Check for other tetrominos
}
}
return collides;
}
public void move(int xOffset) { public void move(int xOffset) {
Vec2i newPos = centerPos.offset(Vec2i.of(xOffset, 0)); Vec2i newPos = centerPos.offset(Vec2i.of(xOffset, 0));
if (Tetris.space == null || newPos.getX() < 0 || newPos.getX() + collision[0].length > Tetris.space.getGameMap()[0].length) { if (collidesHorizontally(newPos, xOffset)) {
return; return;
} }
centerPos = newPos; centerPos = newPos;
} }
private boolean collidesHorizontally(Vec2i newPos, int xOffset) {
if (Tetris.space == null) return false;
boolean collides = newPos.getX() < 0 || newPos.getX() + collision[0].length > Tetris.space.getGameMap()[0].length;
if (!collides) {
for (int i = 0; i < collision.length; i++) {
int maxCollisionX = xOffset > 0 ? collision[i].length - 1 : 0;
while (collision[i][maxCollisionX] == 0) maxCollisionX += xOffset > 0 ? -1 : 1;
if (newPos.getY()+maxCollisionX >= Tetris.space.getGameMap().length) continue;
collides |= Tetris.space.getGameMap()[newPos.getY() + i][newPos.getX() + maxCollisionX] != null; // Check for other tetrominos
}
}
return collides;
}
public void rotate() { public void rotate() {
int M = collision.length; int M = collision.length;
int N = collision[0].length; int N = collision[0].length;

View File

@@ -36,7 +36,7 @@ public enum TetrominoShape {
{1, 0}, {1, 0},
{2, 1}, {2, 1},
{0, 1} {0, 1}
}, Color.PINK); }, Color.ORANGE);
; ;
final int[][] boundary; final int[][] boundary;

View File

@@ -30,9 +30,9 @@ public class GameCanvas extends JPanel {
Color color = Tetris.space.getGameMapWithTetromino()[y][x]; Color color = Tetris.space.getGameMapWithTetromino()[y][x];
if (color == null) continue; if (color == null) continue;
int blockSize = (int) Math.ceil((float) (this.getWidth() - this.getInsets().left - this.getInsets().right) / Tetris.space.getGameMapWithTetromino()[0].length); int blockSize = (int) Math.ceil((float) (this.getWidth() - this.getInsets().left - this.getInsets().right) / Tetris.space.getGameMapWithTetromino()[0].length);
//graphics.setXORMode(color); //graphics.setXORMode(withAlpha(color,0));
graphics.drawImage(texture, x*blockSize +getInsets().left, y*blockSize + getInsets().top, blockSize, blockSize, color, this); graphics.drawImage(texture, x*blockSize +getInsets().left, y*blockSize + getInsets().top, blockSize, blockSize, color, this);
graphics.setColor(withAlpha(color, 100)); graphics.setColor(withAlpha(color, 120));
graphics.fillRect(x*blockSize +getInsets().left, y*blockSize + getInsets().top, blockSize, blockSize); graphics.fillRect(x*blockSize +getInsets().left, y*blockSize + getInsets().top, blockSize, blockSize);
} }
} }

View File

@@ -1,7 +1,7 @@
package eu.midnightdust.yaytris.util; package eu.midnightdust.yaytris.util;
public enum Difficulty { public enum Difficulty {
NOOB(2000), EASY(1200), NORMAL(1000), HARD(750), EXTREME(500), WTF(100); NOOB(2000), EASY(1200), NORMAL(1000), HARD(750), EXTREME(100), WTF(30);
private final int timerPeriod; private final int timerPeriod;
Difficulty(int timerPeriod) { Difficulty(int timerPeriod) {

View File

@@ -1,5 +1,6 @@
{ {
"musicVolume": 100, "musicVolume": 100,
"soundVolume": 100, "soundVolume": 100,
"guiScale": 4.62 "guiScale": 5.0,
"difficulty": "NORMAL"
} }