feat: Handle small terminals
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
package cz.jzitnik.events;
|
||||||
|
|
||||||
|
import cz.jzitnik.utils.events.Event;
|
||||||
|
|
||||||
|
public class TerminalTooSmallEvent implements Event {
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import cz.jzitnik.annotations.injectors.InjectDependency;
|
|||||||
import cz.jzitnik.annotations.injectors.InjectState;
|
import cz.jzitnik.annotations.injectors.InjectState;
|
||||||
import cz.jzitnik.events.FullRoomDraw;
|
import cz.jzitnik.events.FullRoomDraw;
|
||||||
import cz.jzitnik.events.RerenderScreen;
|
import cz.jzitnik.events.RerenderScreen;
|
||||||
|
import cz.jzitnik.events.TerminalTooSmallEvent;
|
||||||
import cz.jzitnik.game.GameRoom;
|
import cz.jzitnik.game.GameRoom;
|
||||||
import cz.jzitnik.game.GameState;
|
import cz.jzitnik.game.GameState;
|
||||||
import cz.jzitnik.game.Player;
|
import cz.jzitnik.game.Player;
|
||||||
@@ -62,56 +63,61 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(FullRoomDraw event) {
|
public void handle(FullRoomDraw event) {
|
||||||
log.debug("Rendering full room");
|
try {
|
||||||
TerminalScreen terminalScreen = terminalState.getTerminalScreen();
|
log.debug("Rendering full room");
|
||||||
List<RerenderScreen.ScreenPart> partsToRerender = new ArrayList<>();
|
TerminalScreen terminalScreen = terminalState.getTerminalScreen();
|
||||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
List<RerenderScreen.ScreenPart> partsToRerender = new ArrayList<>();
|
||||||
|
GameRoom currentRoom = gameState.getCurrentRoom();
|
||||||
|
|
||||||
Set<DoorPosition> doorPositions = RerenderUtils.getDoorPositions(currentRoom);
|
Set<DoorPosition> doorPositions = RerenderUtils.getDoorPositions(currentRoom);
|
||||||
|
|
||||||
var buffer = screenBuffer.getRenderedBuffer();
|
var buffer = screenBuffer.getRenderedBuffer();
|
||||||
var overrideBuffer = currentRoom.getOverrideBuffer();
|
var overrideBuffer = currentRoom.getOverrideBuffer();
|
||||||
|
|
||||||
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
||||||
BufferedImage doors = resourceManager.getResource(ResourceManager.Resource.DOORS);
|
BufferedImage doors = resourceManager.getResource(ResourceManager.Resource.DOORS);
|
||||||
Player player = gameState.getPlayer();
|
Player player = gameState.getPlayer();
|
||||||
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
|
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
|
||||||
TerminalSize terminalSize = terminalScreen.getTerminalSize();
|
TerminalSize terminalSize = terminalScreen.getTerminalSize();
|
||||||
|
|
||||||
int width = room.getWidth();
|
int width = room.getWidth();
|
||||||
int height = room.getHeight();
|
int height = room.getHeight();
|
||||||
|
|
||||||
var start = RerenderUtils.getStart(room, terminalSize);
|
var start = RerenderUtils.getStart(room, terminalSize);
|
||||||
int startX = start.getX();
|
int startX = start.getX();
|
||||||
int startY = start.getY();
|
int startY = start.getY();
|
||||||
|
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
RerenderUtils.PixelResult pixelResult = RerenderUtils.getPixel(currentRoom, room, doors, doorPositions, player, playerTexture, x, y);
|
RerenderUtils.PixelResult pixelResult = RerenderUtils.getPixel(currentRoom, room, doors, doorPositions, player, playerTexture, x, y);
|
||||||
int pixel = pixelResult.pixel();
|
int pixel = pixelResult.pixel();
|
||||||
int red = (pixel >> 16) & 0xff;
|
int red = (pixel >> 16) & 0xff;
|
||||||
int green = (pixel >> 8) & 0xff;
|
int green = (pixel >> 8) & 0xff;
|
||||||
int blue = pixel & 0xff;
|
int blue = pixel & 0xff;
|
||||||
|
|
||||||
Pixel overridePixel = overrideBuffer[y][x];
|
Pixel overridePixel = overrideBuffer[y][x];
|
||||||
Pixel pixel1 = new ColoredPixel(new TextColor.RGB(red, green, blue));
|
Pixel pixel1 = new ColoredPixel(new TextColor.RGB(red, green, blue));
|
||||||
|
|
||||||
Pixel finalPixelLeft = overridePixel.getClass() == Empty.class || pixelResult.isPlayer() ? pixel1 : overridePixel;
|
Pixel finalPixelLeft = overridePixel.getClass() == Empty.class || pixelResult.isPlayer() ? pixel1 : overridePixel;
|
||||||
|
|
||||||
buffer[y + startY][x + startX] = finalPixelLeft;
|
buffer[y + startY][x + startX] = finalPixelLeft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
partsToRerender.add(new RerenderScreen.ScreenPart(
|
partsToRerender.add(new RerenderScreen.ScreenPart(
|
||||||
new TerminalPosition(startX, startY),
|
new TerminalPosition(startX, startY),
|
||||||
new TerminalPosition(startX + width, startY + height - 1)
|
new TerminalPosition(startX + width, startY + height - 1)
|
||||||
));
|
));
|
||||||
|
|
||||||
if (renderState.isFirstRender() || event.isFullRerender()) {
|
if (renderState.isFirstRender() || event.isFullRerender()) {
|
||||||
eventManager.emitEvent(RerenderScreen.full(terminalSize));
|
eventManager.emitEvent(RerenderScreen.full(terminalSize));
|
||||||
renderState.setFirstRender(false);
|
renderState.setFirstRender(false);
|
||||||
} else {
|
} else {
|
||||||
eventManager.emitEvent(new RerenderScreen(partsToRerender.toArray(RerenderScreen.ScreenPart[]::new)));
|
eventManager.emitEvent(new RerenderScreen(partsToRerender.toArray(RerenderScreen.ScreenPart[]::new)));
|
||||||
|
}
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
// Screen too small to fit the room
|
||||||
|
eventManager.emitEvent(new TerminalTooSmallEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package cz.jzitnik.events.handlers;
|
||||||
|
|
||||||
|
import com.googlecode.lanterna.SGR;
|
||||||
|
import com.googlecode.lanterna.TerminalSize;
|
||||||
|
import com.googlecode.lanterna.TextCharacter;
|
||||||
|
import com.googlecode.lanterna.TextColor;
|
||||||
|
import com.googlecode.lanterna.screen.Screen;
|
||||||
|
import com.googlecode.lanterna.screen.TerminalScreen;
|
||||||
|
import cz.jzitnik.annotations.EventHandler;
|
||||||
|
import cz.jzitnik.annotations.injectors.InjectState;
|
||||||
|
import cz.jzitnik.events.TerminalTooSmallEvent;
|
||||||
|
import cz.jzitnik.states.TerminalState;
|
||||||
|
import cz.jzitnik.utils.DependencyManager;
|
||||||
|
import cz.jzitnik.utils.events.AbstractEventHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@EventHandler(TerminalTooSmallEvent.class)
|
||||||
|
public class TerminalTooSmallEventHandler extends AbstractEventHandler<TerminalTooSmallEvent> {
|
||||||
|
public TerminalTooSmallEventHandler(DependencyManager dm) {
|
||||||
|
super(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectState
|
||||||
|
private TerminalState terminalState;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(TerminalTooSmallEvent event) {
|
||||||
|
// Directly render message for the user
|
||||||
|
TerminalScreen terminalScreen = terminalState.getTerminalScreen();
|
||||||
|
terminalScreen.clear();
|
||||||
|
|
||||||
|
TerminalSize terminalSize = terminalScreen.getTerminalSize();
|
||||||
|
String text = "Terminal too small!";
|
||||||
|
String subText = "Please resize your terminal";
|
||||||
|
|
||||||
|
int startY = terminalSize.getRows() / 2;
|
||||||
|
|
||||||
|
int textStartX = (terminalSize.getColumns() / 2) - (text.length() / 2);
|
||||||
|
for (char character : text.toCharArray()) {
|
||||||
|
terminalScreen.setCharacter(textStartX++, startY, new TextCharacter(character, TextColor.ANSI.RED, TextColor.ANSI.DEFAULT, SGR.BOLD));
|
||||||
|
}
|
||||||
|
int subTextStartX = (terminalSize.getColumns() / 2) - (subText.length() / 2);
|
||||||
|
for (char character : subText.toCharArray()) {
|
||||||
|
terminalScreen.setCharacter(subTextStartX++, startY + 1, new TextCharacter(character, TextColor.ANSI.BLACK_BRIGHT, TextColor.ANSI.DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
terminalScreen.refresh(Screen.RefreshType.COMPLETE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user