From 991e51bc1018d883d16b97ab75273f42de046f59 Mon Sep 17 00:00:00 2001 From: lars Date: Tue, 3 Feb 2026 19:08:05 +0100 Subject: [PATCH] fixed ground behavior for tetrominoes --- .../game/stateless/types/tetris/Tetris.java | 14 +-- .../types/tetris/game/TetrisGame.java | 98 +++++++++++++------ .../types/tetris/game/Tetromino.java | 13 +-- 3 files changed, 81 insertions(+), 44 deletions(-) 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 0f3336f..80318c8 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 @@ -82,11 +82,11 @@ class Tetris extends StatelessGame { private void onPlayerInteract(@NotNull PlayerUseItemEvent event) { event.setItemUseTime(0); - this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseRight); + this.tetrisGames.get(event.getPlayer()).pressedButtonRaw(TetrisGame.Button.mouseRight); } private void onPlayerAttack(@NotNull PlayerHandAnimationEvent event) { - this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseLeft); + this.tetrisGames.get(event.getPlayer()).pressedButtonRaw(TetrisGame.Button.mouseLeft); } private void onPlayerTick(PlayerTickEvent event) { @@ -100,11 +100,11 @@ class Tetris extends StatelessGame { if(player.getGameMode() == GameMode.SPECTATOR) return; - if(player.inputs().forward()) tetrisGame.pressedButton(TetrisGame.Button.W); - if(player.inputs().backward()) tetrisGame.pressedButton(TetrisGame.Button.S); - if(player.inputs().right()) tetrisGame.pressedButton(TetrisGame.Button.D); - if(player.inputs().left()) tetrisGame.pressedButton(TetrisGame.Button.A); - if(player.inputs().jump()) tetrisGame.pressedButton(TetrisGame.Button.space); + if(player.inputs().forward()) tetrisGame.pressedButtonRaw(TetrisGame.Button.W); + if(player.inputs().backward()) tetrisGame.pressedButtonRaw(TetrisGame.Button.S); + if(player.inputs().right()) tetrisGame.pressedButtonRaw(TetrisGame.Button.D); + if(player.inputs().left()) tetrisGame.pressedButtonRaw(TetrisGame.Button.A); + if(player.inputs().jump()) tetrisGame.pressedButtonRaw(TetrisGame.Button.space); } private void letPlayerLoose(Player player) { diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/TetrisGame.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/TetrisGame.java index 44dbe5f..5c3ff67 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/TetrisGame.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/tetris/game/TetrisGame.java @@ -2,10 +2,9 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import net.kyori.adventure.text.Component; -import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Pos; import net.minestom.server.scoreboard.Sidebar; -import net.minestom.server.timer.Scheduler; +import net.minestom.server.timer.Task; import net.minestom.server.timer.TaskSchedule; import java.util.*; @@ -23,6 +22,8 @@ public class TetrisGame { private final Map lastPresses = new HashMap<>(); private final List otherTetrisGames = new ArrayList<>(); private final Random random; + private Task tetrominoPlacementTask; + private Task hardTetrominoPlacementTask; public boolean lost = false; public boolean paused = true; public Tetromino currentTetromino; @@ -53,25 +54,28 @@ public class TetrisGame { } } - public void pressedButton(Button button) { - final int standardButtonDelay = 100; - final int buttonDebounce = 70; + public void pressedButtonRaw(Button button) { + final int standardButtonDelay = 95; + final int wsButtonDebounce = 70; if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis() - standardButtonDelay) return; - this.lastPresses.put(button, System.currentTimeMillis()); - if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis() + buttonDebounce); - if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis() - buttonDebounce); + switch(button) { + case W -> this.lastPresses.put(button, System.currentTimeMillis() + wsButtonDebounce); + case S -> this.lastPresses.put(button, System.currentTimeMillis() - wsButtonDebounce); + case mouseLeft, mouseRight -> this.lastPresses.put(button, 0L); + default -> this.lastPresses.put(button, System.currentTimeMillis()); + } if(this.lost || this.paused) return; switch(button) { - case A -> this.currentTetromino.moveLeft(); + case A -> this.moveLeft(); case S -> this.moveDown(); - case D -> this.currentTetromino.moveRight(); - case W -> this.hardDrop(); - case mouseLeft -> this.currentTetromino.rotate(false); - case mouseRight -> this.currentTetromino.rotate(true); + case D -> this.moveRight(); + case W -> this.hardDrop(true); + case mouseLeft -> this.rotate(false); + case mouseRight -> this.rotate(true); case space -> this.switchHold(); } } @@ -82,8 +86,7 @@ public class TetrisGame { public void start() { this.paused = false; - Scheduler scheduler = MinecraftServer.getSchedulerManager(); - scheduler.submitTask(() -> { + this.instance.scheduler().submitTask(() -> { if(this.lost) return TaskSchedule.stop(); int standardTickDelay = 40; if(this.isFast) standardTickDelay = 20; @@ -112,7 +115,7 @@ public class TetrisGame { public void tick() { if(this.lost || this.paused) return; if(!this.currentTetromino.moveDown()) { - this.setActiveTetrominoDown(); + this.scheduleTetrominoPlacement(); } } @@ -139,33 +142,42 @@ public class TetrisGame { this.lost = true; } - private boolean moveDown() { + private void moveDown() { if(!this.currentTetromino.moveDown()) { - this.setActiveTetrominoDown(); - return false; + this.scheduleTetrominoPlacement(); + return; } this.score += 1; this.updateInfo(); - return true; } - private boolean hardDrop() { + private void moveLeft() { + if(this.currentTetromino.moveLeft()) this.stopTetrominoPlacementTask(false); + } + + private void moveRight() { + if(this.currentTetromino.moveRight()) this.stopTetrominoPlacementTask(false); + } + + private void rotate(boolean clockwise) { + if(this.currentTetromino.rotate(clockwise)) this.stopTetrominoPlacementTask(false); + } + + private void hardDrop(boolean addScore) { if(!this.currentTetromino.moveDown()) { this.setActiveTetrominoDown(); - return false; + return; } - this.score += 2; - this.updateInfo(); - while(this.currentTetromino.moveDown()) { - this.score += 2; + do { + if(addScore) this.score += 2; this.updateInfo(); - } + } while(this.currentTetromino.moveDown()); this.setActiveTetrominoDown(); - return true; } - private boolean switchHold() { - if(!this.holdPossible) return false; + private void switchHold() { + if(!this.holdPossible) return; + this.stopTetrominoPlacementTask(true); Tetromino newCurrentTetromino; if(this.holdTetromino == null) { @@ -189,7 +201,6 @@ public class TetrisGame { this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0)); this.holdTetromino.drawAsEntities(); this.holdPossible = false; - return true; } private void updateNextTetrominoes() { @@ -235,7 +246,32 @@ public class TetrisGame { this.sidebar.updateLineScore("2", this.level); } + private void scheduleTetrominoPlacement() { + if(this.tetrominoPlacementTask == null || !this.tetrominoPlacementTask.isAlive()) + this.tetrominoPlacementTask = this.instance.scheduler().scheduleTask(() -> { + this.hardDrop(false); + return TaskSchedule.stop(); + }, TaskSchedule.millis(500)); + if(this.hardTetrominoPlacementTask == null || !this.hardTetrominoPlacementTask.isAlive()) + this.hardTetrominoPlacementTask = this.instance.scheduler().scheduleTask(() -> { + this.hardDrop(false); + return TaskSchedule.stop(); + }, TaskSchedule.millis(6000)); + } + + private void stopTetrominoPlacementTask(boolean resetHard) { + if(this.tetrominoPlacementTask != null) { + this.tetrominoPlacementTask.cancel(); + this.tetrominoPlacementTask = null; + } + if(resetHard && this.hardTetrominoPlacementTask != null) { + this.hardTetrominoPlacementTask.cancel(); + this.hardTetrominoPlacementTask = null; + } + } + private void setActiveTetrominoDown() { + this.stopTetrominoPlacementTask(true); this.currentTetromino.removeOwnEntities(); this.currentTetromino = this.nextTetrominoes.removeFirst(); this.currentTetromino.remove(); 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 943204a..69cbdb6 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 @@ -44,7 +44,7 @@ public class Tetromino { this.position = new Pos(newPosition.x(), newPosition.y(), newPosition.z()); } - public void rotate(boolean clockwise) { + public boolean rotate(boolean clockwise) { int[][] newShapeArray = this.getTurnedShapeArray(clockwise); Orientation newOrientation = this.orientation.rotated(clockwise); @@ -53,10 +53,11 @@ public class Tetromino { Pos candidate = new Pos(this.position.x() + k[0], this.position.y() + k[1], this.position.z()); if(this.checkCollisionAndMove(candidate, newShapeArray)) { this.orientation = newOrientation; - return; + return true; } } + return false; } public boolean moveDown() { @@ -64,14 +65,14 @@ public class Tetromino { return this.checkCollisionAndMove(newPosition, this.shapeArray); } - public void moveLeft() { + public boolean moveLeft() { Pos newPosition = this.position.sub(1, 0, 0); - this.checkCollisionAndMove(newPosition, this.shapeArray); + return this.checkCollisionAndMove(newPosition, this.shapeArray); } - public void moveRight() { + public boolean moveRight() { Pos newPosition = this.position.add(1, 0, 0); - this.checkCollisionAndMove(newPosition, this.shapeArray); + return this.checkCollisionAndMove(newPosition, this.shapeArray); } public void draw() {