summaryrefslogtreecommitdiffstats
path: root/src/se
diff options
context:
space:
mode:
Diffstat (limited to 'src/se')
-rw-r--r--src/se/liu/gusso230/tetris/Board.java61
-rw-r--r--src/se/liu/gusso230/tetris/BoardTester.java2
-rw-r--r--src/se/liu/gusso230/tetris/BoardToTextConverter.java2
-rw-r--r--src/se/liu/gusso230/tetris/Poly.java49
-rw-r--r--src/se/liu/gusso230/tetris/TetrisComponent.java2
5 files changed, 97 insertions, 19 deletions
diff --git a/src/se/liu/gusso230/tetris/Board.java b/src/se/liu/gusso230/tetris/Board.java
index 8feed1f..c730958 100644
--- a/src/se/liu/gusso230/tetris/Board.java
+++ b/src/se/liu/gusso230/tetris/Board.java
@@ -5,6 +5,11 @@ import java.util.List;
import java.util.Random;
public class Board {
+ private enum GameState {
+ RUNNING, GAMEOVER,
+ }
+
+ private GameState state = GameState.RUNNING;
private SquareType[][] squares;
private int width;
private int height;
@@ -33,15 +38,22 @@ public class Board {
public void tick() {
System.out.println("tick");
- if (falling == null) {
- newFalling();
- } else {
- moveFalling();
+ if (state == GameState.RUNNING) {
+ if (falling == null) {
+ newFalling();
+ } else {
+ moveFalling();
+ }
}
}
private void moveFalling() {
fallingY += 1;
+ if (hasFallingCollision() || !falling.inside(fallingX, fallingY, 0, width - 1, 0, height - 1)) {
+ fallingY -= 1;
+ placeAt(falling, fallingX, fallingY);
+ falling = null;
+ }
notifyListeners();
}
@@ -49,20 +61,43 @@ public class Board {
falling = tetrominoMaker.getRandomPoly(RND);
fallingX = (width - falling.getBoundingBoxSize()) / 2;
fallingY = -1;
+ if (hasFallingCollision()) {
+ state = GameState.GAMEOVER;
+ }
notifyListeners();
}
- public void move(Direction dir) {
+ private boolean hasFallingCollision() {
+ return !falling.onlyCoversEmpty(fallingX, fallingY, this);
+ }
+
+ public void move(Direction dir) {
+ if (falling == null) {
+ return;
+ }
+ int dx = 0;
switch (dir) {
case LEFT:
- fallingX -= 1;
+ dx = -1;
break;
case RIGHT:
- fallingX += 1;
+ dx = +1;
break;
}
+ fallingX += dx;
+ if (!falling.inside(fallingX, fallingY, 0, width - 1, 0, height - 1)
+ || hasFallingCollision())
+ {
+ fallingX -= dx;
+ }
notifyListeners();
- }
+ }
+
+ private void placeAt(Poly poly, int x, int y) {
+ for (Point pt : poly.getPoints()) {
+ squares[y + pt.getY()][x + pt.getX()] = poly.getSquareType();
+ }
+ }
public int getWidth() {
return width;
@@ -72,11 +107,13 @@ public class Board {
return height;
}
- public SquareType getSquareAt(int x, int y) {
- if (falling != null && falling.covers(x, y, fallingX, fallingY)) {
+ public SquareType getSquareAt(int x, int y, boolean includeFalling) {
+ if (includeFalling && falling != null && falling.covers(fallingX, fallingY, x, y)) {
return falling.getSquareType();
- } else {
+ } else if (y >= 0 && y < height && x >= 0 && x < width) {
return squares[y][x];
+ } else {
+ return SquareType.EMPTY;
}
}
@@ -127,7 +164,7 @@ public class Board {
}
private void notifyListeners() {
- for (BoardListener bl: boardListeners) {
+ for (BoardListener bl : boardListeners) {
bl.boardChanged();
}
}
diff --git a/src/se/liu/gusso230/tetris/BoardTester.java b/src/se/liu/gusso230/tetris/BoardTester.java
index 14f3b5a..2bd30ab 100644
--- a/src/se/liu/gusso230/tetris/BoardTester.java
+++ b/src/se/liu/gusso230/tetris/BoardTester.java
@@ -16,7 +16,7 @@ public class BoardTester {
}
};
- final Timer clockTimer = new Timer(500, tick);
+ final Timer clockTimer = new Timer(250, tick);
clockTimer.setCoalesce(true);
clockTimer.start();
}
diff --git a/src/se/liu/gusso230/tetris/BoardToTextConverter.java b/src/se/liu/gusso230/tetris/BoardToTextConverter.java
index 3dca3b9..33d8c3b 100644
--- a/src/se/liu/gusso230/tetris/BoardToTextConverter.java
+++ b/src/se/liu/gusso230/tetris/BoardToTextConverter.java
@@ -33,7 +33,7 @@ public class BoardToTextConverter {
StringBuilder s = new StringBuilder();
for (int y = 0; y < board.getHeight(); y++) {
for (int x = 0; x < board.getWidth(); x++) {
- s.append(fromSquareType(board.getSquareAt(x, y)));
+ s.append(fromSquareType(board.getSquareAt(x, y, true)));
}
s.append('\n');
}
diff --git a/src/se/liu/gusso230/tetris/Poly.java b/src/se/liu/gusso230/tetris/Poly.java
index 1787194..6f8bece 100644
--- a/src/se/liu/gusso230/tetris/Poly.java
+++ b/src/se/liu/gusso230/tetris/Poly.java
@@ -22,14 +22,15 @@ public class Poly {
}
/**
- * Returns wether this poly covers a position (x, y) if the top left corner of the poly is at (posX, posY).
+ * Returns wether this poly covers a position (x, y) if the top left corner
+ * of the poly is at (posX, posY).
*
- * @param x The x position of the coordinate to test.
- * @param y The y position of the coordinate to test.
* @param posX The x position of the top left corner of the poly's bounding box.
* @param posY The y position of the top left corner of the poly's bounding box.
+ * @param x The x position of the coordinate to test.
+ * @param y The y position of the coordinate to test.
*/
- public boolean covers(int x, int y, int posX, int posY) {
+ public boolean covers(int posX, int posY, int x, int y) {
for (Point point : points) {
if (posX + point.getX() == x && posY + point.getY() == y) {
return true;
@@ -39,6 +40,37 @@ public class Poly {
}
/**
+ * Returns wether this poly is completely inside some box from (minX, minY)
+ * to (maxX, maxY) if the top left corner of the poly is at (posX, posY).
+ *
+ * Where the "minimum" and "maximum" corners mentioned below are located depends on
+ * the orientation of the grid. What matters is that minX < maxX and minY < maxY.
+ *
+ * @param posX The x position of the top left corner of the poly's bounding box.
+ * @param posY The y position of the top left corner of the poly's bounding box.
+ * @param minX The x position of the "minimum" corner.
+ * @param maxX The x position of the "maximum" corner.
+ * @param minY The y position of the "minimum" corner.
+ * @param maxY The y position of the "maximum" corner.
+ */
+ public boolean inside(int posX, int posY, int minX, int maxX, int minY, int maxY) {
+ if (minX > maxX) {
+ throw new IllegalArgumentException("minX has to be smaller than or equal to maxX");
+ }
+ if (minY > maxY) {
+ throw new IllegalArgumentException("minY has to be smaller than or equal to maxY");
+ }
+ for (Point point : points) {
+ int pointX = posX + point.getX();
+ int pointY = posY + point.getY();
+ if (pointX < minX || pointX > maxX || pointY < minY || pointY > maxY) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Rotates all the poly's points one step clockwise.
*/
public void rotateClockwise() {
@@ -47,6 +79,15 @@ public class Poly {
}
}
+ public boolean onlyCoversEmpty(int posX, int posY, Board board) {
+ for (Point point : points) {
+ if (board.getSquareAt(posX + point.getX(), posY + point.getY(), false) != SquareType.EMPTY) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public int getBoundingBoxSize() {
return boundingBoxSize;
}
diff --git a/src/se/liu/gusso230/tetris/TetrisComponent.java b/src/se/liu/gusso230/tetris/TetrisComponent.java
index 0773ae4..2be91a3 100644
--- a/src/se/liu/gusso230/tetris/TetrisComponent.java
+++ b/src/se/liu/gusso230/tetris/TetrisComponent.java
@@ -48,7 +48,7 @@ public class TetrisComponent extends JComponent implements BoardListener {
}
public Color getColor(int x, int y) {
- return SQUARE_TYPE_COLORS.get(board.getSquareAt(x, y));
+ return SQUARE_TYPE_COLORS.get(board.getSquareAt(x, y, true));
}
@Override public void boardChanged() {