forked from jzitnik/twodcraft
feat: Implemented pig spawning and pig walking
This commit is contained in:
parent
c50184983b
commit
940c3f3fe5
6
pom.xml
6
pom.xml
@ -40,6 +40,12 @@
|
|||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>31.1-jre</version>
|
<version>31.1-jre</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.18.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cz.jzitnik;
|
package cz.jzitnik;
|
||||||
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.mobs.EntityLogicProvider;
|
||||||
import cz.jzitnik.game.threads.HealthRegenerationThread;
|
import cz.jzitnik.game.threads.HealthRegenerationThread;
|
||||||
import cz.jzitnik.game.threads.HungerDrainThread;
|
import cz.jzitnik.game.threads.HungerDrainThread;
|
||||||
import cz.jzitnik.game.threads.InputHandlerThread;
|
import cz.jzitnik.game.threads.InputHandlerThread;
|
||||||
@ -33,16 +34,18 @@ public class Main {
|
|||||||
Thread inputHandlerThread = new InputHandlerThread(game, terminal, screenRenderer, isRunning);
|
Thread inputHandlerThread = new InputHandlerThread(game, terminal, screenRenderer, isRunning);
|
||||||
Thread healingThread = new HealthRegenerationThread(game.getPlayer());
|
Thread healingThread = new HealthRegenerationThread(game.getPlayer());
|
||||||
Thread hungerDrainThread = new HungerDrainThread(game.getPlayer());
|
Thread hungerDrainThread = new HungerDrainThread(game.getPlayer());
|
||||||
|
EntityLogicProvider entityLogicProvider = new EntityLogicProvider();
|
||||||
|
|
||||||
|
// Start all threads
|
||||||
healingThread.start();
|
healingThread.start();
|
||||||
hungerDrainThread.start();
|
hungerDrainThread.start();
|
||||||
inputHandlerThread.start();
|
inputHandlerThread.start();
|
||||||
|
|
||||||
|
|
||||||
while (isRunning[0]) {
|
while (isRunning[0]) {
|
||||||
if (game.getWindow() == Window.WORLD) {
|
if (game.getWindow() == Window.WORLD) {
|
||||||
screenRenderer.render(game);
|
screenRenderer.render(game);
|
||||||
}
|
}
|
||||||
|
entityLogicProvider.update(game);
|
||||||
|
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
package cz.jzitnik.game;
|
package cz.jzitnik.game;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.entities.GameStates;
|
||||||
|
import cz.jzitnik.game.entities.Player;
|
||||||
import cz.jzitnik.game.generation.Generation;
|
import cz.jzitnik.game.generation.Generation;
|
||||||
import cz.jzitnik.game.items.Item;
|
import cz.jzitnik.game.entities.items.Item;
|
||||||
import cz.jzitnik.game.items.ItemType;
|
import cz.jzitnik.game.entities.items.ItemType;
|
||||||
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
||||||
|
import cz.jzitnik.game.mobs.EntitySpawnProvider;
|
||||||
import cz.jzitnik.game.sprites.Breaking;
|
import cz.jzitnik.game.sprites.Breaking;
|
||||||
import cz.jzitnik.game.sprites.Steve;
|
import cz.jzitnik.game.sprites.Steve;
|
||||||
import cz.jzitnik.game.ui.Chest;
|
import cz.jzitnik.game.blocks.Chest;
|
||||||
import cz.jzitnik.game.ui.Furnace;
|
import cz.jzitnik.game.blocks.Furnace;
|
||||||
import cz.jzitnik.game.ui.Window;
|
import cz.jzitnik.game.ui.Window;
|
||||||
import cz.jzitnik.game.ui.Inventory;
|
import cz.jzitnik.game.ui.Inventory;
|
||||||
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
import cz.jzitnik.game.handlers.rightclick.RightClickHandlerProvider;
|
||||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -28,12 +33,14 @@ public class Game {
|
|||||||
private boolean mining = false;
|
private boolean mining = false;
|
||||||
@Setter
|
@Setter
|
||||||
private Window window = Window.WORLD;
|
private Window window = Window.WORLD;
|
||||||
|
|
||||||
//jsonignore
|
|
||||||
private final GameStates gameStates = new GameStates(this);
|
|
||||||
|
|
||||||
private final Inventory inventory = new Inventory();
|
private final Inventory inventory = new Inventory();
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private final EntitySpawnProvider entitySpawnProvider = new EntitySpawnProvider();
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private final GameStates gameStates = new GameStates(this);
|
||||||
|
|
||||||
public Game() {
|
public Game() {
|
||||||
Generation.generateWorld(this);
|
Generation.generateWorld(this);
|
||||||
}
|
}
|
||||||
@ -51,13 +58,13 @@ public class Game {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void movePlayerRight(ScreenRenderer screenRenderer) {
|
public void movePlayerRight(ScreenRenderer screenRenderer, Terminal terminal) {
|
||||||
if (window != Window.WORLD) {
|
if (window != Window.WORLD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int[] cords = getPlayerCords();
|
int[] cords = getPlayerCords();
|
||||||
|
|
||||||
if (world[cords[1]][cords[0] + 1].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] - 1][cords[0] + 1].stream().anyMatch(block -> !block.isGhost())) {
|
if (isSolid(world[cords[1]][cords[0] + 1]) || isSolid(world[cords[1] - 1][cords[0] + 1])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,16 +74,18 @@ public class Game {
|
|||||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
|
|
||||||
|
entitySpawnProvider.update(this, terminal);
|
||||||
|
|
||||||
update(screenRenderer);
|
update(screenRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void movePlayerLeft(ScreenRenderer screenRenderer) {
|
public void movePlayerLeft(ScreenRenderer screenRenderer, Terminal terminal) {
|
||||||
if (window != Window.WORLD) {
|
if (window != Window.WORLD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int[] cords = getPlayerCords();
|
int[] cords = getPlayerCords();
|
||||||
|
|
||||||
if (world[cords[1]][cords[0] - 1].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] - 1][cords[0] - 1].stream().anyMatch(block -> !block.isGhost())) {
|
if (isSolid(world[cords[1]][cords[0] - 1]) || isSolid(world[cords[1] - 1][cords[0] - 1])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +95,8 @@ public class Game {
|
|||||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
|
|
||||||
|
entitySpawnProvider.update(this, terminal);
|
||||||
|
|
||||||
update(screenRenderer);
|
update(screenRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +106,7 @@ public class Game {
|
|||||||
}
|
}
|
||||||
int[] cords = getPlayerCords();
|
int[] cords = getPlayerCords();
|
||||||
|
|
||||||
if (world[cords[1] - 2][cords[0]].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] + 1][cords[0]].stream().allMatch(Block::isGhost)) {
|
if (isSolid(world[cords[1] - 2][cords[0]]) || !isSolid(world[cords[1] + 1][cords[0]])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,20 +117,12 @@ public class Game {
|
|||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(400);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
int[] cords2 = getPlayerCords();
|
|
||||||
|
|
||||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
update(screenRenderer);
|
||||||
world[cords2[1] - 1][cords2[0]].remove(player.getPlayerBlock1());
|
|
||||||
world[cords2[1]][cords2[0]].add(player.getPlayerBlock1());
|
|
||||||
world[cords2[1] + 1][cords2[0]].add(player.getPlayerBlock2());
|
|
||||||
world[cords2[1]][cords2[0]].remove(player.getPlayerBlock2());
|
|
||||||
|
|
||||||
screenRenderer.render(this);
|
|
||||||
}
|
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +236,7 @@ public class Game {
|
|||||||
}
|
}
|
||||||
int[] cords2 = getPlayerCords();
|
int[] cords2 = getPlayerCords();
|
||||||
|
|
||||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
if (!isSolid(world[cords2[1] + 1][cords2[0]])) {
|
||||||
world[cords2[1] - 1][cords2[0]].remove(player.getPlayerBlock1());
|
world[cords2[1] - 1][cords2[0]].remove(player.getPlayerBlock1());
|
||||||
world[cords2[1]][cords2[0]].add(player.getPlayerBlock1());
|
world[cords2[1]][cords2[0]].add(player.getPlayerBlock1());
|
||||||
world[cords2[1] + 1][cords2[0]].add(player.getPlayerBlock2());
|
world[cords2[1] + 1][cords2[0]].add(player.getPlayerBlock2());
|
||||||
@ -268,7 +271,7 @@ public class Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!blocks.stream().allMatch(block -> block.getBlockId().equals("air"))) {
|
if (!blocks.stream().allMatch(block -> block.getBlockId().equals("air"))) {
|
||||||
RightClickHandler.handle(x, y, this, screenRenderer);
|
RightClickHandlerProvider.handle(x, y, this, screenRenderer);
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -293,4 +296,8 @@ public class Game {
|
|||||||
inventory.setItemInhHandIndex(slot);
|
inventory.setItemInhHandIndex(slot);
|
||||||
screenRenderer.render(this);
|
screenRenderer.render(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSolid(List<Block> blocks) {
|
||||||
|
return !blocks.stream().allMatch(Block::isGhost);
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,8 +5,8 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface RegisterPlaceHandler {
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface EntityLogic {
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
11
src/main/java/cz/jzitnik/game/annotations/EntitySpawn.java
Normal file
11
src/main/java/cz/jzitnik/game/annotations/EntitySpawn.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package cz.jzitnik.game.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface EntitySpawn {
|
||||||
|
}
|
13
src/main/java/cz/jzitnik/game/annotations/PlaceHandler.java
Normal file
13
src/main/java/cz/jzitnik/game/annotations/PlaceHandler.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package cz.jzitnik.game.annotations;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface PlaceHandler {
|
||||||
|
String value();
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package cz.jzitnik.game.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface RightClickLogic {
|
||||||
|
}
|
@ -1,7 +1,11 @@
|
|||||||
package cz.jzitnik.game.ui;
|
package cz.jzitnik.game.blocks;
|
||||||
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.annotations.RightClickLogic;
|
||||||
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
|
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
||||||
|
import cz.jzitnik.game.ui.InventoryClickHandler;
|
||||||
|
import cz.jzitnik.game.ui.Window;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
import cz.jzitnik.tui.SpriteList;
|
import cz.jzitnik.tui.SpriteList;
|
||||||
import org.jline.terminal.MouseEvent;
|
import org.jline.terminal.MouseEvent;
|
||||||
@ -10,7 +14,8 @@ import org.jline.terminal.Terminal;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Chest {
|
@RightClickLogic
|
||||||
|
public class Chest implements RightClickHandler {
|
||||||
private static final int ROW_AMOUNT = 4;
|
private static final int ROW_AMOUNT = 4;
|
||||||
private static final int COLUMN_AMOUNT = 6;
|
private static final int COLUMN_AMOUNT = 6;
|
||||||
private static final int CELL_WIDTH = 50;
|
private static final int CELL_WIDTH = 50;
|
||||||
@ -91,4 +96,9 @@ public class Chest {
|
|||||||
items[i] = null;
|
items[i] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockRightClick(int ignored, int ignored2, Game game, ScreenRenderer ignored4) {
|
||||||
|
game.setWindow(Window.CHEST);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,10 +1,14 @@
|
|||||||
package cz.jzitnik.game.ui;
|
package cz.jzitnik.game.blocks;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.annotations.RightClickLogic;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.game.items.Item;
|
import cz.jzitnik.game.entities.items.Item;
|
||||||
|
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
||||||
import cz.jzitnik.game.smelting.Smelting;
|
import cz.jzitnik.game.smelting.Smelting;
|
||||||
|
import cz.jzitnik.game.ui.InventoryClickHandler;
|
||||||
|
import cz.jzitnik.game.ui.Window;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
import cz.jzitnik.tui.SpriteList;
|
import cz.jzitnik.tui.SpriteList;
|
||||||
import cz.jzitnik.tui.utils.Numbers;
|
import cz.jzitnik.tui.utils.Numbers;
|
||||||
@ -15,7 +19,8 @@ import org.jline.terminal.Terminal;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Furnace {
|
@RightClickLogic
|
||||||
|
public class Furnace implements RightClickHandler {
|
||||||
private final Block block;
|
private final Block block;
|
||||||
private final InventoryItem[] items = new InventoryItem[2];
|
private final InventoryItem[] items = new InventoryItem[2];
|
||||||
private InventoryItem outputItem;
|
private InventoryItem outputItem;
|
||||||
@ -254,4 +259,9 @@ public class Furnace {
|
|||||||
|
|
||||||
setSmelting(false);
|
setSmelting(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockRightClick(int ignored, int ignored2, Game game, ScreenRenderer ignored3) {
|
||||||
|
game.setWindow(Window.FURNACE);
|
||||||
|
}
|
||||||
}
|
}
|
51
src/main/java/cz/jzitnik/game/blocks/OakDoorData.java
Normal file
51
src/main/java/cz/jzitnik/game/blocks/OakDoorData.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package cz.jzitnik.game.blocks;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.RightClickLogic;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
||||||
|
import cz.jzitnik.game.sprites.OakDoor;
|
||||||
|
|
||||||
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
|
|
||||||
|
@RightClickLogic
|
||||||
|
public class OakDoorData implements RightClickHandler {
|
||||||
|
private void change(Block door) {
|
||||||
|
door.setSpriteState(switch (door.getSpriteState().get()) {
|
||||||
|
case OakDoor.OakDoorState.TOP -> OakDoor.OakDoorState.TOPCLOSED;
|
||||||
|
case OakDoor.OakDoorState.BOTTOM -> OakDoor.OakDoorState.BOTTOMCLOSED;
|
||||||
|
case OakDoor.OakDoorState.TOPCLOSED -> OakDoor.OakDoorState.TOP;
|
||||||
|
case OakDoor.OakDoorState.BOTTOMCLOSED -> OakDoor.OakDoorState.BOTTOM;
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
||||||
|
});
|
||||||
|
|
||||||
|
door.setGhost(switch (door.getSpriteState().get()) {
|
||||||
|
case OakDoor.OakDoorState.TOP, OakDoor.OakDoorState.BOTTOM -> true;
|
||||||
|
case OakDoor.OakDoorState.TOPCLOSED, OakDoor.OakDoorState.BOTTOMCLOSED -> false;
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBlockRightClick(int x, int y, Game game, ScreenRenderer screenRenderer) {
|
||||||
|
var blocks = game.getWorld()[y][x];
|
||||||
|
var door = blocks.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
||||||
|
|
||||||
|
|
||||||
|
switch (door.getSpriteState().get()) {
|
||||||
|
case OakDoor.OakDoorState.TOP, OakDoor.OakDoorState.TOPCLOSED -> {
|
||||||
|
var blocks2 = game.getWorld()[y+1][x];
|
||||||
|
var door2 = blocks2.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
||||||
|
change(door2);
|
||||||
|
}
|
||||||
|
case OakDoor.OakDoorState.BOTTOM, OakDoor.OakDoorState.BOTTOMCLOSED -> {
|
||||||
|
var blocks2 = game.getWorld()[y-1][x];
|
||||||
|
var door2 = blocks2.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
||||||
|
change(door2);
|
||||||
|
}
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
change(door);
|
||||||
|
game.update(screenRenderer);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package cz.jzitnik.game.crafting;
|
package cz.jzitnik.game.crafting;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cz.jzitnik.game.crafting;
|
package cz.jzitnik.game.crafting;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package cz.jzitnik.game;
|
package cz.jzitnik.game.entities;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.Item;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.items.ItemType;
|
import cz.jzitnik.game.entities.items.Item;
|
||||||
import cz.jzitnik.game.items.ToolVariant;
|
import cz.jzitnik.game.entities.items.ItemType;
|
||||||
|
import cz.jzitnik.game.entities.items.ToolVariant;
|
||||||
import cz.jzitnik.game.ui.Inventory;
|
import cz.jzitnik.game.ui.Inventory;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -24,6 +25,7 @@ public class Block {
|
|||||||
private List<ToolVariant> toolVariants = new ArrayList<>();
|
private List<ToolVariant> toolVariants = new ArrayList<>();
|
||||||
private List<Item> drops = new ArrayList<>();
|
private List<Item> drops = new ArrayList<>();
|
||||||
private Object data = null;
|
private Object data = null;
|
||||||
|
private boolean isMob = false;
|
||||||
|
|
||||||
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
||||||
this.blockId = blockId;
|
this.blockId = blockId;
|
@ -1,4 +1,4 @@
|
|||||||
package cz.jzitnik.game;
|
package cz.jzitnik.game.entities;
|
||||||
|
|
||||||
import cz.jzitnik.game.handlers.place.PlaceHandler;
|
import cz.jzitnik.game.handlers.place.PlaceHandler;
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package cz.jzitnik.game;
|
package cz.jzitnik.game.entities;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.ui.CraftingTable;
|
import cz.jzitnik.game.ui.CraftingTable;
|
||||||
|
|
||||||
public class GameStates {
|
public class GameStates {
|
@ -1,4 +1,4 @@
|
|||||||
package cz.jzitnik.game;
|
package cz.jzitnik.game.entities;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
@ -1,4 +1,4 @@
|
|||||||
package cz.jzitnik.game.items;
|
package cz.jzitnik.game.entities.items;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
@ -1,6 +1,6 @@
|
|||||||
package cz.jzitnik.game.items;
|
package cz.jzitnik.game.entities.items;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
@ -1,9 +1,11 @@
|
|||||||
package cz.jzitnik.game.items;
|
package cz.jzitnik.game.entities.items;
|
||||||
|
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.blocks.OakDoorData;
|
||||||
import cz.jzitnik.game.ui.Chest;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.ui.Furnace;
|
import cz.jzitnik.game.blocks.Chest;
|
||||||
|
import cz.jzitnik.game.blocks.Furnace;
|
||||||
|
import cz.jzitnik.game.mobs.services.pig.PigData;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -93,6 +95,7 @@ public class ItemBlockSupplier {
|
|||||||
}
|
}
|
||||||
public static Block oakDoor() {
|
public static Block oakDoor() {
|
||||||
var block = new Block("oak_door", SpriteLoader.SPRITES.OAK_DOOR, 3, ItemType.AXE, new ArrayList<>());
|
var block = new Block("oak_door", SpriteLoader.SPRITES.OAK_DOOR, 3, ItemType.AXE, new ArrayList<>());
|
||||||
|
block.setData(new OakDoorData());
|
||||||
block.setDrops(List.of(Helper.oakDoor(block)));
|
block.setDrops(List.of(Helper.oakDoor(block)));
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -146,4 +149,16 @@ public class ItemBlockSupplier {
|
|||||||
return Helper.oakDoor(Blocks.oakDoor());
|
return Helper.oakDoor(Blocks.oakDoor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Mobs {
|
||||||
|
public static Block pig() {
|
||||||
|
// Yes, pig is a block. Cry about it.
|
||||||
|
var block = new Block("pig", SpriteLoader.SPRITES.PIG);
|
||||||
|
block.setMob(true);
|
||||||
|
block.setGhost(true);
|
||||||
|
block.setMineable(false);
|
||||||
|
block.setData(new PigData());
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cz.jzitnik.game.items;
|
package cz.jzitnik.game.entities.items;
|
||||||
|
|
||||||
public enum ItemType {
|
public enum ItemType {
|
||||||
PICKAXE,
|
PICKAXE,
|
@ -1,4 +1,4 @@
|
|||||||
package cz.jzitnik.game.items;
|
package cz.jzitnik.game.entities.items;
|
||||||
|
|
||||||
public enum ToolVariant {
|
public enum ToolVariant {
|
||||||
WOODEN,
|
WOODEN,
|
@ -1,12 +0,0 @@
|
|||||||
package cz.jzitnik.game.generation;
|
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CaveGenerator {
|
|
||||||
private static final int WIDTH = 512;
|
|
||||||
private static final int HEIGHT = 256;
|
|
||||||
|
|
||||||
public static void generateCaves(List<Block>[][] world, int[] terrainHeight) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
package cz.jzitnik.game.generation;
|
package cz.jzitnik.game.generation;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.SpriteLoader;
|
import cz.jzitnik.game.SpriteLoader;
|
||||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
import cz.jzitnik.game.items.ItemType;
|
import cz.jzitnik.game.entities.items.ItemType;
|
||||||
import cz.jzitnik.game.sprites.Steve;
|
import cz.jzitnik.game.sprites.Steve;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -18,13 +18,16 @@ public class Generation {
|
|||||||
|
|
||||||
Block steveBlock = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
Block steveBlock = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||||
steveBlock.setSpriteState(Steve.SteveState.FIRST);
|
steveBlock.setSpriteState(Steve.SteveState.FIRST);
|
||||||
|
steveBlock.setGhost(true);
|
||||||
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||||
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
||||||
|
steveBlock2.setGhost(true);
|
||||||
|
|
||||||
|
int[] terrainHeight = generateTerrain();
|
||||||
|
|
||||||
game.getPlayer().setPlayerBlock1(steveBlock);
|
game.getPlayer().setPlayerBlock1(steveBlock);
|
||||||
game.getPlayer().setPlayerBlock2(steveBlock2);
|
game.getPlayer().setPlayerBlock2(steveBlock2);
|
||||||
|
|
||||||
int[] terrainHeight = generateTerrain();
|
|
||||||
populateWorld(world, terrainHeight);
|
populateWorld(world, terrainHeight);
|
||||||
plantTrees(world, terrainHeight);
|
plantTrees(world, terrainHeight);
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package cz.jzitnik.game.handlers.place;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import cz.jzitnik.game.annotations.RegisterPlaceHandler;
|
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
public class PlaceHandler {
|
public class PlaceHandler {
|
||||||
@ -28,13 +27,13 @@ public class PlaceHandler {
|
|||||||
|
|
||||||
private void registerHandlers() {
|
private void registerHandlers() {
|
||||||
Reflections reflections = new Reflections("cz.jzitnik.game.handlers.place.handlers");
|
Reflections reflections = new Reflections("cz.jzitnik.game.handlers.place.handlers");
|
||||||
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(RegisterPlaceHandler.class);
|
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(cz.jzitnik.game.annotations.PlaceHandler.class);
|
||||||
|
|
||||||
for (Class<?> clazz : handlerClasses) {
|
for (Class<?> clazz : handlerClasses) {
|
||||||
if (CustomPlaceHandler.class.isAssignableFrom(clazz)) {
|
if (CustomPlaceHandler.class.isAssignableFrom(clazz)) {
|
||||||
try {
|
try {
|
||||||
CustomPlaceHandler handlerInstance = (CustomPlaceHandler) clazz.getDeclaredConstructor().newInstance();
|
CustomPlaceHandler handlerInstance = (CustomPlaceHandler) clazz.getDeclaredConstructor().newInstance();
|
||||||
RegisterPlaceHandler annotation = clazz.getAnnotation(RegisterPlaceHandler.class);
|
cz.jzitnik.game.annotations.PlaceHandler annotation = clazz.getAnnotation(cz.jzitnik.game.annotations.PlaceHandler.class);
|
||||||
placeHandlerList.put(annotation.value(), handlerInstance);
|
placeHandlerList.put(annotation.value(), handlerInstance);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -1,54 +1,14 @@
|
|||||||
package cz.jzitnik.game.handlers.place.handlers;
|
package cz.jzitnik.game.handlers.place.handlers;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.annotations.PlaceHandler;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.annotations.RegisterPlaceHandler;
|
|
||||||
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
||||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
import cz.jzitnik.game.sprites.OakDoor;
|
import cz.jzitnik.game.sprites.OakDoor;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
|
||||||
|
|
||||||
@RegisterPlaceHandler("oak_door")
|
@PlaceHandler("oak_door")
|
||||||
public class DoorPlaceHandler implements CustomPlaceHandler {
|
public class DoorPlaceHandler implements CustomPlaceHandler {
|
||||||
public static void rightClick(Game game, int x, int y, ScreenRenderer screenRenderer) {
|
|
||||||
var blocks = game.getWorld()[y][x];
|
|
||||||
var door = blocks.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
|
||||||
|
|
||||||
|
|
||||||
switch (door.getSpriteState().get()) {
|
|
||||||
case OakDoor.OakDoorState.TOP, OakDoor.OakDoorState.TOPCLOSED -> {
|
|
||||||
var blocks2 = game.getWorld()[y+1][x];
|
|
||||||
var door2 = blocks2.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
|
||||||
change(door2);
|
|
||||||
}
|
|
||||||
case OakDoor.OakDoorState.BOTTOM, OakDoor.OakDoorState.BOTTOMCLOSED -> {
|
|
||||||
var blocks2 = game.getWorld()[y-1][x];
|
|
||||||
var door2 = blocks2.stream().filter(block -> block.getBlockId().equals("oak_door")).toList().getFirst();
|
|
||||||
change(door2);
|
|
||||||
}
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
change(door);
|
|
||||||
game.update(screenRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void change(Block door) {
|
|
||||||
door.setSpriteState(switch (door.getSpriteState().get()) {
|
|
||||||
case OakDoor.OakDoorState.TOP -> OakDoor.OakDoorState.TOPCLOSED;
|
|
||||||
case OakDoor.OakDoorState.BOTTOM -> OakDoor.OakDoorState.BOTTOMCLOSED;
|
|
||||||
case OakDoor.OakDoorState.TOPCLOSED -> OakDoor.OakDoorState.TOP;
|
|
||||||
case OakDoor.OakDoorState.BOTTOMCLOSED -> OakDoor.OakDoorState.BOTTOM;
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
|
||||||
});
|
|
||||||
|
|
||||||
door.setGhost(switch (door.getSpriteState().get()) {
|
|
||||||
case OakDoor.OakDoorState.TOP, OakDoor.OakDoorState.BOTTOM -> true;
|
|
||||||
case OakDoor.OakDoorState.TOPCLOSED, OakDoor.OakDoorState.BOTTOMCLOSED -> false;
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: " + door.getSpriteState().get());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean place(Game game, int x, int y) {
|
public boolean place(Game game, int x, int y) {
|
||||||
var blocks = game.getWorld()[y][x];
|
var blocks = game.getWorld()[y][x];
|
||||||
|
@ -1,40 +1,8 @@
|
|||||||
package cz.jzitnik.game.handlers.rightclick;
|
package cz.jzitnik.game.handlers.rightclick;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.handlers.place.handlers.DoorPlaceHandler;
|
|
||||||
import cz.jzitnik.game.ui.Window;
|
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
|
|
||||||
import java.util.HashMap;
|
public interface RightClickHandler {
|
||||||
|
void onBlockRightClick(int x, int y, Game game, ScreenRenderer screenRenderer);
|
||||||
public class RightClickHandler {
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Function3<T, U> {
|
|
||||||
void apply(T t, U u);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(int x, int y, Game game, ScreenRenderer screenRenderer) {
|
|
||||||
if (game.isMining()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, Function3<Integer, Integer>> functionMap = new HashMap<>();
|
|
||||||
functionMap.put("crafting_table", game.getGameStates().craftingTable::render);
|
|
||||||
functionMap.put("chest", (Integer ignored, Integer ignored2) -> game.setWindow(Window.CHEST));
|
|
||||||
functionMap.put("furnace", (Integer ignored, Integer ignored2) -> game.setWindow(Window.FURNACE));
|
|
||||||
functionMap.put("oak_door", (Integer xx, Integer xy) -> DoorPlaceHandler.rightClick(game, xx, xy, screenRenderer));
|
|
||||||
|
|
||||||
game.getGameStates().clickX = x;
|
|
||||||
game.getGameStates().clickY = y;
|
|
||||||
|
|
||||||
var blocks = game.getWorld()[y][x];
|
|
||||||
for (Block block : blocks) {
|
|
||||||
if (functionMap.containsKey(block.getBlockId())) {
|
|
||||||
functionMap.get(block.getBlockId()).apply(x, y);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package cz.jzitnik.game.handlers.rightclick;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.annotations.RightClickLogic;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
|
|
||||||
|
public class RightClickHandlerProvider {
|
||||||
|
public static void handle(int x, int y, Game game, ScreenRenderer screenRenderer) {
|
||||||
|
if (game.isMining()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
game.getGameStates().clickX = x;
|
||||||
|
game.getGameStates().clickY = y;
|
||||||
|
|
||||||
|
var blocks = game.getWorld()[y][x];
|
||||||
|
for (Block block : blocks) {
|
||||||
|
if (block.getBlockId().equalsIgnoreCase("crafting_table")) {
|
||||||
|
game.getGameStates().craftingTable.render(x, y);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.getData() != null && block.getData().getClass().isAnnotationPresent(RightClickLogic.class) && block.getData() instanceof RightClickHandler handlerClass) {
|
||||||
|
handlerClass.onBlockRightClick(x, y, game, screenRenderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package cz.jzitnik.game.mobs;
|
||||||
|
|
||||||
|
public interface EntityLogicInterface {
|
||||||
|
void nextIteration(EntityLogicProvider.EntityLogicMobDTO entityLogicMobDTO);
|
||||||
|
}
|
82
src/main/java/cz/jzitnik/game/mobs/EntityLogicProvider.java
Normal file
82
src/main/java/cz/jzitnik/game/mobs/EntityLogicProvider.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package cz.jzitnik.game.mobs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.EntityLogic;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
public class EntityLogicProvider {
|
||||||
|
private static final int CHUNK_SIZE = 20;
|
||||||
|
private final HashMap<String, EntityLogicInterface> logicList = new HashMap<>();
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public static class EntityLogicMobDTO {
|
||||||
|
private Game game;
|
||||||
|
private Block mob;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Game game) {
|
||||||
|
int[] playerLocation = game.getPlayerCords();
|
||||||
|
int playerX = playerLocation[0];
|
||||||
|
int playerY = playerLocation[1];
|
||||||
|
|
||||||
|
int startX = Math.max(0, playerX - CHUNK_SIZE);
|
||||||
|
int startY = Math.max(0, playerY - CHUNK_SIZE);
|
||||||
|
int endX = Math.min(game.getWorld()[0].length, playerX + CHUNK_SIZE);
|
||||||
|
int endY = Math.min(game.getWorld().length, playerY + CHUNK_SIZE);
|
||||||
|
|
||||||
|
List<EntityLogicMobDTO> mobs = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int y = startY; y <= endY; y++) {
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
int finalX = x;
|
||||||
|
int finalY = y;
|
||||||
|
List<EntityLogicMobDTO> blockMobs = game.getWorld()[y][x].stream().filter(Block::isMob).map(mob -> new EntityLogicMobDTO(game, mob, finalX, finalY)).toList();
|
||||||
|
mobs.addAll(blockMobs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EntityLogicMobDTO entityLogicMobDTO : mobs) {
|
||||||
|
run(entityLogicMobDTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void run(EntityLogicMobDTO entityLogicMobDTO) {
|
||||||
|
if (!logicList.containsKey(entityLogicMobDTO.getMob().getBlockId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logicList.get(entityLogicMobDTO.getMob().getBlockId()).nextIteration(entityLogicMobDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLogicProvider() {
|
||||||
|
registerHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerHandlers() {
|
||||||
|
Reflections reflections = new Reflections("cz.jzitnik.game.mobs.services");
|
||||||
|
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(EntityLogic.class);
|
||||||
|
|
||||||
|
for (Class<?> clazz : handlerClasses) {
|
||||||
|
if (EntityLogicInterface.class.isAssignableFrom(clazz)) {
|
||||||
|
try {
|
||||||
|
EntityLogicInterface instance = (EntityLogicInterface) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
EntityLogic annotation = clazz.getAnnotation(EntityLogic.class);
|
||||||
|
logicList.put(annotation.value(), instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package cz.jzitnik.game.mobs;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import org.jline.terminal.Terminal;
|
||||||
|
|
||||||
|
public interface EntitySpawnInterface {
|
||||||
|
void spawn(int playerX, int playerY, Game game, Terminal terminal);
|
||||||
|
}
|
57
src/main/java/cz/jzitnik/game/mobs/EntitySpawnProvider.java
Normal file
57
src/main/java/cz/jzitnik/game/mobs/EntitySpawnProvider.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package cz.jzitnik.game.mobs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.EntitySpawn;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.jline.terminal.Terminal;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
public class EntitySpawnProvider {
|
||||||
|
private final List<EntitySpawnInterface> spawnList = new ArrayList<>();
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public static class EntityLogicMobDTO {
|
||||||
|
private Game game;
|
||||||
|
private Block mob;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Game game, Terminal terminal) {
|
||||||
|
int[] playerLocation = game.getPlayerCords();
|
||||||
|
int playerX = playerLocation[0];
|
||||||
|
int playerY = playerLocation[1];
|
||||||
|
|
||||||
|
for (EntitySpawnInterface entitySpawnInterface: spawnList) {
|
||||||
|
|
||||||
|
entitySpawnInterface.spawn(playerX, playerY, game, terminal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntitySpawnProvider() {
|
||||||
|
registerHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerHandlers() {
|
||||||
|
Reflections reflections = new Reflections("cz.jzitnik.game.mobs.services");
|
||||||
|
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(EntitySpawn.class);
|
||||||
|
|
||||||
|
for (Class<?> clazz : handlerClasses) {
|
||||||
|
if (EntitySpawnInterface.class.isAssignableFrom(clazz)) {
|
||||||
|
try {
|
||||||
|
EntitySpawnInterface instance = (EntitySpawnInterface) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
spawnList.add(instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
src/main/java/cz/jzitnik/game/mobs/services/pig/PigData.java
Normal file
12
src/main/java/cz/jzitnik/game/mobs/services/pig/PigData.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package cz.jzitnik.game.mobs.services.pig;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PigData {
|
||||||
|
private int lastDirection = 1; // 1 = right, -1 = left
|
||||||
|
private int movementCooldown = 0;
|
||||||
|
private int jumpAttempts = 0;
|
||||||
|
}
|
177
src/main/java/cz/jzitnik/game/mobs/services/pig/PigLogic.java
Normal file
177
src/main/java/cz/jzitnik/game/mobs/services/pig/PigLogic.java
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package cz.jzitnik.game.mobs.services.pig;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.EntityLogic;
|
||||||
|
import cz.jzitnik.game.annotations.EntitySpawn;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
|
import cz.jzitnik.game.mobs.EntityLogicInterface;
|
||||||
|
import cz.jzitnik.game.mobs.EntityLogicProvider;
|
||||||
|
import cz.jzitnik.game.mobs.EntitySpawnInterface;
|
||||||
|
import cz.jzitnik.game.sprites.Pig;
|
||||||
|
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||||
|
import org.jline.terminal.Terminal;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@EntitySpawn
|
||||||
|
@EntityLogic("pig")
|
||||||
|
public class PigLogic implements EntityLogicInterface, EntitySpawnInterface {
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nextIteration(EntityLogicProvider.EntityLogicMobDTO entityLogicMobDTO) {
|
||||||
|
int pigX = entityLogicMobDTO.getX();
|
||||||
|
int pigY = entityLogicMobDTO.getY();
|
||||||
|
var game = entityLogicMobDTO.getGame();
|
||||||
|
var pig = entityLogicMobDTO.getMob();
|
||||||
|
var world = game.getWorld();
|
||||||
|
var pigData = (PigData) pig.getData();
|
||||||
|
|
||||||
|
boolean updated = false;
|
||||||
|
int newPigX = pigX;
|
||||||
|
int newPigY = pigY;
|
||||||
|
|
||||||
|
// Reduce movement cooldown
|
||||||
|
if (pigData.getMovementCooldown() > 0) {
|
||||||
|
pigData.setMovementCooldown(pigData.getMovementCooldown() - 1);
|
||||||
|
return; // Skip movement this iteration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine movement direction
|
||||||
|
int direction = pigData.getLastDirection();
|
||||||
|
if (random.nextInt(10) < 3) { // 30% chance to change direction
|
||||||
|
direction = -direction;
|
||||||
|
}
|
||||||
|
pigData.setLastDirection(direction);
|
||||||
|
|
||||||
|
// Update sprite direction
|
||||||
|
if (direction == 1) {
|
||||||
|
pig.setSpriteState(Pig.PigState.RIGHT);
|
||||||
|
} else {
|
||||||
|
pig.setSpriteState(Pig.PigState.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Block> blocksAhead = world[pigY][pigX + direction];
|
||||||
|
if (!game.isSolid(blocksAhead)) {
|
||||||
|
world[pigY][pigX].remove(pig);
|
||||||
|
world[pigY][pigX + direction].add(pig);
|
||||||
|
newPigX = pigX + direction;
|
||||||
|
updated = true;
|
||||||
|
pigData.setJumpAttempts(0); // Reset jump attempts when moving forward
|
||||||
|
} else {
|
||||||
|
List<Block> blocksAboveAhead = world[pigY - 1][pigX + direction];
|
||||||
|
List<Block> blocksTwoAboveAhead = world[pigY - 2][pigX + direction];
|
||||||
|
|
||||||
|
// Jump if there is only one block height obstacle and limit jump attempts
|
||||||
|
if (!game.isSolid(blocksAboveAhead) && game.isSolid(blocksAhead) && !game.isSolid(blocksTwoAboveAhead)) {
|
||||||
|
if (pigData.getJumpAttempts() < 2) { // Limit jumping attempts to prevent infinite jumping
|
||||||
|
world[pigY][pigX].remove(pig);
|
||||||
|
world[pigY - 1][pigX + direction].add(pig);
|
||||||
|
newPigX = pigX + direction;
|
||||||
|
newPigY = pigY - 1;
|
||||||
|
updated = true;
|
||||||
|
pigData.setJumpAttempts(pigData.getJumpAttempts() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Falling logic (avoid long falls)
|
||||||
|
while (updated) {
|
||||||
|
if (!game.isSolid(world[newPigY + 1][newPigX])) {
|
||||||
|
if (newPigY - pigY < 3) { // Only fall if it's at most 2 blocks drop
|
||||||
|
world[newPigY][newPigX].remove(pig);
|
||||||
|
world[newPigY + 1][newPigX].add(pig);
|
||||||
|
newPigY++;
|
||||||
|
} else {
|
||||||
|
updated = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply movement cooldown to slow down movement
|
||||||
|
pigData.setMovementCooldown(random.nextInt(3) + 1); // 1-3 iterations cooldown
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn(int playerX, int playerY, Game game, Terminal terminal) {
|
||||||
|
// Cordinates where player can see
|
||||||
|
int[] data = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminal.getHeight(), terminal.getWidth(), game.getWorld()[0].length, game.getWorld().length);
|
||||||
|
var world = game.getWorld();
|
||||||
|
int startX = data[0];
|
||||||
|
int endX = data[1];
|
||||||
|
|
||||||
|
// Left side
|
||||||
|
int lstartX = startX - 20;
|
||||||
|
int lendX = startX - 5;
|
||||||
|
int lstartY = playerY - 15;
|
||||||
|
int lendY = playerY + 15;
|
||||||
|
|
||||||
|
if (countPrasata(lstartX, lendX, lstartY, lendY, game) < 3 && random.nextInt(100) < 2) {
|
||||||
|
var spawnLocations = pigCanSpawn(lstartX, lendX, playerY, game);
|
||||||
|
if (!spawnLocations.isEmpty()) {
|
||||||
|
System.out.println(spawnLocations.size());
|
||||||
|
for (int i = 0; i < Math.min(4, spawnLocations.size()); i++) {
|
||||||
|
var randomLocation = getRandomEntry(spawnLocations);
|
||||||
|
int x = randomLocation.getKey();
|
||||||
|
int y = randomLocation.getValue();
|
||||||
|
|
||||||
|
world[y][x].add(ItemBlockSupplier.Mobs.pig());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right side
|
||||||
|
int rstartX = endX + 5;
|
||||||
|
int rendX = endX + 20;
|
||||||
|
int rstartY = playerY - 15;
|
||||||
|
int rendY = playerY + 15;
|
||||||
|
|
||||||
|
if (countPrasata(rstartX, rendX, rstartY, rendY, game) < 3 && random.nextInt(100) < 2) {
|
||||||
|
var spawnLocations = pigCanSpawn(rstartX, rendX, playerY, game);
|
||||||
|
if (!spawnLocations.isEmpty()) {
|
||||||
|
System.out.println(spawnLocations.size());
|
||||||
|
for (int i = 0; i < Math.min(4, spawnLocations.size()); i++) {
|
||||||
|
var randomLocation = getRandomEntry(spawnLocations);
|
||||||
|
int x = randomLocation.getKey();
|
||||||
|
int y = randomLocation.getValue();
|
||||||
|
|
||||||
|
world[y][x].add(ItemBlockSupplier.Mobs.pig());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <K, V> Map.Entry<K, V> getRandomEntry(HashMap<K, V> map) {
|
||||||
|
List<Map.Entry<K, V>> entryList = new ArrayList<>(map.entrySet());
|
||||||
|
Random random = new Random();
|
||||||
|
return entryList.get(random.nextInt(entryList.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<Integer, Integer> pigCanSpawn(int startX, int endX, int playerY, Game game) {
|
||||||
|
var map = new HashMap<Integer, Integer>();
|
||||||
|
var world = game.getWorld();
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
for (int y = Math.max(0, playerY - 30); y < Math.min(world.length, playerY + 30); y++) {
|
||||||
|
if (world[y][x].stream().anyMatch(i -> i.getBlockId().equals("grass"))) {
|
||||||
|
map.put(x, y - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long countPrasata(int startX, int endX, int startY, int endY, Game game) {
|
||||||
|
long pigAmount = 0;
|
||||||
|
for (int y = startY; y <= endY; y++) {
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
pigAmount += game.getWorld()[y][x].stream().filter(i -> i.getBlockId().equals("pig")).count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pigAmount;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package cz.jzitnik.game.smelting;
|
package cz.jzitnik.game.smelting;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.Item;
|
import cz.jzitnik.game.entities.items.Item;
|
||||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cz.jzitnik.game.threads;
|
package cz.jzitnik.game.threads;
|
||||||
|
|
||||||
import cz.jzitnik.game.Player;
|
import cz.jzitnik.game.entities.Player;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cz.jzitnik.game.threads;
|
package cz.jzitnik.game.threads;
|
||||||
|
|
||||||
import cz.jzitnik.game.Player;
|
import cz.jzitnik.game.entities.Player;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package cz.jzitnik.game.threads;
|
package cz.jzitnik.game.threads;
|
||||||
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.blocks.Chest;
|
||||||
|
import cz.jzitnik.game.blocks.Furnace;
|
||||||
import cz.jzitnik.game.ui.*;
|
import cz.jzitnik.game.ui.*;
|
||||||
import cz.jzitnik.tui.MouseHandler;
|
import cz.jzitnik.tui.MouseHandler;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
@ -54,11 +56,11 @@ public class InputHandlerThread extends Thread {
|
|||||||
switch (key) {
|
switch (key) {
|
||||||
case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer);
|
case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer);
|
||||||
case 'a' -> {
|
case 'a' -> {
|
||||||
game.movePlayerLeft(screenRenderer);
|
game.movePlayerLeft(screenRenderer, terminal);
|
||||||
screenRenderer.render(game);
|
screenRenderer.render(game);
|
||||||
}
|
}
|
||||||
case 'd' -> {
|
case 'd' -> {
|
||||||
game.movePlayerRight(screenRenderer);
|
game.movePlayerRight(screenRenderer, terminal);
|
||||||
screenRenderer.render(game);
|
screenRenderer.render(game);
|
||||||
}
|
}
|
||||||
case ' ' -> {
|
case ' ' -> {
|
||||||
|
@ -3,7 +3,7 @@ package cz.jzitnik.game.ui;
|
|||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.crafting.CraftingRecipe;
|
import cz.jzitnik.game.crafting.CraftingRecipe;
|
||||||
import cz.jzitnik.game.crafting.CraftingRecipeList;
|
import cz.jzitnik.game.crafting.CraftingRecipeList;
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||||
import cz.jzitnik.tui.SpriteList;
|
import cz.jzitnik.tui.SpriteList;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cz.jzitnik.game.ui;
|
package cz.jzitnik.game.ui;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.game.items.Item;
|
import cz.jzitnik.game.entities.items.Item;
|
||||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||||
import cz.jzitnik.tui.SpriteList;
|
import cz.jzitnik.tui.SpriteList;
|
||||||
import cz.jzitnik.tui.utils.Numbers;
|
import cz.jzitnik.tui.utils.Numbers;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cz.jzitnik.game.ui;
|
package cz.jzitnik.game.ui;
|
||||||
|
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.tui.ScreenRenderer;
|
import cz.jzitnik.tui.ScreenRenderer;
|
||||||
import org.jline.terminal.MouseEvent;
|
import org.jline.terminal.MouseEvent;
|
||||||
import org.jline.terminal.Terminal;
|
import org.jline.terminal.Terminal;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cz.jzitnik.game.ui;
|
package cz.jzitnik.game.ui;
|
||||||
|
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package cz.jzitnik.game.ui;
|
|||||||
|
|
||||||
import cz.jzitnik.game.crafting.CraftingRecipe;
|
import cz.jzitnik.game.crafting.CraftingRecipe;
|
||||||
import cz.jzitnik.game.crafting.CraftingRecipeList;
|
import cz.jzitnik.game.crafting.CraftingRecipeList;
|
||||||
import cz.jzitnik.game.items.InventoryItem;
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||||
import cz.jzitnik.tui.SpriteList;
|
import cz.jzitnik.tui.SpriteList;
|
||||||
import cz.jzitnik.tui.utils.Numbers;
|
import cz.jzitnik.tui.utils.Numbers;
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package cz.jzitnik.tui;
|
package cz.jzitnik.tui;
|
||||||
|
|
||||||
import cz.jzitnik.game.Block;
|
import cz.jzitnik.game.entities.Block;
|
||||||
import cz.jzitnik.game.Game;
|
import cz.jzitnik.game.Game;
|
||||||
import cz.jzitnik.game.sprites.Steve;
|
import cz.jzitnik.game.sprites.Steve;
|
||||||
import cz.jzitnik.game.ui.Chest;
|
import cz.jzitnik.game.blocks.Chest;
|
||||||
import cz.jzitnik.game.ui.Furnace;
|
import cz.jzitnik.game.blocks.Furnace;
|
||||||
import cz.jzitnik.game.ui.Healthbar;
|
import cz.jzitnik.game.ui.Healthbar;
|
||||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.jline.terminal.Terminal;
|
import org.jline.terminal.Terminal;
|
||||||
|
|
||||||
@ -16,10 +15,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class ScreenRenderer {
|
public class ScreenRenderer {
|
||||||
private SpriteList spriteList;
|
private final SpriteList spriteList;
|
||||||
private Terminal terminal;
|
private final Terminal terminal;
|
||||||
|
|
||||||
public ScreenRenderer(SpriteList spriteList, Terminal terminal) {
|
public ScreenRenderer(SpriteList spriteList, Terminal terminal) {
|
||||||
this.spriteList = spriteList;
|
this.spriteList = spriteList;
|
||||||
@ -41,7 +39,7 @@ public class ScreenRenderer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Game game) {
|
public synchronized void render(Game game) {
|
||||||
var world = game.getWorld();
|
var world = game.getWorld();
|
||||||
StringBuilder main = new StringBuilder();
|
StringBuilder main = new StringBuilder();
|
||||||
main.append("\033[H\033[2J");
|
main.append("\033[H\033[2J");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user