diff options
Diffstat (limited to 'src/se')
| -rw-r--r-- | src/se/liu/gusso230/tetris/Board.java | 61 | ||||
| -rw-r--r-- | src/se/liu/gusso230/tetris/BoardTester.java | 2 | ||||
| -rw-r--r-- | src/se/liu/gusso230/tetris/BoardToTextConverter.java | 2 | ||||
| -rw-r--r-- | src/se/liu/gusso230/tetris/Poly.java | 49 | ||||
| -rw-r--r-- | src/se/liu/gusso230/tetris/TetrisComponent.java | 2 |
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() { |
