added ghost tetromino
This commit is contained in:
parent
f56023004a
commit
710838645f
@ -93,21 +93,20 @@ class Tetris extends StatelessGame {
|
||||
|
||||
@Override
|
||||
protected void onLoad(@NotNull CompletableFuture<Void> 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);
|
||||
|
@ -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<this.height; 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);
|
||||
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GRAY_CONCRETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
|
||||
batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE);
|
||||
batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE);
|
||||
batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE);
|
||||
|
||||
BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
|
||||
}
|
||||
|
||||
public int removeFullLines() {
|
||||
int removedLinesCounter = 0;
|
||||
for(int y=1; y<22; y++) {
|
||||
for(int y=1; y<this.height; 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;
|
||||
@ -62,8 +71,19 @@ public class Playfield {
|
||||
return removedLinesCounter;
|
||||
}
|
||||
|
||||
public void removeBlock(Block block) {
|
||||
for(int x=0; x<12; x++) {
|
||||
for(int y=0; y<this.height; y++) {
|
||||
if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)).equals(block)) {
|
||||
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void removeFullLine(int positionY) {
|
||||
for(int y=positionY; y<22; y++) {
|
||||
for(int y=positionY; y<this.height; 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);
|
||||
|
@ -25,23 +25,30 @@ public class TetrisGame {
|
||||
private Tetromino holdTetromino;
|
||||
private final List<Tetromino> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user