changed background, added hold, show score

This commit is contained in:
Lars Neuhaus 2024-10-21 19:22:31 +02:00
parent 236d372746
commit 55a98b6464
3 changed files with 122 additions and 30 deletions

View File

@ -66,7 +66,12 @@ class Tetris extends StatelessGame {
System.out.println("D"); System.out.println("D");
System.out.println(this.tetrisGame.moveRight()); 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 -> { case mouseLeft -> {
System.out.println("mouse left"); System.out.println("mouse left");
System.out.println(this.tetrisGame.rotate(false)); System.out.println(this.tetrisGame.rotate(false));
@ -75,7 +80,10 @@ class Tetris extends StatelessGame {
System.out.println("mouse right"); System.out.println("mouse right");
System.out.println(this.tetrisGame.rotate(true)); 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 @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent event) { 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(); Player player = event.getPlayer();
Pos previousPosition = event.getPlayer().getPosition(); Pos previousPosition = event.getPlayer().getPosition();
@ -135,7 +146,7 @@ class Tetris extends StatelessGame {
if(previousPosition.y() < currentPosition.y()) pressedButton(Button.space); 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) { protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) {
@ -150,6 +161,14 @@ class Tetris extends StatelessGame {
protected boolean onPlayerJoin(Player p) { protected boolean onPlayerJoin(Player p) {
p.getInventory().setItemStack(0, ItemStack.builder(Material.BIRCH_BUTTON).customName(Component.text("Controller")).build()); p.getInventory().setItemStack(0, ItemStack.builder(Material.BIRCH_BUTTON).customName(Component.text("Controller")).build());
p.setSprinting(false); 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); return super.onPlayerJoin(p);
} }

View File

@ -23,12 +23,17 @@ public class Playfield {
return this.lowerLeftCorner.add(5, 21, 1); return this.lowerLeftCorner.add(5, 21, 1);
} }
public Pos getHoldPosition() {
return this.lowerLeftCorner.add(-4, 19, 0);
}
public void generate() { public void generate() {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x=0; x<12; x++) { for(int x=0; x<12; x++) {
for(int y=0; y<21; y++) { for(int y=0; y<22; y++) {
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.STONE); 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) { if(x==0 || x==11 || y==0) {
batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE); batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE);
@ -43,7 +48,7 @@ public class Playfield {
public int removeFullLines() { public int removeFullLines() {
int removedLinesCounter = 0; int removedLinesCounter = 0;
for(int y=1; y<21; y++) { for(int y=1; y<22; y++) {
boolean isFullLine = true; boolean isFullLine = true;
for(int x=1; x<11; x++) { for(int x=1; x<11; x++) {
if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false; 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) { 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++) { for(int x=1; x<11; x++) {
Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1)); Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1));
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove); this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove);

View File

@ -1,11 +1,16 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game; package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.scoreboard.Sidebar;
import net.minestom.server.timer.Scheduler; import net.minestom.server.timer.Scheduler;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random; import java.util.Random;
public class TetrisGame { public class TetrisGame {
@ -15,12 +20,15 @@ public class TetrisGame {
private int lines = 0; private int lines = 0;
private int score = 0; private int score = 0;
private boolean lost = false; private boolean lost = false;
public boolean paused = true;
public Tetromino currentTetromino; public Tetromino currentTetromino;
private Tetromino nextTetromino; private Tetromino nextTetromino;
private Tetromino holdTetromino; private Tetromino holdTetromino;
private final Random random = new Random(); private final List<Tetromino> tetrominoBag = new ArrayList<>();
private boolean holdPossible = true;
private final Pos holdPosition;
private final Pos tetrominoSpawnPosition; private final Pos tetrominoSpawnPosition;
public Sidebar sidebar = new Sidebar(Component.text("Info:"));
public TetrisGame(StatelessGame instance, Pos lowerLeftCorner) { public TetrisGame(StatelessGame instance, Pos lowerLeftCorner) {
this(instance, lowerLeftCorner, new Tetromino(instance, Tetromino.Shape.J), new Tetromino(instance, Tetromino.Shape.T)); 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.currentTetromino = startTetromino;
this.nextTetromino = nextTetromino; this.nextTetromino = nextTetromino;
this.holdPosition = this.playfield.getHoldPosition();
this.tetrominoSpawnPosition = this.playfield.getTetrominoSpawnPosition(); this.tetrominoSpawnPosition = this.playfield.getTetrominoSpawnPosition();
this.buildSidebar();
} }
public void start() { public void start() {
this.paused = false;
Scheduler scheduler = MinecraftServer.getSchedulerManager(); Scheduler scheduler = MinecraftServer.getSchedulerManager();
scheduler.submitTask(() -> { scheduler.submitTask(() -> {
if(this.lost) return TaskSchedule.stop(); if(this.lost) return TaskSchedule.stop();
if(this.paused) return TaskSchedule.tick(40/this.level);
this.tick(); this.tick();
return TaskSchedule.tick(40/this.level); return TaskSchedule.tick(40/this.level);
}); });
@ -52,60 +64,111 @@ public class TetrisGame {
} }
public void tick() { public void tick() {
if(this.lost) return; if(this.lost || this.paused) return;
if(!currentTetromino.moveDown()) { if(!currentTetromino.moveDown()) {
setActiveTetrominoDown(); setActiveTetrominoDown();
} }
} }
public void addPoints(int points) {
this.score += points;
this.updateSidebar();
}
public boolean rotate(boolean clockwise) { public boolean rotate(boolean clockwise) {
if(this.lost) return false; if(this.lost || this.paused) return false;
return this.currentTetromino.rotate(clockwise); return this.currentTetromino.rotate(clockwise);
} }
public boolean moveLeft() { public boolean moveLeft() {
if(this.lost) return false; if(this.lost || this.paused) return false;
return this.currentTetromino.moveLeft(); return this.currentTetromino.moveLeft();
} }
public boolean moveRight() { public boolean moveRight() {
if(this.lost) return false; if(this.lost || this.paused) return false;
return this.currentTetromino.moveRight(); return this.currentTetromino.moveRight();
} }
public boolean moveDown() { public boolean moveDown() {
if(this.lost) return false; if(this.lost || this.paused) return false;
if(!this.currentTetromino.moveDown()) { if(!this.currentTetromino.moveDown()) {
this.setActiveTetrominoDown(); this.setActiveTetrominoDown();
return false; return false;
} }
this.score += 1; 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; return true;
} }
private Tetromino getNextTetromino() { private Tetromino getNextTetromino() {
int randomNumber = random.nextInt(1, 7); if(this.tetrominoBag.isEmpty()) {
Tetromino.Shape nextShape; for(Tetromino.Shape shape : Tetromino.Shape.values()) {
this.tetrominoBag.add(new Tetromino(this.instance, shape));
switch (randomNumber) { }
case 2 -> nextShape = Tetromino.Shape.J; Collections.shuffle(this.tetrominoBag);
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;
} }
return new Tetromino(this.instance, nextShape); return this.tetrominoBag.removeFirst();
} }
private void loose() { private void loose() {
this.lost = true; 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() { private void setActiveTetrominoDown() {
currentTetromino = nextTetromino; currentTetromino = nextTetromino;
nextTetromino = getNextTetromino(); nextTetromino = getNextTetromino();
@ -117,19 +180,24 @@ public class TetrisGame {
this.score += 40 * this.level; this.score += 40 * this.level;
} }
case 2 -> { case 2 -> {
this.lines += 3; this.lines += 2;
this.score += 100 * this.level; this.score += 100 * this.level;
} }
case 3 -> { case 3 -> {
this.lines += 5; this.lines += 3;
this.score += 300 * this.level; this.score += 300 * this.level;
} }
case 4 -> { case 4 -> {
this.lines += 8; this.lines += 4;
this.score += 1200 * this.level; 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.setPosition(this.tetrominoSpawnPosition);
currentTetromino.draw(); currentTetromino.draw();
if(!currentTetromino.moveDown()) { if(!currentTetromino.moveDown()) {