twodcraft/src/main/java/cz/jzitnik/tui/ScreenRenderer.java

164 lines
6.2 KiB
Java

package cz.jzitnik.tui;
import cz.jzitnik.game.entities.Block;
import cz.jzitnik.game.Game;
import cz.jzitnik.game.sprites.Steve;
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.Setter;
import org.jline.terminal.Terminal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class ScreenRenderer {
private final SpriteList spriteList;
private final Terminal terminal;
public ScreenRenderer(SpriteList spriteList, Terminal terminal) {
this.spriteList = spriteList;
this.terminal = terminal;
}
@Getter
@Setter
private Optional<List<Integer>> selectedBlock = Optional.empty();
private int[] getPlayerCords(List<Block>[][] world) {
for (int i = 0; i < world.length; i++) {
for (int j = 0; j < world[i].length; j++) {
if (world[i][j].stream().anyMatch(x -> x.getBlockId().equals("steve") && x.getSpriteState().isPresent()
&& x.getSpriteState().get() == Steve.SteveState.SECOND)) {
return new int[] { j, i };
}
}
}
return null;
}
public synchronized void render(Game game) {
var world = game.getWorld();
StringBuilder main = new StringBuilder();
main.append("\033[H\033[2J");
switch (game.getWindow()) {
case INVENTORY -> game.getInventory().renderFull(main, terminal, spriteList, true, Optional.empty());
case CRAFTING_TABLE -> game.getGameStates().craftingTable.render(main, terminal, spriteList);
case CHEST -> ((Chest) game.getWorld()[game.getGameStates().clickY][game.getGameStates().clickX].stream()
.filter(i -> i.getBlockId().equals("chest")).toList().getFirst().getData()).render(game, main,
terminal, spriteList);
case FURNACE -> ((Furnace) game.getWorld()[game.getGameStates().clickY][game.getGameStates().clickX]
.stream().filter(i -> i.getBlockId().equals("furnace")).toList().getFirst().getData()).render(game,
main, terminal, spriteList);
case WORLD -> {
// World
int[] cords = getPlayerCords(world);
if (cords == null)
return;
int playerX = cords[0];
int playerY = cords[1];
int terminalWidth = terminal.getWidth();
int terminalHeight = terminal.getHeight();
int[] data = ScreenMovingCalculationProvider.calculate(playerX, playerY, terminalHeight, terminalWidth,
world[0].length, world.length);
// Calculate visible area boundaries
int startX = data[0];
int endX = data[1];
int startY = data[2];
int endY = data[3];
int visibleWidth = endX - startX;
int visibleHeight = endY - startY;
if (visibleWidth % 2 != 0) {
endX = Math.max(startX, endX - 1);
}
if (visibleHeight % 2 != 0) {
endY = Math.max(startY, endY - 1);
}
StringBuilder[] lines = new StringBuilder[(endY - startY) * 25 + 1];
for (int i = 0; i < lines.length; i++) {
lines[i] = new StringBuilder();
}
int counter = 0;
for (int y = startY; y < endY; y++) {
for (int x = startX; x < endX; x++) {
List<Block> blocks = world[y][x];
List<String> sprites = new ArrayList<>(blocks.stream()
.map(block -> block.getSpriteState().isEmpty()
? spriteList.getSprite(block.getSprite()).getSprite()
: spriteList.getSprite(block.getSprite())
.getSprite(block.getSpriteState().get()))
.toList());
if (selectedBlock.isPresent() && selectedBlock.get().get(0) == x
&& selectedBlock.get().get(1) == y) {
StringBuilder stringBuilder = getStringBuilder();
sprites.add(stringBuilder.toString());
}
String sprite = SpriteCombiner.combineSprites(sprites.toArray(String[]::new));
String[] spriteLines = sprite.split("\n");
for (int i = 0; i < spriteLines.length; i++) {
lines[counter * 25 + i].append(spriteLines[i]).append("\033[0m");
}
}
counter++;
}
// World
for (int i = 0; i < lines.length; i++) {
main.append(lines[i]);
if (i < lines.length - 1) {
main.append("\n");
}
}
// Empty space between world and hotbar
main.append("\n\n\n");
Healthbar.render(main, spriteList, terminal, game);
game.getInventory().renderHotbar(main, spriteList, terminal, false);
}
}
System.out.println(main);
}
private static StringBuilder getStringBuilder() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("\033[38;5;231;48;5;231m▓".repeat(50));
stringBuilder.append("\n");
for (int i = 0; i < 23; i++) {
stringBuilder.append("\033[38;5;231;48;5;231m▓");
stringBuilder.append("\033[38;5;231;48;5;231m▓");
stringBuilder.append("\033[0m ".repeat(46));
stringBuilder.append("\033[38;5;231;48;5;231m▓");
stringBuilder.append("\033[38;5;231;48;5;231m▓");
stringBuilder.append("\n");
}
stringBuilder.append("\033[38;5;231;48;5;231m▓".repeat(50));
stringBuilder.append("\n");
return stringBuilder;
}
}