feat: Implemented healthbar
This commit is contained in:
7
src/main/java/cz/jzitnik/game/Dependencies.java
Normal file
7
src/main/java/cz/jzitnik/game/Dependencies.java
Normal file
@ -0,0 +1,7 @@
|
||||
package cz.jzitnik.game;
|
||||
|
||||
import cz.jzitnik.game.handlers.place.PlaceHandler;
|
||||
|
||||
public class Dependencies {
|
||||
public PlaceHandler placeHandler = new PlaceHandler();
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
package cz.jzitnik.game;
|
||||
|
||||
import cz.jzitnik.game.generation.Generation;
|
||||
import cz.jzitnik.game.items.Item;
|
||||
import cz.jzitnik.game.items.ItemType;
|
||||
import cz.jzitnik.game.handlers.place.CustomPlaceHandler;
|
||||
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.ui.Window;
|
||||
import cz.jzitnik.game.ui.Inventory;
|
||||
import cz.jzitnik.tui.RightClickHandler;
|
||||
import cz.jzitnik.game.handlers.rightclick.RightClickHandler;
|
||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import lombok.Getter;
|
||||
@ -20,11 +22,9 @@ import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class Game {
|
||||
private List<Block>[][] world = new ArrayList[256][512];
|
||||
@Setter
|
||||
private Block player;
|
||||
@Setter
|
||||
private Block player2;
|
||||
@SuppressWarnings("unchecked")
|
||||
private final List<Block>[][] world = (List<Block>[][]) new ArrayList[256][512];
|
||||
private final Player player = new Player();
|
||||
private boolean mining = false;
|
||||
@Setter
|
||||
private Window window = Window.WORLD;
|
||||
@ -61,10 +61,10 @@ public class Game {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1]][cords[0] + 1].add(player2);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
world[cords[1]-1][cords[0] + 1].add(player);
|
||||
world[cords[1]-1][cords[0]].remove(player);
|
||||
world[cords[1]][cords[0] + 1].add(player.getPlayerBlock2());
|
||||
world[cords[1]][cords[0]].remove(player.getPlayerBlock2());
|
||||
world[cords[1]-1][cords[0] + 1].add(player.getPlayerBlock1());
|
||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||
screenRenderer.render(this);
|
||||
|
||||
update(screenRenderer);
|
||||
@ -80,10 +80,10 @@ public class Game {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1]][cords[0] - 1].add(player2);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
world[cords[1]-1][cords[0] - 1].add(player);
|
||||
world[cords[1]-1][cords[0]].remove(player);
|
||||
world[cords[1]][cords[0] - 1].add(player.getPlayerBlock2());
|
||||
world[cords[1]][cords[0]].remove(player.getPlayerBlock2());
|
||||
world[cords[1]-1][cords[0] - 1].add(player.getPlayerBlock1());
|
||||
world[cords[1]-1][cords[0]].remove(player.getPlayerBlock1());
|
||||
screenRenderer.render(this);
|
||||
|
||||
update(screenRenderer);
|
||||
@ -95,14 +95,14 @@ 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().anyMatch(Block::isGhost)) {
|
||||
if (world[cords[1] - 2][cords[0]].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] + 1][cords[0]].stream().allMatch(Block::isGhost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1] - 1][cords[0]].remove(player);
|
||||
world[cords[1] - 1][cords[0]].add(player2);
|
||||
world[cords[1] - 2][cords[0]].add(player);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
world[cords[1] - 1][cords[0]].remove(player.getPlayerBlock1());
|
||||
world[cords[1] - 1][cords[0]].add(player.getPlayerBlock2());
|
||||
world[cords[1] - 2][cords[0]].add(player.getPlayerBlock1());
|
||||
world[cords[1]][cords[0]].remove(player.getPlayerBlock2());
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
@ -113,10 +113,10 @@ public class Game {
|
||||
int[] cords2 = getPlayerCords();
|
||||
|
||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
||||
world[cords2[1] - 1][cords2[0]].remove(player);
|
||||
world[cords2[1]][cords2[0]].add(player);
|
||||
world[cords2[1] + 1][cords2[0]].add(player2);
|
||||
world[cords2[1]][cords2[0]].remove(player2);
|
||||
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);
|
||||
}
|
||||
@ -132,7 +132,7 @@ public class Game {
|
||||
world[y][x].add(breakingBlock);
|
||||
screenRenderer.render(this);
|
||||
|
||||
double hardness = world[y][x].stream().filter(block -> !block.isGhost()).toList().get(0).calculateHardness(inventory);
|
||||
double hardness = world[y][x].stream().filter(block -> !block.isGhost()).toList().getFirst().calculateHardness(inventory);
|
||||
|
||||
this.mining = true;
|
||||
|
||||
@ -187,9 +187,10 @@ public class Game {
|
||||
}
|
||||
}
|
||||
|
||||
blocks.clear();
|
||||
blocks.add(new Block("air", SpriteLoader.SPRITES.AIR, true, false));
|
||||
CustomPlaceHandler customPlaceHandler = gameStates.dependencies.placeHandler.get(blocks.stream().filter(Block::isMineable).toList().getFirst().getBlockId());
|
||||
customPlaceHandler.mine(this, x, y);
|
||||
inventory.getItemInHand().ifPresent(Item::use);
|
||||
|
||||
screenRenderer.render(this);
|
||||
|
||||
update(screenRenderer);
|
||||
@ -233,10 +234,10 @@ public class Game {
|
||||
int[] cords2 = getPlayerCords();
|
||||
|
||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
||||
world[cords2[1] - 1][cords2[0]].remove(player);
|
||||
world[cords2[1]][cords2[0]].add(player);
|
||||
world[cords2[1] + 1][cords2[0]].add(player2);
|
||||
world[cords2[1]][cords2[0]].remove(player2);
|
||||
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);
|
||||
} else {
|
||||
@ -264,7 +265,7 @@ public class Game {
|
||||
}
|
||||
|
||||
if (!blocks.stream().allMatch(block -> block.getBlockId().equals("air"))) {
|
||||
RightClickHandler.handle(x, y, this);
|
||||
RightClickHandler.handle(x, y, this, screenRenderer);
|
||||
screenRenderer.render(this);
|
||||
return;
|
||||
}
|
||||
@ -273,12 +274,13 @@ public class Game {
|
||||
return;
|
||||
}
|
||||
|
||||
blocks.removeAll(blocks.stream().filter(block -> block.getBlockId().equals("air")).toList());
|
||||
blocks.add(inventory.getItemInHand().get().getBlock().get());
|
||||
Item item = inventory.getItemInHand().get();
|
||||
|
||||
inventory.decreaseItemInHand();
|
||||
CustomPlaceHandler placeHandler = gameStates.dependencies.placeHandler.get(item.getId());
|
||||
|
||||
screenRenderer.render(this);
|
||||
if (placeHandler.place(this, x, y)) {
|
||||
screenRenderer.render(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void changeSlot(int slot, ScreenRenderer screenRenderer) {
|
||||
|
@ -4,10 +4,12 @@ import cz.jzitnik.game.ui.CraftingTable;
|
||||
|
||||
public class GameStates {
|
||||
public CraftingTable craftingTable;
|
||||
public Dependencies dependencies;
|
||||
public int clickX = -1;
|
||||
public int clickY = -1;
|
||||
|
||||
public GameStates(Game game) {
|
||||
craftingTable = new CraftingTable(game);
|
||||
dependencies = new Dependencies();
|
||||
}
|
||||
}
|
||||
|
13
src/main/java/cz/jzitnik/game/Player.java
Normal file
13
src/main/java/cz/jzitnik/game/Player.java
Normal file
@ -0,0 +1,13 @@
|
||||
package cz.jzitnik.game;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Player {
|
||||
private int health = 10;
|
||||
private int hunger = 6;
|
||||
private Block playerBlock1;
|
||||
private Block playerBlock2;
|
||||
}
|
@ -21,10 +21,12 @@ public class SpriteLoader {
|
||||
|
||||
CHEST,
|
||||
CRAFTING_TABLE,
|
||||
COAL_ORE,
|
||||
|
||||
OAK_LOG,
|
||||
OAK_LEAF,
|
||||
OAK_PLANKS,
|
||||
OAK_DOOR,
|
||||
|
||||
WOODEN_PICKAXE,
|
||||
STONE_PICKAXE,
|
||||
@ -41,9 +43,13 @@ public class SpriteLoader {
|
||||
ITEM_COBBLESTONE,
|
||||
ITEM_STONE,
|
||||
ITEM_FURNACE,
|
||||
ITEM_OAK_DOOR,
|
||||
|
||||
ITEM_CRAFTING_TABLE,
|
||||
ITEM_CHEST
|
||||
ITEM_CHEST,
|
||||
|
||||
HEART,
|
||||
HUNGER
|
||||
}
|
||||
|
||||
public static final HashMap<SPRITES, Sprite> SPRITES_MAP = new HashMap<>();
|
||||
@ -63,6 +69,8 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.CHEST, new SimpleSprite("chest.ans"));
|
||||
SPRITES_MAP.put(SPRITES.COBBLESTONE, new SimpleSprite("cobblestone.ans"));
|
||||
SPRITES_MAP.put(SPRITES.FURNACE, new Furnace());
|
||||
SPRITES_MAP.put(SPRITES.COAL_ORE, new SimpleSprite("coal_ore.ans"));
|
||||
SPRITES_MAP.put(SPRITES.OAK_DOOR, new OakDoor());
|
||||
|
||||
SPRITES_MAP.put(SPRITES.WOODEN_PICKAXE, new SimpleSprite("items/wooden_pickaxe.ans"));
|
||||
SPRITES_MAP.put(SPRITES.STONE_PICKAXE, new SimpleSprite("items/stone_pickaxe.ans"));
|
||||
@ -79,6 +87,10 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.ITEM_STONE, new SimpleSprite("items/stone.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_CHEST, new SimpleSprite("items/chest.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_FURNACE, new SimpleSprite("items/furnace.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_OAK_DOOR, new SimpleSprite("oak_door/items/oak_door.ans"));
|
||||
|
||||
SPRITES_MAP.put(SPRITES.HEART, new Heart());
|
||||
SPRITES_MAP.put(SPRITES.HUNGER, new Hunger());
|
||||
}
|
||||
|
||||
public static SpriteList<SPRITES> load() {
|
||||
|
@ -0,0 +1,12 @@
|
||||
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 RegisterPlaceHandler {
|
||||
String value();
|
||||
}
|
@ -94,6 +94,18 @@ public class CraftingRecipeList {
|
||||
{"cobblestone", null, "cobblestone"},
|
||||
{"cobblestone", "cobblestone", "cobblestone"}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.furnace())));
|
||||
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{"oak_planks", "oak_planks", null},
|
||||
{"oak_planks", "oak_planks", null},
|
||||
{"oak_planks", "oak_planks", null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.oakDoor())));
|
||||
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{"dirt", null, null},
|
||||
{null, null, null},
|
||||
{null, null, null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.oakDoor())));
|
||||
}
|
||||
|
||||
public static Optional<CraftingRecipe> getRecipe(String[] r) {
|
||||
|
12
src/main/java/cz/jzitnik/game/generation/CaveGenerator.java
Normal file
12
src/main/java/cz/jzitnik/game/generation/CaveGenerator.java
Normal file
@ -0,0 +1,12 @@
|
||||
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,5 +1,8 @@
|
||||
package cz.jzitnik.game;
|
||||
package cz.jzitnik.game.generation;
|
||||
|
||||
import cz.jzitnik.game.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.sprites.Steve;
|
||||
@ -18,8 +21,8 @@ public class Generation {
|
||||
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
||||
|
||||
game.setPlayer(steveBlock);
|
||||
game.setPlayer2(steveBlock2);
|
||||
game.getPlayer().setPlayerBlock1(steveBlock);
|
||||
game.getPlayer().setPlayerBlock2(steveBlock2);
|
||||
|
||||
int[] terrainHeight = generateTerrain();
|
||||
populateWorld(world, terrainHeight);
|
||||
@ -77,9 +80,7 @@ public class Generation {
|
||||
|
||||
for (List<Block>[] lists : world) {
|
||||
for (List<Block> list : lists) {
|
||||
if (list.isEmpty()) {
|
||||
list.add(new Block("air", SpriteLoader.SPRITES.AIR, true, false));
|
||||
}
|
||||
list.addFirst(new Block("air", SpriteLoader.SPRITES.AIR, true, false));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package cz.jzitnik.game.handlers.place;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
|
||||
public interface CustomPlaceHandler {
|
||||
boolean place(Game game, int x, int y);
|
||||
void mine(Game game, int x, int y);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cz.jzitnik.game.handlers.place;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
|
||||
public class DefaultPlaceHandler implements CustomPlaceHandler {
|
||||
@Override
|
||||
public boolean place(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
var inventory = game.getInventory();
|
||||
|
||||
blocks.add(inventory.getItemInHand().get().getBlock().get());
|
||||
|
||||
inventory.decreaseItemInHand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mine(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
|
||||
blocks.removeAll(blocks.stream().filter(i -> !i.getBlockId().equals("air")).toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
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 {
|
||||
private final HashMap<String, CustomPlaceHandler> placeHandlerList = new HashMap<>();
|
||||
private final CustomPlaceHandler defaultPlaceHandler = new DefaultPlaceHandler();
|
||||
|
||||
public boolean contains(String itemId) {
|
||||
return placeHandlerList.containsKey(itemId);
|
||||
}
|
||||
|
||||
public CustomPlaceHandler get(String itemId) {
|
||||
if (!contains(itemId)) {
|
||||
return defaultPlaceHandler;
|
||||
}
|
||||
|
||||
return placeHandlerList.get(itemId);
|
||||
}
|
||||
|
||||
public PlaceHandler() {
|
||||
registerHandlers();
|
||||
}
|
||||
|
||||
private void registerHandlers() {
|
||||
Reflections reflections = new Reflections("cz.jzitnik.game.handlers.place.handlers");
|
||||
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(RegisterPlaceHandler.class);
|
||||
|
||||
for (Class<?> clazz : handlerClasses) {
|
||||
if (CustomPlaceHandler.class.isAssignableFrom(clazz)) {
|
||||
try {
|
||||
CustomPlaceHandler handlerInstance = (CustomPlaceHandler) clazz.getDeclaredConstructor().newInstance();
|
||||
RegisterPlaceHandler annotation = clazz.getAnnotation(RegisterPlaceHandler.class);
|
||||
placeHandlerList.put(annotation.value(), handlerInstance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package cz.jzitnik.game.handlers.place.handlers;
|
||||
|
||||
import cz.jzitnik.game.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.sprites.OakDoor;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
|
||||
@RegisterPlaceHandler("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];
|
||||
var blocksTop = game.getWorld()[y-1][x];
|
||||
|
||||
if (!blocksTop.stream().allMatch(Block::isGhost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var inventory = game.getInventory();
|
||||
|
||||
Block block = inventory.getItemInHand().get().getBlock().get();
|
||||
block.setSpriteState(OakDoor.OakDoorState.BOTTOMCLOSED);
|
||||
blocks.add(block);
|
||||
|
||||
Block block2 = ItemBlockSupplier.Blocks.oakDoor();
|
||||
block2.setSpriteState(OakDoor.OakDoorState.TOPCLOSED);
|
||||
blocksTop.add(block2);
|
||||
|
||||
inventory.decreaseItemInHand();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mine(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
Block block = blocks.stream().filter(b -> b.getBlockId().equals("oak_door")).toList().getFirst();
|
||||
|
||||
if (block.getSpriteState().get() == OakDoor.OakDoorState.BOTTOM || block.getSpriteState().get() == OakDoor.OakDoorState.BOTTOMCLOSED) {
|
||||
var blocks2 = game.getWorld()[y-1][x];
|
||||
blocks2.removeAll(blocks2.stream().filter(i -> !i.getBlockId().equals("air")).toList());
|
||||
}
|
||||
|
||||
if (block.getSpriteState().get() == OakDoor.OakDoorState.TOP || block.getSpriteState().get() == OakDoor.OakDoorState.TOPCLOSED) {
|
||||
var blocks2 = game.getWorld()[y+1][x];
|
||||
blocks2.removeAll(blocks2.stream().filter(i -> !i.getBlockId().equals("air")).toList());
|
||||
}
|
||||
|
||||
blocks.removeAll(blocks.stream().filter(i -> !i.getBlockId().equals("air")).toList());
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package cz.jzitnik.tui;
|
||||
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;
|
||||
|
||||
@ -12,7 +14,7 @@ public class RightClickHandler {
|
||||
void apply(T t, U u);
|
||||
}
|
||||
|
||||
public static void handle(int x, int y, Game game) {
|
||||
public static void handle(int x, int y, Game game, ScreenRenderer screenRenderer) {
|
||||
if (game.isMining()) {
|
||||
return;
|
||||
}
|
||||
@ -21,6 +23,7 @@ public class RightClickHandler {
|
||||
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;
|
@ -36,6 +36,9 @@ public class ItemBlockSupplier {
|
||||
public static Item furnace(Block ref) {
|
||||
return new Item("furnace", "Furnace", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_FURNACE, ref);
|
||||
}
|
||||
public static Item oakDoor(Block ref) {
|
||||
return new Item("oak_door", "Oak door", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_OAK_DOOR, ref);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Blocks {
|
||||
@ -85,6 +88,14 @@ public class ItemBlockSupplier {
|
||||
block.setDrops(List.of(Helper.furnace(block)));
|
||||
return block;
|
||||
}
|
||||
public static Block coalOre() {
|
||||
return new Block("coal_ore", SpriteLoader.SPRITES.COAL_ORE);
|
||||
}
|
||||
public static Block oakDoor() {
|
||||
var block = new Block("oak_door", SpriteLoader.SPRITES.OAK_DOOR, 3, ItemType.AXE, new ArrayList<>());
|
||||
block.setDrops(List.of(Helper.oakDoor(block)));
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
// I hate this but whatever
|
||||
@ -131,5 +142,8 @@ public class ItemBlockSupplier {
|
||||
public static Item furnace() {
|
||||
return Helper.furnace(Blocks.furnace());
|
||||
}
|
||||
public static Item oakDoor() {
|
||||
return Helper.oakDoor(Blocks.oakDoor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
src/main/java/cz/jzitnik/game/sprites/Heart.java
Normal file
25
src/main/java/cz/jzitnik/game/sprites/Heart.java
Normal file
@ -0,0 +1,25 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
public class Heart extends Sprite {
|
||||
public enum HeartState {
|
||||
OFF,
|
||||
ON,
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
throw new RuntimeException("Idk");
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
return ResourceLoader.loadResource(
|
||||
switch (e) {
|
||||
case HeartState.OFF -> "gui/heartempty.ans";
|
||||
case HeartState.ON -> "gui/heartfull.ans";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
25
src/main/java/cz/jzitnik/game/sprites/Hunger.java
Normal file
25
src/main/java/cz/jzitnik/game/sprites/Hunger.java
Normal file
@ -0,0 +1,25 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
public class Hunger extends Sprite {
|
||||
public enum HungerState {
|
||||
OFF,
|
||||
ON,
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
throw new RuntimeException("Idk");
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
return ResourceLoader.loadResource(
|
||||
switch (e) {
|
||||
case HungerState.OFF -> "gui/hungerempty.ans";
|
||||
case HungerState.ON -> "gui/hungerfull.ans";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
29
src/main/java/cz/jzitnik/game/sprites/OakDoor.java
Normal file
29
src/main/java/cz/jzitnik/game/sprites/OakDoor.java
Normal file
@ -0,0 +1,29 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
public class OakDoor extends Sprite {
|
||||
public enum OakDoorState {
|
||||
TOP,
|
||||
BOTTOM,
|
||||
TOPCLOSED,
|
||||
BOTTOMCLOSED
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
return ResourceLoader.loadResource("oak_door/bottomclosed.ans");
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
return ResourceLoader.loadResource(
|
||||
switch (e) {
|
||||
case OakDoorState.TOP -> "oak_door/top.ans";
|
||||
case OakDoorState.BOTTOM -> "oak_door/bottom.ans";
|
||||
case OakDoorState.TOPCLOSED -> "oak_door/topclosed.ans";
|
||||
case OakDoorState.BOTTOMCLOSED -> "oak_door/bottomclosed.ans";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
49
src/main/java/cz/jzitnik/game/ui/Healthbar.java
Normal file
49
src/main/java/cz/jzitnik/game/ui/Healthbar.java
Normal file
@ -0,0 +1,49 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.sprites.Heart;
|
||||
import cz.jzitnik.game.sprites.Hunger;
|
||||
import cz.jzitnik.tui.SpriteList;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import static cz.jzitnik.game.ui.Inventory.INVENTORY_SIZE_PX;
|
||||
|
||||
public class Healthbar {
|
||||
public static void render(StringBuilder buffer, SpriteList spriteList, Terminal terminal, Game game) {
|
||||
int termWidth = terminal.getWidth();
|
||||
int startLeft = (termWidth / 2) - (INVENTORY_SIZE_PX / 2);
|
||||
|
||||
int heartSize = 9 * 20;
|
||||
int moveLeft = INVENTORY_SIZE_PX - (heartSize * 2);
|
||||
|
||||
String[] spriteOn = spriteList.getSprite(SpriteLoader.SPRITES.HEART).getSprite(Heart.HeartState.ON).split("\n");
|
||||
String[] spriteOff = spriteList.getSprite(SpriteLoader.SPRITES.HEART).getSprite(Heart.HeartState.OFF).split("\n");
|
||||
|
||||
String[] hungerSpriteOn = spriteList.getSprite(SpriteLoader.SPRITES.HUNGER).getSprite(Hunger.HungerState.ON).split("\n");
|
||||
String[] hungerSpriteOff = spriteList.getSprite(SpriteLoader.SPRITES.HUNGER).getSprite(Hunger.HungerState.OFF).split("\n");
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
buffer.append(" ".repeat(startLeft));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
if (j < game.getPlayer().getHealth()) {
|
||||
buffer.append(spriteOn[i]);
|
||||
} else {
|
||||
buffer.append(spriteOff[i]);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.append("\033[0m").append(" ".repeat(moveLeft));
|
||||
for (int j = 0; j < 10; j++) {
|
||||
if ((10 - j) <= game.getPlayer().getHunger()) {
|
||||
buffer.append(hungerSpriteOn[i]);
|
||||
} else {
|
||||
buffer.append(hungerSpriteOff[i]);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.append("\n");
|
||||
}
|
||||
buffer.append("\n\n");
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ public class ScreenMovingCalculationProvider {
|
||||
int spriteHeight = 25;
|
||||
|
||||
int viewXRadius = (terminalWidth / 2) / spriteWidth;
|
||||
int viewYRadius = ((terminalHeight - 30) / 2) / spriteHeight;
|
||||
int viewYRadius = ((terminalHeight - 30 - 9) / 2) / spriteHeight;
|
||||
|
||||
// Ensure at least one sprite is visible
|
||||
viewXRadius = Math.max(viewXRadius, 1);
|
||||
|
@ -5,6 +5,7 @@ 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.ui.Healthbar;
|
||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -141,6 +142,8 @@ public class ScreenRenderer {
|
||||
// Empty space between world and hotbar
|
||||
main.append("\n\n\n");
|
||||
|
||||
Healthbar.render(main, spriteList, terminal, game);
|
||||
|
||||
game.getInventory().renderHotbar(main, spriteList, terminal, false);
|
||||
}
|
||||
}
|
||||
|
@ -23,11 +23,4 @@ public class SpriteList<E extends Enum<E>> {
|
||||
public Sprite getSprite(E key) {
|
||||
return sprites.get(key);
|
||||
}
|
||||
|
||||
public void setSprite(E key, Sprite value) {
|
||||
if (!sprites.containsKey(key)) {
|
||||
throw new IllegalArgumentException("Invalid key: " + key);
|
||||
}
|
||||
sprites.put(key, value);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user