From d11073560b2a294eb52916a25fe1dacd38bd637a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Thu, 4 Mar 2021 09:47:39 +0100 Subject: heavy --- src/se/liu/gusso230/tetris/Board.java | 26 ++++++--- src/se/liu/gusso230/tetris/BoardInterface.java | 6 ++ src/se/liu/gusso230/tetris/BoardTester.java | 2 + src/se/liu/gusso230/tetris/DefaultFallHandler.java | 2 +- src/se/liu/gusso230/tetris/FallHandler.java | 2 +- src/se/liu/gusso230/tetris/Fallthrough.java | 2 +- src/se/liu/gusso230/tetris/Heavy.java | 66 ++++++++++++++++++++++ src/se/liu/gusso230/tetris/TetrisComponent.java | 14 ++++- 8 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 src/se/liu/gusso230/tetris/BoardInterface.java create mode 100644 src/se/liu/gusso230/tetris/Heavy.java (limited to 'src') diff --git a/src/se/liu/gusso230/tetris/Board.java b/src/se/liu/gusso230/tetris/Board.java index 5e0ca08..278ddf3 100644 --- a/src/se/liu/gusso230/tetris/Board.java +++ b/src/se/liu/gusso230/tetris/Board.java @@ -115,7 +115,7 @@ public class Board { private void moveFalling() { fallingY += 1; - if (hasFallingCollision() || !falling.isInside(fallingX, fallingY, 0, width - 1, 0, height - 1)) { + if (hasFallingCollision(0, 1) || !falling.isInside(fallingX, fallingY, 0, width - 1, 0, height - 1)) { fallingY -= 1; placeAt(falling, fallingX, fallingY); falling = null; @@ -128,14 +128,14 @@ public class Board { falling = tetrominoMaker.getRandomPoly(RND); fallingX = (width - falling.getBoundingBoxSize()) / 2; fallingY = -1; - if (hasFallingCollision()) { + if (hasFallingCollision(0, 0)) { setGameOver(); } notifyListeners(); } - private boolean hasFallingCollision() { - return fallHandler.hasFallingCollision(this); + private boolean hasFallingCollision(final int dx, final int dy) { + return fallHandler.hasFallingCollision(this, dx, dy); } private boolean fallingIsOutside() { @@ -156,7 +156,7 @@ public class Board { break; } fallingX += dx; - if (fallingIsOutside() || hasFallingCollision()) + if (fallingIsOutside() || hasFallingCollision(dx, 0)) { fallingX -= dx; } @@ -175,7 +175,7 @@ public class Board { } // reverse rotation if collision - if (fallingIsOutside() || hasFallingCollision()) { + if (fallingIsOutside() || hasFallingCollision(0, 0)) { if (dir == Direction.RIGHT) { falling.rotateCounterClockwise(); } else { @@ -186,6 +186,10 @@ public class Board { notifyListeners(); } + public void powerup() { + fallHandler = new Heavy(); + } + private void checkFullLines() { int y = height - 1; int linesCleared = 0; @@ -229,7 +233,11 @@ public class Board { private void updateFallHandler() { if (lineStreak >= LINE_STREAK_TARGET) { - fallHandler = new Fallthrough(); + if (lineStreak == LINE_STREAK_TARGET) { + fallHandler = new Heavy(); + } else { + fallHandler = new Fallthrough(); + } lineStreak -= LINE_STREAK_TARGET; } } @@ -325,6 +333,10 @@ public class Board { this.state = state; } + public void setSquareAt(int x, int y, SquareType type) { + squares[y][x] = type; + } + public void togglePaused() { paused = !paused; } diff --git a/src/se/liu/gusso230/tetris/BoardInterface.java b/src/se/liu/gusso230/tetris/BoardInterface.java new file mode 100644 index 0000000..8f9ec0a --- /dev/null +++ b/src/se/liu/gusso230/tetris/BoardInterface.java @@ -0,0 +1,6 @@ +package se.liu.gusso230.tetris; + +public interface BoardInterface { + boolean promptUserYesNo(String prompt); + String promptUserString(String prompt); +} diff --git a/src/se/liu/gusso230/tetris/BoardTester.java b/src/se/liu/gusso230/tetris/BoardTester.java index 82c225e..1063853 100644 --- a/src/se/liu/gusso230/tetris/BoardTester.java +++ b/src/se/liu/gusso230/tetris/BoardTester.java @@ -7,6 +7,8 @@ public class BoardTester implements BoardInterface { HighscoreList highscores = new HighscoreList(); Board board = new Board(10, 20, highscores, new BoardTester()); + board.setSquareAt(5, 18, SquareType.S); + TetrisViewer viewer = new TetrisViewer(board); viewer.show(); diff --git a/src/se/liu/gusso230/tetris/DefaultFallHandler.java b/src/se/liu/gusso230/tetris/DefaultFallHandler.java index 180d8f4..4f56ed8 100644 --- a/src/se/liu/gusso230/tetris/DefaultFallHandler.java +++ b/src/se/liu/gusso230/tetris/DefaultFallHandler.java @@ -1,7 +1,7 @@ package se.liu.gusso230.tetris; public class DefaultFallHandler implements FallHandler { - @Override public boolean hasFallingCollision(final Board board) { + @Override public boolean hasFallingCollision(final Board board, final int dx, final int dy) { return !board.getFalling().onlyCoversEmpty(board.getFallingX(), board.getFallingY(), board); } diff --git a/src/se/liu/gusso230/tetris/FallHandler.java b/src/se/liu/gusso230/tetris/FallHandler.java index ed21d33..887c96e 100644 --- a/src/se/liu/gusso230/tetris/FallHandler.java +++ b/src/se/liu/gusso230/tetris/FallHandler.java @@ -1,6 +1,6 @@ package se.liu.gusso230.tetris; public interface FallHandler { - boolean hasFallingCollision(Board board); + boolean hasFallingCollision(Board board, int dx, int dy); String getDescription(); } diff --git a/src/se/liu/gusso230/tetris/Fallthrough.java b/src/se/liu/gusso230/tetris/Fallthrough.java index add19fc..ff95725 100644 --- a/src/se/liu/gusso230/tetris/Fallthrough.java +++ b/src/se/liu/gusso230/tetris/Fallthrough.java @@ -1,7 +1,7 @@ package se.liu.gusso230.tetris; public class Fallthrough implements FallHandler { - @Override public boolean hasFallingCollision(final Board board) { + @Override public boolean hasFallingCollision(final Board board, final int dx, final int dy) { return !board.getFalling().isAtOrAbove(board.getFallingY(), board.getHeight()); } diff --git a/src/se/liu/gusso230/tetris/Heavy.java b/src/se/liu/gusso230/tetris/Heavy.java new file mode 100644 index 0000000..4f7700c --- /dev/null +++ b/src/se/liu/gusso230/tetris/Heavy.java @@ -0,0 +1,66 @@ +package se.liu.gusso230.tetris; + +public class Heavy implements FallHandler { + @Override public boolean hasFallingCollision(final Board board, final int dx, final int dy) { + if (dx != 0) { + return new DefaultFallHandler().hasFallingCollision(board, dx, dy); + } + + boolean emptyUnderAll = true; + for (Point point: board.getFalling().getPoints()) { + int x = board.getFallingX() + point.getX(); + int y = board.getFallingY() + point.getY(); + + if (board.getSquareAt(x, y, false) != SquareType.EMPTY) { + emptyUnderAll = false; + break; + } + } + if (emptyUnderAll) { + return false; + } + + for (Point point: board.getFalling().getPoints()) { + int newX = board.getFallingX() + point.getX(); + int newY = board.getFallingY() + point.getY(); + if (newY >= board.getHeight()) { + // below board + return true; + } + + boolean foundEmpty = false; + for (int y = newY; y < board.getHeight(); y++) { + if (board.getSquareAt(newX, y, false) == SquareType.EMPTY) { + foundEmpty = true; + break; + } + } + if (!foundEmpty) { + // no empty square found until below board + return true; + } + } + + for (Point point: board.getFalling().getPoints()) { + int x = board.getFallingX() + point.getX(); + int y = board.getFallingY() + point.getY(); + + SquareType above = SquareType.EMPTY; + while (y < board.getHeight()) { + SquareType old = board.getSquareAt(x, y, false); + board.setSquareAt(x, y, above); + above = old; + if (old == SquareType.EMPTY) { + break; + } + y++; + } + } + + return false; + } + + @Override public String getDescription() { + return "Heavy"; + } +} diff --git a/src/se/liu/gusso230/tetris/TetrisComponent.java b/src/se/liu/gusso230/tetris/TetrisComponent.java index d2093ea..17705d6 100644 --- a/src/se/liu/gusso230/tetris/TetrisComponent.java +++ b/src/se/liu/gusso230/tetris/TetrisComponent.java @@ -20,17 +20,19 @@ public class TetrisComponent extends JComponent implements BoardListener { this.getInputMap().put(KeyStroke.getKeyStroke('a'), "moveLeft"); this.getInputMap().put(KeyStroke.getKeyStroke('d'), "moveRight"); - this.getInputMap().put(KeyStroke.getKeyStroke('q'), "rotateLeft"); - this.getInputMap().put(KeyStroke.getKeyStroke('e'), "rotateRight"); + this.getInputMap().put(KeyStroke.getKeyStroke('s'), "rotateLeft"); + this.getInputMap().put(KeyStroke.getKeyStroke('w'), "rotateRight"); this.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "moveLeft"); this.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "moveRight"); this.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "rotateLeft"); this.getInputMap().put(KeyStroke.getKeyStroke("UP"), "rotateRight"); + this.getInputMap().put(KeyStroke.getKeyStroke('e'), "powerup"); this.getActionMap().put("moveLeft", new MoveAction(Direction.LEFT)); this.getActionMap().put("moveRight", new MoveAction(Direction.RIGHT)); this.getActionMap().put("rotateLeft", new RotateAction(Direction.LEFT)); this.getActionMap().put("rotateRight", new RotateAction(Direction.RIGHT)); + this.getActionMap().put("powerup", new PowerUpAction()); } private class MoveAction extends AbstractAction { @@ -55,6 +57,14 @@ public class TetrisComponent extends JComponent implements BoardListener { } } + private class PowerUpAction extends AbstractAction { + private PowerUpAction() {} + + @Override public void actionPerformed(final ActionEvent actionEvent) { + board.powerup(); + } + } + @Override protected void paintComponent(final Graphics g) { super.paintComponent(g); final Graphics2D g2d = (Graphics2D) g; -- cgit v1.2.1