added basic tetris classes
This commit is contained in:
parent
9d287f7c2f
commit
5acfe8f6af
@ -1,8 +1,8 @@
|
||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris;
|
||||
|
||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.TetrisGame;
|
||||
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
||||
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -10,8 +10,6 @@ import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.player.*;
|
||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -21,9 +19,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
class Tetris extends StatelessGame {
|
||||
private final boolean isFast;
|
||||
private final int width = 9;
|
||||
private final int height = 20;
|
||||
private TetrisGame tetrisGame;
|
||||
|
||||
private final Map<Button, Long> lastPresses = new HashMap<>();
|
||||
|
||||
@ -37,12 +33,10 @@ class Tetris extends StatelessGame {
|
||||
space
|
||||
}
|
||||
|
||||
public Tetris(boolean isFast) {
|
||||
public Tetris() {
|
||||
super(Dimension.THE_END.key, "Tetris", new FirstWinsScore());
|
||||
this.setGenerator(new CircularPlateTerrainGenerator(30).setPlateHeight(0));
|
||||
|
||||
this.isFast = isFast;
|
||||
|
||||
eventNode()
|
||||
.addListener(PlayerUseItemEvent.class, this::onPlayerInteract)
|
||||
.addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack);
|
||||
@ -51,6 +45,8 @@ class Tetris extends StatelessGame {
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
this.tetrisGame.generate();
|
||||
}
|
||||
|
||||
protected void pressedButton(Button button) {
|
||||
@ -74,25 +70,7 @@ class Tetris extends StatelessGame {
|
||||
|
||||
@Override
|
||||
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||
|
||||
for(int y = 45; y <= 45+height; y++) {
|
||||
for(int x = -(width/2)-1; x <= (width/2)+1; x++) {
|
||||
batch.setBlock(x, y, 0, Block.STONE);
|
||||
}
|
||||
}
|
||||
|
||||
for(int y = 45; y <= 45+height; y++) {
|
||||
batch.setBlock(-(width/2)-1, y, 1, Block.GRAY_CONCRETE);
|
||||
batch.setBlock((width/2)+1, y, 1, Block.GRAY_CONCRETE);
|
||||
}
|
||||
for(int x = -(width/2)-1; x <= (width/2)+1; x++) {
|
||||
batch.setBlock(x, 45, 1, Block.GRAY_CONCRETE);
|
||||
}
|
||||
|
||||
batch.setBlock((int) getSpawn().x(), (int) (getSpawn().y()-1), (int) getSpawn().z(), Block.STONE);
|
||||
|
||||
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
|
||||
this.tetrisGame = new TetrisGame(this, getSpawn().sub(6, 8, 15));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,10 +95,10 @@ class Tetris extends StatelessGame {
|
||||
double forwardAmount = movementVector.dot(forward);
|
||||
double leftAmount = movementVector.dot(left);
|
||||
|
||||
if (forwardAmount > 0.01) {
|
||||
if (forwardAmount > 0.018) {
|
||||
pressedButton(Button.W);
|
||||
releasedButton(Button.S);
|
||||
} else if (forwardAmount < -0.01) {
|
||||
} else if (forwardAmount < -0.018) {
|
||||
pressedButton(Button.S);
|
||||
releasedButton(Button.W);
|
||||
} else {
|
||||
@ -128,10 +106,10 @@ class Tetris extends StatelessGame {
|
||||
releasedButton(Button.S);
|
||||
}
|
||||
|
||||
if (leftAmount > 0.01) {
|
||||
if (leftAmount > 0.018) {
|
||||
pressedButton(Button.D);
|
||||
releasedButton(Button.A);
|
||||
} else if (leftAmount < -0.01) {
|
||||
} else if (leftAmount < -0.018) {
|
||||
pressedButton(Button.A);
|
||||
releasedButton(Button.D);
|
||||
} else {
|
||||
@ -155,6 +133,7 @@ class Tetris extends StatelessGame {
|
||||
@Override
|
||||
protected boolean onPlayerJoin(Player p) {
|
||||
p.getInventory().setItemStack(0, ItemStack.builder(Material.BIRCH_BUTTON).customName(Component.text("Controller")).build());
|
||||
p.setSprinting(false);
|
||||
return super.onPlayerJoin(p);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class TetrisFactory implements GameFactory {
|
||||
|
||||
@Override
|
||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
||||
return new Tetris(false).setParent(parent);
|
||||
return new Tetris().setParent(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,37 @@
|
||||
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.util.BatchUtil;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
public class Playfield {
|
||||
private final Pos lowerLeftCorner;
|
||||
|
||||
public Playfield(Pos lowerLeftCorner) {
|
||||
this.lowerLeftCorner = lowerLeftCorner;
|
||||
}
|
||||
|
||||
public Pos getPlayerSpawnPosition() {
|
||||
return lowerLeftCorner.add(6, 8, 15);
|
||||
}
|
||||
|
||||
public void generate(StatelessGame instance) {
|
||||
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||
|
||||
for(int x=0; x<12; x++) {
|
||||
for(int y=0; y<21; y++) {
|
||||
batch.setBlock(lowerLeftCorner.add(x, y, 0), Block.STONE);
|
||||
|
||||
if(x==0 || x==11 || y==0) {
|
||||
batch.setBlock(lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
|
||||
|
||||
BatchUtil.loadAndApplyBatch(batch, instance, () -> {});
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
||||
|
||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
|
||||
public class TetrisGame {
|
||||
private final StatelessGame instance;
|
||||
private final Playfield playfield;
|
||||
private int speed = 1;
|
||||
private int lines = 0;
|
||||
private Tetromino currentTetromino;
|
||||
private Tetromino nextTetromino;
|
||||
|
||||
public TetrisGame(StatelessGame instance, Pos lowerLeftCorner) {
|
||||
this(instance, lowerLeftCorner, new Tetromino(Tetromino.Shape.J), new Tetromino(Tetromino.Shape.T));
|
||||
}
|
||||
|
||||
public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino startTetromino, Tetromino nextTetromino) {
|
||||
this.playfield = new Playfield(lowerLeftCorner);
|
||||
this.currentTetromino = startTetromino;
|
||||
this.nextTetromino = nextTetromino;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
this.playfield.generate(this.instance);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
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.util.BatchUtil;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
public class Tetromino {
|
||||
private final Shape shape;
|
||||
|
||||
private int[][] shapeArray;
|
||||
|
||||
public enum Shape {
|
||||
I,
|
||||
J,
|
||||
L,
|
||||
O,
|
||||
S,
|
||||
T,
|
||||
Z
|
||||
}
|
||||
|
||||
public Tetromino(Shape shape) {
|
||||
this.shape = shape;
|
||||
|
||||
switch (this.shape) {
|
||||
case I -> shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
|
||||
case J -> shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}};
|
||||
case L -> shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}};
|
||||
case O -> shapeArray = new int[][]{{1,1}, {1,1}};
|
||||
case S -> shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}};
|
||||
case T -> shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}};
|
||||
case Z -> shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}};
|
||||
}
|
||||
}
|
||||
|
||||
private int[][] getTurnedShapeArray(boolean clockwise) {
|
||||
int iterations = 1;
|
||||
if(!clockwise) iterations = 3;
|
||||
|
||||
int arrayLength = this.shapeArray.length;
|
||||
int[][] returnArray = new int[arrayLength][arrayLength];
|
||||
|
||||
for(int k=0; k<iterations; k++) {
|
||||
for(int i=0; i<arrayLength; i++) {
|
||||
for(int j=0; j<arrayLength; j++) {
|
||||
returnArray[i][arrayLength-1-j] = this.shapeArray[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
public void draw(StatelessGame instance, Pos spawnPosition) {
|
||||
int arrayLength = this.shapeArray.length;
|
||||
|
||||
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||
|
||||
for(int x=-1; x<arrayLength-1; x++) {
|
||||
for(int y=-1; y<arrayLength-1; y++) {
|
||||
batch.setBlock(spawnPosition.add(x, y, 0), Block.WHITE_CONCRETE);
|
||||
}
|
||||
}
|
||||
|
||||
BatchUtil.loadAndApplyBatch(batch, instance, () -> {});
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user