refactor(ui): Better API for UI texts
This commit is contained in:
parent
6ece6d3096
commit
6028b54d10
@ -9,6 +9,8 @@ import cz.jzitnik.game.handlers.tooluse.ToolUseProvider;
|
||||
import cz.jzitnik.game.mobs.EntityHurtAnimation;
|
||||
import cz.jzitnik.game.mobs.EntityKill;
|
||||
import cz.jzitnik.game.smelting.Smelting;
|
||||
import cz.jzitnik.game.sprites.ui.Font;
|
||||
import cz.jzitnik.game.ui.Escape;
|
||||
|
||||
public class Dependencies {
|
||||
public PlaceHandler placeHandler = new PlaceHandler();
|
||||
@ -20,4 +22,6 @@ public class Dependencies {
|
||||
public Smelting smelting = new Smelting();
|
||||
public ToolUseProvider toolUseProvider = new ToolUseProvider();
|
||||
public Sound sound = new Sound();
|
||||
public Font font = new Font();
|
||||
public Escape escape = new Escape();
|
||||
}
|
||||
|
@ -1,11 +1,34 @@
|
||||
package cz.jzitnik.game.sprites.ui;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class Font {
|
||||
private final String[] lines = ResourceLoader.loadResource("ui/font.ans").split("\n");
|
||||
private final int HEIGHT = 7;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class FontDTO {
|
||||
private String data;
|
||||
private int width;
|
||||
private int height;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
private class CharDTO {
|
||||
private String character;
|
||||
private int width;
|
||||
}
|
||||
|
||||
private String get(int startY, int startX, int height, int width, String color) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
@ -18,11 +41,10 @@ public class Font {
|
||||
stringBuilder.append("\033[0m\n");
|
||||
}
|
||||
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private String getDigit(char digit, String color) {
|
||||
private CharDTO getDigit(char digit, String color) {
|
||||
int num = Integer.valueOf(digit);
|
||||
int width = 12;
|
||||
int startY = HEIGHT;
|
||||
@ -33,12 +55,12 @@ public class Font {
|
||||
startX = (26 + 9) * width;
|
||||
}
|
||||
|
||||
return get(startY, startX, HEIGHT, width, color);
|
||||
return new CharDTO(get(startY, startX, HEIGHT, width, color), width);
|
||||
}
|
||||
|
||||
public String getChar(char character, String color) {
|
||||
public CharDTO getChar(char character, String color) {
|
||||
if (character == ' ') {
|
||||
return ("\033[49m ".repeat(12) + "\n").repeat(HEIGHT);
|
||||
return new CharDTO(("\033[49m ".repeat(12) + "\n").repeat(HEIGHT), 12);
|
||||
}
|
||||
|
||||
if (Character.isDigit(character)) {
|
||||
@ -50,16 +72,19 @@ public class Font {
|
||||
int startY = (upper ? 0 : 1) * HEIGHT;
|
||||
int startX = (upper ? character - 'A' : character - 'a') * width;
|
||||
|
||||
return get(startY, startX, HEIGHT, width, color);
|
||||
return new CharDTO(get(startY, startX, HEIGHT, width, color), width);
|
||||
}
|
||||
|
||||
public String getLine(String text) {
|
||||
public FontDTO getLine(String text) {
|
||||
char[] chars = text.toCharArray();
|
||||
|
||||
String[][] letters = new String[chars.length][];
|
||||
int width = 0;
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
letters[i] = getChar(chars[i], "[47m").split("\n");
|
||||
var charDto = getChar(chars[i], "[47m");
|
||||
letters[i] = charDto.getCharacter().split("\n");
|
||||
width += charDto.getWidth();
|
||||
}
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
@ -72,6 +97,137 @@ public class Font {
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
return new FontDTO(stringBuilder.toString(), width, HEIGHT);
|
||||
}
|
||||
|
||||
public FontDTO scale(FontDTO font, int times) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
var line = font.getData();
|
||||
var lines = line.split("\n");
|
||||
|
||||
for (int lineNum = 0; lineNum < lines.length; lineNum++) {
|
||||
for (int i = 0; i < times; i++) {
|
||||
stringBuilder.append(scaleLine(lines[lineNum], times));
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return new FontDTO(stringBuilder.toString(), font.getWidth() * times, font.getHeight() * times);
|
||||
}
|
||||
|
||||
private StringBuilder scaleLine(String line, int times) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
for (char c : line.toCharArray()) {
|
||||
if (c == ' ') {
|
||||
result.append(" ".repeat(times));
|
||||
} else {
|
||||
result.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public FontDTO getScaledLine(String text, Size size, int termWidth) {
|
||||
return scale(getLine(text), size.getFunc().apply(termWidth));
|
||||
}
|
||||
|
||||
// This will probably need little more work
|
||||
public enum Size {
|
||||
SMALL((x) -> {
|
||||
if (x < 800) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}),
|
||||
MEDIUM((x) -> {
|
||||
if (x < 800) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}),
|
||||
LARGE((x) -> {
|
||||
if (x < 800) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 4;
|
||||
});
|
||||
|
||||
@Getter
|
||||
private Function<Integer, Integer> func;
|
||||
|
||||
Size(Function<Integer, Integer> func) {
|
||||
this.func = func;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Align {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
CENTER
|
||||
}
|
||||
|
||||
private FontDTO applyAlignment(FontDTO data, Align alignment, int termWidth) {
|
||||
return switch (alignment) {
|
||||
case LEFT -> data;
|
||||
case CENTER -> {
|
||||
var lines = data.getData().split("\n");
|
||||
int nowWidth = data.getWidth();
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
var leftPad = (termWidth - nowWidth) / 2;
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
buffer.append(" ".repeat(leftPad)).append(lines[i]);
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
yield new FontDTO(buffer.toString(), termWidth, data.getHeight());
|
||||
}
|
||||
case RIGHT -> {
|
||||
var lines = data.getData().split("\n");
|
||||
int nowWidth = data.getWidth();
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
var leftPad = termWidth - nowWidth;
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
buffer.append(" ".repeat(leftPad)).append(lines[i]);
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
yield new FontDTO(buffer.toString(), termWidth, data.getHeight());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public FontDTO line(Terminal terminal, String text, Object... attributes) {
|
||||
int termWidth = terminal.getWidth();
|
||||
//int termHeight = terminal.getHeight();
|
||||
|
||||
Size fontSize = Size.MEDIUM;
|
||||
Align alignment = Align.LEFT;
|
||||
|
||||
for (Object attribute : attributes) {
|
||||
if (Size.class.isAssignableFrom(attribute.getClass())) {
|
||||
fontSize = (Size) attribute;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Align.class.isAssignableFrom(attribute.getClass())) {
|
||||
alignment = (Align) attribute;
|
||||
continue;
|
||||
}
|
||||
|
||||
log.error("Invalid attribute class {}. Skipping", attribute.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
return applyAlignment(getScaledLine(text, fontSize, termWidth), alignment, termWidth);
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,21 @@ package cz.jzitnik.game.ui;
|
||||
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import cz.jzitnik.game.sprites.ui.Font;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.ui.Font.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class Escape {
|
||||
public static void render(StringBuilder buffer, Terminal terminal) {
|
||||
Font font = new Font();
|
||||
String character = font.getLine("Never gonna give you up never gonna let you down");
|
||||
public void render(StringBuilder buffer, Terminal terminal, Game game) {
|
||||
var font = game.getGameStates().dependencies.font;
|
||||
var width = terminal.getWidth();
|
||||
var height = terminal.getHeight();
|
||||
|
||||
buffer.append(character);
|
||||
log.debug("Terminal width: {}", width);
|
||||
log.debug("Terminal height: {}", height);
|
||||
|
||||
var twodcraft = font.line(terminal, "2DCraft", Size.LARGE, Align.LEFT);
|
||||
buffer.append(twodcraft.getData());
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ public class ScreenRenderer {
|
||||
main.append("\033[H\033[2J");
|
||||
|
||||
switch (game.getWindow()) {
|
||||
// Different screens: Probably will need a rewrite
|
||||
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()
|
||||
@ -80,7 +81,7 @@ public class ScreenRenderer {
|
||||
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 ESC -> Escape.render(main, terminal);
|
||||
case ESC -> game.getGameStates().dependencies.escape.render(main, terminal, game);
|
||||
case WORLD -> {
|
||||
// World
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user