diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/Tetris.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/Tetris.java index fa4763a..ed29ff8 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/Tetris.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/Tetris.java @@ -93,21 +93,20 @@ class Tetris extends StatelessGame { @Override protected void onLoad(@NotNull CompletableFuture callback) { - this.tetrisGame = new TetrisGame(this, getSpawn().sub(6, 8, 15)); - this.tetrisGame.generate(); + } @Override protected void onPlayerMove(@NotNull PlayerMoveEvent event) { -// if(!getSpawn().withView(event.getNewPosition()).equals(event.getNewPosition())) { -// event.setCancelled(true); -// event.getPlayer().setSprinting(false); -// } - Player player = event.getPlayer(); Pos previousPosition = event.getPlayer().getPosition(); Pos currentPosition = event.getNewPosition(); + if(this.tetrisGame == null) return; + + event.setNewPosition(this.tetrisGame.getPlayerSpawnPosition().withView(event.getNewPosition())); + player.setSprinting(false); + Vec movementVector = currentPosition.asVec().sub(previousPosition.asVec()); float yaw = player.getPosition().yaw(); @@ -145,8 +144,6 @@ class Tetris extends StatelessGame { } if(previousPosition.y() < currentPosition.y()) pressedButton(Button.space); - -// event.setNewPosition(getSpawn().withView(event.getNewPosition())); } protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) { @@ -162,11 +159,9 @@ class Tetris extends StatelessGame { p.getInventory().setItemStack(0, ItemStack.builder(Material.BIRCH_BUTTON).customName(Component.text("Controller")).build()); p.setSprinting(false); -// p.setGameMode(GameMode.SPECTATOR); -// Entity anvil = new Entity(EntityType.FALLING_BLOCK); -// ((FallingBlockMeta) anvil.getEntityMeta()).setBlock(Block.ANVIL); -// anvil.setInstance(this, getSpawn()); -// anvil.addPassenger(p); + this.tetrisGame = new TetrisGame(this, getSpawn().sub(6, 8, 15)); + this.tetrisGame.generate(); + p.teleport(this.tetrisGame.getPlayerSpawnPosition()); this.tetrisGame.sidebar.addViewer(p); return super.onPlayerJoin(p); diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Playfield.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Playfield.java index 601f250..882c221 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Playfield.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Playfield.java @@ -9,6 +9,7 @@ import net.minestom.server.instance.block.Block; public class Playfield { private final Pos lowerLeftCorner; private final StatelessGame instance; + private final int height = 22; public Playfield(Pos lowerLeftCorner, StatelessGame instance) { this.lowerLeftCorner = lowerLeftCorner; @@ -16,7 +17,7 @@ public class Playfield { } public Pos getPlayerSpawnPosition() { - return this.lowerLeftCorner.add(6, 8, 15); + return this.lowerLeftCorner.add(6, 8, 20); } public Pos getTetrominoSpawnPosition() { @@ -27,28 +28,36 @@ public class Playfield { return this.lowerLeftCorner.add(-4, 19, 0); } + public Pos getNextPosition() { + return this.lowerLeftCorner.add(14, 19, 0); + } + public void generate() { AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); for(int x=0; x<12; x++) { - for(int y=0; y<22; y++) { + for(int y=0; y {}); } public int removeFullLines() { int removedLinesCounter = 0; - for(int y=1; y<22; y++) { + for(int y=1; y tetrominoBag = new ArrayList<>(); private boolean holdPossible = true; + private final Pos nextPosition; private final Pos holdPosition; private final Pos tetrominoSpawnPosition; public Sidebar sidebar = new Sidebar(Component.text("Info:")); public TetrisGame(StatelessGame instance, Pos lowerLeftCorner) { - this(instance, lowerLeftCorner, new Tetromino(instance, Tetromino.Shape.J), new Tetromino(instance, Tetromino.Shape.T)); + this(instance, lowerLeftCorner, Tetromino.Shape.J); } - public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino startTetromino, Tetromino nextTetromino) { + public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino.Shape startTetrominoShape) { this.instance = instance; this.playfield = new Playfield(lowerLeftCorner, this.instance); - this.currentTetromino = startTetromino; - this.nextTetromino = nextTetromino; this.holdPosition = this.playfield.getHoldPosition(); + this.nextPosition = this.playfield.getNextPosition(); this.tetrominoSpawnPosition = this.playfield.getTetrominoSpawnPosition(); this.buildSidebar(); + + this.currentTetromino = new Tetromino(this.instance, startTetrominoShape, this.playfield); + this.nextTetromino = this.getNextTetromino(); + } + + public Pos getPlayerSpawnPosition() { + return this.playfield.getPlayerSpawnPosition(); } public void start() { @@ -115,7 +122,7 @@ public class TetrisGame { } this.currentTetromino.remove(); - this.holdTetromino = this.currentTetromino; + this.holdTetromino = new Tetromino(this.instance, this.currentTetromino.shape, this.playfield); this.currentTetromino = newCurrentTetromino; this.currentTetromino.setPosition(this.tetrominoSpawnPosition); @@ -123,7 +130,7 @@ public class TetrisGame { if(!this.currentTetromino.moveDown()) loose(); this.holdTetromino.setPosition(this.holdPosition); - this.holdTetromino.draw(); + this.holdTetromino.draw(false); this.holdPossible = false; return true; } @@ -132,12 +139,17 @@ public class TetrisGame { private Tetromino getNextTetromino() { if(this.tetrominoBag.isEmpty()) { for(Tetromino.Shape shape : Tetromino.Shape.values()) { - this.tetrominoBag.add(new Tetromino(this.instance, shape)); + this.tetrominoBag.add(new Tetromino(this.instance, shape, this.playfield)); } Collections.shuffle(this.tetrominoBag); } - return this.tetrominoBag.removeFirst(); + if(this.nextTetromino != null) this.nextTetromino.remove(); + Tetromino tetromino = this.tetrominoBag.removeFirst(); + tetromino.setPosition(this.nextPosition); + tetromino.draw(false); + + return tetromino; } private void loose() { @@ -169,8 +181,8 @@ public class TetrisGame { } private void setActiveTetrominoDown() { - currentTetromino = nextTetromino; - nextTetromino = getNextTetromino(); + this.currentTetromino = this.nextTetromino; + this.nextTetromino = getNextTetromino(); int removedLines = this.playfield.removeFullLines(); switch (removedLines) { @@ -197,9 +209,9 @@ public class TetrisGame { this.updateSidebar(); - currentTetromino.setPosition(this.tetrominoSpawnPosition); - currentTetromino.draw(); - if(!currentTetromino.moveDown()) { + this.currentTetromino.setPosition(this.tetrominoSpawnPosition); + this.currentTetromino.draw(); + if(!this.currentTetromino.moveDown()) { loose(); } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Tetromino.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Tetromino.java index d95c945..bd5b56d 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Tetromino.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/Tetromino.java @@ -9,10 +9,12 @@ import java.util.Arrays; import java.util.List; public class Tetromino { - private final Shape shape; + public final Shape shape; private final StatelessGame instance; + private final Playfield playfield; private Pos position; private int[][] shapeArray; + private final Block ghostBlock = Block.ICE; public enum Shape { I, @@ -24,9 +26,10 @@ public class Tetromino { Z } - public Tetromino(StatelessGame instance, Shape shape) { + public Tetromino(StatelessGame instance, Shape shape, Playfield playfield) { this.instance = instance; this.shape = shape; + this.playfield = playfield; switch (this.shape) { case I -> shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}; @@ -39,10 +42,6 @@ public class Tetromino { } } - public Pos getPosition() { - return this.position; - } - public void setPosition(Pos newPosition) { this.position = newPosition; } @@ -68,6 +67,20 @@ public class Tetromino { } public void draw() { + this.draw(true); + } + + public void draw(boolean withGhost) { + if(withGhost) { + this.playfield.removeBlock(this.ghostBlock); + Pos ghostPos = this.position; + while (!checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) { + ghostPos = ghostPos.sub(0, 1, 0); + } + Pos positionChange = this.position.sub(ghostPos); + getBlockPositions().forEach(pos -> this.instance.setBlock(pos.sub(positionChange), this.ghostBlock)); + } + getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock())); } @@ -150,6 +163,7 @@ public class Tetromino { for(Pos pos : newBlockPositions) { if(isPartOfTetromino(pos)) continue; + if(this.instance.getBlock(pos) == this.ghostBlock) continue; if(this.instance.getBlock(pos) != Block.AIR) return true; }