forked from jzitnik/twodcraft
164 lines
6.2 KiB
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;
|
|
}
|
|
|
|
}
|