From 55a98b646458744315ca065cd047695c93704404 Mon Sep 17 00:00:00 2001 From: lars Date: Mon, 21 Oct 2024 19:22:31 +0200 Subject: [PATCH] changed background, added hold, show score --- .../game/stateless/types/tetris/Tetris.java | 27 ++++- .../types/tetris/game/Playfield.java | 13 +- .../types/tetris/game/TetrisGame.java | 112 ++++++++++++++---- 3 files changed, 122 insertions(+), 30 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 f873c62..fa4763a 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 @@ -66,7 +66,12 @@ class Tetris extends StatelessGame { System.out.println("D"); System.out.println(this.tetrisGame.moveRight()); } - case W -> System.out.println("W"); + case W -> { + System.out.println("W"); + while(this.tetrisGame.moveDown()) { + this.tetrisGame.addPoints(2); + } + } case mouseLeft -> { System.out.println("mouse left"); System.out.println(this.tetrisGame.rotate(false)); @@ -75,7 +80,10 @@ class Tetris extends StatelessGame { System.out.println("mouse right"); System.out.println(this.tetrisGame.rotate(true)); } - case space -> System.out.println("space"); + case space -> { + System.out.println("space"); + System.out.println(this.tetrisGame.switchHold()); + } } } @@ -91,7 +99,10 @@ class Tetris extends StatelessGame { @Override protected void onPlayerMove(@NotNull PlayerMoveEvent event) { - super.onPlayerMove(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(); @@ -135,7 +146,7 @@ class Tetris extends StatelessGame { if(previousPosition.y() < currentPosition.y()) pressedButton(Button.space); - event.setNewPosition(getSpawn().withView(event.getNewPosition())); +// event.setNewPosition(getSpawn().withView(event.getNewPosition())); } protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) { @@ -150,6 +161,14 @@ class Tetris extends StatelessGame { protected boolean onPlayerJoin(Player p) { 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.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 9f1e060..601f250 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 @@ -23,12 +23,17 @@ public class Playfield { return this.lowerLeftCorner.add(5, 21, 1); } + public Pos getHoldPosition() { + return this.lowerLeftCorner.add(-4, 19, 0); + } + public void generate() { AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); for(int x=0; x<12; x++) { - for(int y=0; y<21; y++) { - batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.STONE); + for(int y=0; y<22; y++) { + batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GLASS); + batch.setBlock(this.lowerLeftCorner.add(x, y, -1), Block.BLACK_CONCRETE); if(x==0 || x==11 || y==0) { batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE); @@ -43,7 +48,7 @@ public class Playfield { public int removeFullLines() { int removedLinesCounter = 0; - for(int y=1; y<21; y++) { + for(int y=1; y<22; y++) { boolean isFullLine = true; for(int x=1; x<11; x++) { if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false; @@ -58,7 +63,7 @@ public class Playfield { } private void removeFullLine(int positionY) { - for(int y=positionY; y<21; y++) { + for(int y=positionY; y<22; y++) { for(int x=1; x<11; x++) { Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1)); this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove); 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 3bd3414..e18b192 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 @@ -1,11 +1,16 @@ 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.TaskSchedule; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Random; public class TetrisGame { @@ -15,12 +20,15 @@ public class TetrisGame { private int lines = 0; private int score = 0; private boolean lost = false; + public boolean paused = true; public Tetromino currentTetromino; private Tetromino nextTetromino; private Tetromino holdTetromino; - private final Random random = new Random(); - + private final List tetrominoBag = new ArrayList<>(); + private boolean holdPossible = true; + 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)); @@ -32,13 +40,17 @@ public class TetrisGame { this.currentTetromino = startTetromino; this.nextTetromino = nextTetromino; + this.holdPosition = this.playfield.getHoldPosition(); this.tetrominoSpawnPosition = this.playfield.getTetrominoSpawnPosition(); + this.buildSidebar(); } public void start() { + this.paused = false; Scheduler scheduler = MinecraftServer.getSchedulerManager(); scheduler.submitTask(() -> { if(this.lost) return TaskSchedule.stop(); + if(this.paused) return TaskSchedule.tick(40/this.level); this.tick(); return TaskSchedule.tick(40/this.level); }); @@ -52,60 +64,111 @@ public class TetrisGame { } public void tick() { - if(this.lost) return; + if(this.lost || this.paused) return; if(!currentTetromino.moveDown()) { setActiveTetrominoDown(); } } + public void addPoints(int points) { + this.score += points; + this.updateSidebar(); + } + public boolean rotate(boolean clockwise) { - if(this.lost) return false; + if(this.lost || this.paused) return false; return this.currentTetromino.rotate(clockwise); } public boolean moveLeft() { - if(this.lost) return false; + if(this.lost || this.paused) return false; return this.currentTetromino.moveLeft(); } public boolean moveRight() { - if(this.lost) return false; + if(this.lost || this.paused) return false; return this.currentTetromino.moveRight(); } public boolean moveDown() { - if(this.lost) return false; + if(this.lost || this.paused) return false; if(!this.currentTetromino.moveDown()) { this.setActiveTetrominoDown(); return false; } this.score += 1; + this.updateSidebar(); + return true; + } + + public boolean switchHold() { + if(!holdPossible) return false; + if(this.lost || this.paused) return false; + + Tetromino newCurrentTetromino; + if(this.holdTetromino == null) { + newCurrentTetromino = this.nextTetromino; + this.nextTetromino = this.getNextTetromino(); + } else { + newCurrentTetromino = this.holdTetromino; + this.holdTetromino.remove(); + } + + this.currentTetromino.remove(); + this.holdTetromino = this.currentTetromino; + this.currentTetromino = newCurrentTetromino; + + this.currentTetromino.setPosition(this.tetrominoSpawnPosition); + this.currentTetromino.draw(); + if(!this.currentTetromino.moveDown()) loose(); + + this.holdTetromino.setPosition(this.holdPosition); + this.holdTetromino.draw(); + this.holdPossible = false; return true; } private Tetromino getNextTetromino() { - int randomNumber = random.nextInt(1, 7); - Tetromino.Shape nextShape; - - switch (randomNumber) { - case 2 -> nextShape = Tetromino.Shape.J; - case 3 -> nextShape = Tetromino.Shape.L; - case 4 -> nextShape = Tetromino.Shape.O; - case 5 -> nextShape = Tetromino.Shape.S; - case 6 -> nextShape = Tetromino.Shape.T; - case 7 -> nextShape = Tetromino.Shape.Z; - default -> nextShape = Tetromino.Shape.I; + if(this.tetrominoBag.isEmpty()) { + for(Tetromino.Shape shape : Tetromino.Shape.values()) { + this.tetrominoBag.add(new Tetromino(this.instance, shape)); + } + Collections.shuffle(this.tetrominoBag); } - return new Tetromino(this.instance, nextShape); + return this.tetrominoBag.removeFirst(); } private void loose() { this.lost = true; } + private void buildSidebar() { + this.sidebar.createLine(new Sidebar.ScoreboardLine( + "0", + Component.text("Score: "), + 0 + )); + this.sidebar.createLine(new Sidebar.ScoreboardLine( + "1", + Component.text("Lines: "), + 0 + )); + this.sidebar.createLine(new Sidebar.ScoreboardLine( + "2", + Component.text("Level: "), + 1 + )); + } + + private void updateSidebar() { + this.sidebar.updateLineScore("0", this.score); + this.sidebar.updateLineScore("1", this.lines); + this.sidebar.updateLineScore("2", this.level); + } + private void setActiveTetrominoDown() { currentTetromino = nextTetromino; nextTetromino = getNextTetromino(); @@ -117,19 +180,24 @@ public class TetrisGame { this.score += 40 * this.level; } case 2 -> { - this.lines += 3; + this.lines += 2; this.score += 100 * this.level; } case 3 -> { - this.lines += 5; + this.lines += 3; this.score += 300 * this.level; } case 4 -> { - this.lines += 8; + this.lines += 4; this.score += 1200 * this.level; } } + this.level = (int) Math.floor((double) this.lines / 10) + 1; + this.holdPossible = true; + + this.updateSidebar(); + currentTetromino.setPosition(this.tetrominoSpawnPosition); currentTetromino.draw(); if(!currentTetromino.moveDown()) {