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>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.18.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cz.jzitnik;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.mobs.EntityLogicProvider;
|
||||
import cz.jzitnik.game.threads.HealthRegenerationThread;
|
||||
import cz.jzitnik.game.threads.HungerDrainThread;
|
||||
import cz.jzitnik.game.threads.InputHandlerThread;
|
||||
@ -33,16 +34,18 @@ public class Main {
|
||||
Thread inputHandlerThread = new InputHandlerThread(game, terminal, screenRenderer, isRunning);
|
||||
Thread healingThread = new HealthRegenerationThread(game.getPlayer());
|
||||
Thread hungerDrainThread = new HungerDrainThread(game.getPlayer());
|
||||
EntityLogicProvider entityLogicProvider = new EntityLogicProvider();
|
||||
|
||||
// Start all threads
|
||||
healingThread.start();
|
||||
hungerDrainThread.start();
|
||||
inputHandlerThread.start();
|
||||
|
||||
|
||||
while (isRunning[0]) {
|
||||
if (game.getWindow() == Window.WORLD) {
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
entityLogicProvider.update(game);
|
||||
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
@ -1,16 +1,21 @@
|
||||
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.items.Item;
|
||||
import cz.jzitnik.game.items.ItemType;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
||||
import cz.jzitnik.game.mobs.EntitySpawnProvider;
|
||||
import cz.jzitnik.game.sprites.Breaking;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.game.ui.Furnace;
|
||||
import cz.jzitnik.game.blocks.Chest;
|
||||
import cz.jzitnik.game.blocks.Furnace;
|
||||
import cz.jzitnik.game.ui.Window;
|
||||
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.ScreenRenderer;
|
||||
import lombok.Getter;
|
||||
@ -28,12 +33,14 @@ public class Game {
|
||||
private boolean mining = false;
|
||||
@Setter
|
||||
private Window window = Window.WORLD;
|
||||
|
||||
//jsonignore
|
||||
private final GameStates gameStates = new GameStates(this);
|
||||
|
||||
private final Inventory inventory = new Inventory();
|
||||
|
||||
@JsonIgnore
|
||||
private final EntitySpawnProvider entitySpawnProvider = new EntitySpawnProvider();
|
||||
|
||||
@JsonIgnore
|
||||
private final GameStates gameStates = new GameStates(this);
|
||||
|
||||
public Game() {
|
||||
Generation.generateWorld(this);
|
||||
}
|
||||
@ -51,13 +58,13 @@ public class Game {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void movePlayerRight(ScreenRenderer screenRenderer) {
|
||||
public void movePlayerRight(ScreenRenderer screenRenderer, Terminal terminal) {
|
||||
if (window != Window.WORLD) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -67,16 +74,18 @@ public class Game {
|
||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||
screenRenderer.render(this);
|
||||
|
||||
entitySpawnProvider.update(this, terminal);
|
||||
|
||||
update(screenRenderer);
|
||||
}
|
||||
|
||||
public void movePlayerLeft(ScreenRenderer screenRenderer) {
|
||||
public void movePlayerLeft(ScreenRenderer screenRenderer, Terminal terminal) {
|
||||
if (window != Window.WORLD) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -86,6 +95,8 @@ public class Game {
|
||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||
screenRenderer.render(this);
|
||||
|
||||
entitySpawnProvider.update(this, terminal);
|
||||
|
||||
update(screenRenderer);
|
||||
}
|
||||
|
||||
@ -95,7 +106,7 @@ public class Game {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -106,20 +117,12 @@ public class Game {
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
Thread.sleep(400);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
int[] cords2 = getPlayerCords();
|
||||
|
||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
||||
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);
|
||||
}
|
||||
update(screenRenderer);
|
||||
}).start();
|
||||
}
|
||||
|
||||
@ -233,7 +236,7 @@ public class Game {
|
||||
}
|
||||
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]][cords2[0]].add(player.getPlayerBlock1());
|
||||
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"))) {
|
||||
RightClickHandler.handle(x, y, this, screenRenderer);
|
||||
RightClickHandlerProvider.handle(x, y, this, screenRenderer);
|
||||
screenRenderer.render(this);
|
||||
return;
|
||||
}
|
||||
@ -293,4 +296,8 @@ public class Game {
|
||||
inventory.setItemInhHandIndex(slot);
|
||||
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.ElementType;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface RegisterPlaceHandler {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EntityLogic {
|
||||
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.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.SpriteList;
|
||||
import org.jline.terminal.MouseEvent;
|
||||
@ -10,7 +14,8 @@ import org.jline.terminal.Terminal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Chest {
|
||||
@RightClickLogic
|
||||
public class Chest implements RightClickHandler {
|
||||
private static final int ROW_AMOUNT = 4;
|
||||
private static final int COLUMN_AMOUNT = 6;
|
||||
private static final int CELL_WIDTH = 50;
|
||||
@ -91,4 +96,9 @@ public class Chest {
|
||||
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.items.InventoryItem;
|
||||
import cz.jzitnik.game.items.Item;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
||||
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.SpriteList;
|
||||
import cz.jzitnik.tui.utils.Numbers;
|
||||
@ -15,7 +19,8 @@ import org.jline.terminal.Terminal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Furnace {
|
||||
@RightClickLogic
|
||||
public class Furnace implements RightClickHandler {
|
||||
private final Block block;
|
||||
private final InventoryItem[] items = new InventoryItem[2];
|
||||
private InventoryItem outputItem;
|
||||
@ -254,4 +259,9 @@ public class Furnace {
|
||||
|
||||
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;
|
||||
|
||||
import cz.jzitnik.game.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cz.jzitnik.game.crafting;
|
||||
|
||||
import cz.jzitnik.game.items.InventoryItem;
|
||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||
|
||||
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.items.ItemType;
|
||||
import cz.jzitnik.game.items.ToolVariant;
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
import cz.jzitnik.game.entities.items.ToolVariant;
|
||||
import cz.jzitnik.game.ui.Inventory;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -24,6 +25,7 @@ public class Block {
|
||||
private List<ToolVariant> toolVariants = new ArrayList<>();
|
||||
private List<Item> drops = new ArrayList<>();
|
||||
private Object data = null;
|
||||
private boolean isMob = false;
|
||||
|
||||
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
||||
this.blockId = blockId;
|
@ -1,4 +1,4 @@
|
||||
package cz.jzitnik.game;
|
||||
package cz.jzitnik.game.entities;
|
||||
|
||||
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;
|
||||
|
||||
public class GameStates {
|
@ -1,4 +1,4 @@
|
||||
package cz.jzitnik.game;
|
||||
package cz.jzitnik.game.entities;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
@ -1,4 +1,4 @@
|
||||
package cz.jzitnik.game.items;
|
||||
package cz.jzitnik.game.entities.items;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
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 lombok.AllArgsConstructor;
|
||||
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.Block;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.game.ui.Furnace;
|
||||
import cz.jzitnik.game.blocks.OakDoorData;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
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.Arrays;
|
||||
@ -93,6 +95,7 @@ public class ItemBlockSupplier {
|
||||
}
|
||||
public static Block oakDoor() {
|
||||
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)));
|
||||
return block;
|
||||
}
|
||||
@ -146,4 +149,16 @@ public class ItemBlockSupplier {
|
||||
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 {
|
||||
PICKAXE,
|
@ -1,4 +1,4 @@
|
||||
package cz.jzitnik.game.items;
|
||||
package cz.jzitnik.game.entities.items;
|
||||
|
||||
public enum ToolVariant {
|
||||
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;
|
||||
|
||||
import cz.jzitnik.game.Block;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.items.ItemType;
|
||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -18,13 +18,16 @@ public class Generation {
|
||||
|
||||
Block steveBlock = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||
steveBlock.setSpriteState(Steve.SteveState.FIRST);
|
||||
steveBlock.setGhost(true);
|
||||
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
||||
steveBlock2.setGhost(true);
|
||||
|
||||
int[] terrainHeight = generateTerrain();
|
||||
|
||||
game.getPlayer().setPlayerBlock1(steveBlock);
|
||||
game.getPlayer().setPlayerBlock2(steveBlock2);
|
||||
|
||||
int[] terrainHeight = generateTerrain();
|
||||
populateWorld(world, terrainHeight);
|
||||
plantTrees(world, terrainHeight);
|
||||
|
||||
|
@ -3,7 +3,6 @@ package cz.jzitnik.game.handlers.place;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import cz.jzitnik.game.annotations.RegisterPlaceHandler;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
public class PlaceHandler {
|
||||
@ -28,13 +27,13 @@ public class PlaceHandler {
|
||||
|
||||
private void registerHandlers() {
|
||||
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) {
|
||||
if (CustomPlaceHandler.class.isAssignableFrom(clazz)) {
|
||||
try {
|
||||
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);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -1,54 +1,14 @@
|
||||
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.annotations.RegisterPlaceHandler;
|
||||
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.tui.ScreenRenderer;
|
||||
|
||||
@RegisterPlaceHandler("oak_door")
|
||||
@PlaceHandler("oak_door")
|
||||
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
|
||||
public boolean place(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
|
@ -1,40 +1,8 @@
|
||||
package cz.jzitnik.game.handlers.rightclick;
|
||||
|
||||
import cz.jzitnik.game.Block;
|
||||
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 java.util.HashMap;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
public interface RightClickHandler {
|
||||
void onBlockRightClick(int x, int y, Game game, ScreenRenderer screenRenderer);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
import cz.jzitnik.game.items.Item;
|
||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cz.jzitnik.game.threads;
|
||||
|
||||
import cz.jzitnik.game.Player;
|
||||
import cz.jzitnik.game.entities.Player;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cz.jzitnik.game.threads;
|
||||
|
||||
import cz.jzitnik.game.Player;
|
||||
import cz.jzitnik.game.entities.Player;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
|
@ -1,6 +1,8 @@
|
||||
package cz.jzitnik.game.threads;
|
||||
|
||||
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.tui.MouseHandler;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
@ -54,11 +56,11 @@ public class InputHandlerThread extends Thread {
|
||||
switch (key) {
|
||||
case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> game.changeSlot(key - 49, screenRenderer);
|
||||
case 'a' -> {
|
||||
game.movePlayerLeft(screenRenderer);
|
||||
game.movePlayerLeft(screenRenderer, terminal);
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
case 'd' -> {
|
||||
game.movePlayerRight(screenRenderer);
|
||||
game.movePlayerRight(screenRenderer, terminal);
|
||||
screenRenderer.render(game);
|
||||
}
|
||||
case ' ' -> {
|
||||
|
@ -3,7 +3,7 @@ package cz.jzitnik.game.ui;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.crafting.CraftingRecipe;
|
||||
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.utils.SpriteCombiner;
|
||||
import cz.jzitnik.tui.SpriteList;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.items.InventoryItem;
|
||||
import cz.jzitnik.game.items.Item;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||
import cz.jzitnik.tui.SpriteList;
|
||||
import cz.jzitnik.tui.utils.Numbers;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import org.jline.terminal.MouseEvent;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.items.InventoryItem;
|
||||
import cz.jzitnik.game.entities.items.InventoryItem;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
|
@ -2,7 +2,7 @@ package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.crafting.CraftingRecipe;
|
||||
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.SpriteList;
|
||||
import cz.jzitnik.tui.utils.Numbers;
|
||||
|
@ -1,14 +1,13 @@
|
||||
package cz.jzitnik.tui;
|
||||
|
||||
import cz.jzitnik.game.Block;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.game.ui.Furnace;
|
||||
import cz.jzitnik.game.blocks.Chest;
|
||||
import cz.jzitnik.game.blocks.Furnace;
|
||||
import cz.jzitnik.game.ui.Healthbar;
|
||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
@ -16,10 +15,9 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class ScreenRenderer {
|
||||
private SpriteList spriteList;
|
||||
private Terminal terminal;
|
||||
private final SpriteList spriteList;
|
||||
private final Terminal terminal;
|
||||
|
||||
public ScreenRenderer(SpriteList spriteList, Terminal terminal) {
|
||||
this.spriteList = spriteList;
|
||||
@ -41,7 +39,7 @@ public class ScreenRenderer {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void render(Game game) {
|
||||
public synchronized void render(Game game) {
|
||||
var world = game.getWorld();
|
||||
StringBuilder main = new StringBuilder();
|
||||
main.append("\033[H\033[2J");
|
||||
|
Loading…
x
Reference in New Issue
Block a user