feat: New Grid API and Inventory rendered
This commit is contained in:
6
src/main/java/cz/jzitnik/events/InventoryRerender.java
Normal file
6
src/main/java/cz/jzitnik/events/InventoryRerender.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package cz.jzitnik.events;
|
||||
|
||||
import cz.jzitnik.utils.events.Event;
|
||||
|
||||
public class InventoryRerender implements Event {
|
||||
}
|
||||
@@ -78,6 +78,9 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
|
||||
int startY = start.getY();
|
||||
|
||||
RerenderUtils.rerenderPart(0, width - 1, 0, height - 1, startX, startY, currentRoom, room, player, playerTexture, screenBuffer, resourceManager, debugging);
|
||||
if (event.isFullRerender()) {
|
||||
InventoryRerenderHandler.renderInventoryRerender(dm);
|
||||
}
|
||||
|
||||
partsToRerender.add(new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(startX, startY),
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package cz.jzitnik.events.handlers;
|
||||
|
||||
import com.googlecode.lanterna.TerminalSize;
|
||||
import com.googlecode.lanterna.TextColor;
|
||||
import cz.jzitnik.annotations.EventHandler;
|
||||
import cz.jzitnik.events.InventoryRerender;
|
||||
import cz.jzitnik.game.GameRoom;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.items.GameItem;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.ui.Grid;
|
||||
import cz.jzitnik.ui.pixels.ColoredPixel;
|
||||
import cz.jzitnik.ui.pixels.Pixel;
|
||||
import cz.jzitnik.utils.DependencyManager;
|
||||
import cz.jzitnik.utils.RerenderUtils;
|
||||
import cz.jzitnik.utils.StateManager;
|
||||
import cz.jzitnik.utils.events.AbstractEventHandler;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@EventHandler(InventoryRerender.class)
|
||||
public class InventoryRerenderHandler extends AbstractEventHandler<InventoryRerender> {
|
||||
|
||||
private static final int ITEMS_X = 3;
|
||||
private static final int ITEMS_Y = 5;
|
||||
private static final int OUTER_BORDER_WIDTH = 3;
|
||||
private static final int INNER_BORDER_WIDTH = 2;
|
||||
private static final int ITEM_SIZE = 16; // Characters
|
||||
private static final int ITEM_PADDING = 2; // padding on each side
|
||||
|
||||
private static final Pixel BORDER_COLOR =
|
||||
new ColoredPixel(new TextColor.RGB(255, 255, 255));
|
||||
private static final Pixel BACKGROUND_COLOR =
|
||||
new ColoredPixel(new TextColor.RGB(166, 166, 166));
|
||||
|
||||
private static final int ITEM_SLOT_SIZE = ITEM_SIZE + ITEM_PADDING * 2;
|
||||
private static final int INVENTORY_WIDTH =
|
||||
OUTER_BORDER_WIDTH * 2 +
|
||||
(ITEMS_X * (ITEM_SLOT_SIZE + INNER_BORDER_WIDTH) - INNER_BORDER_WIDTH);
|
||||
private static final int INVENTORY_HEIGHT =
|
||||
OUTER_BORDER_WIDTH * 2 +
|
||||
(ITEMS_Y * (ITEM_SLOT_SIZE + INNER_BORDER_WIDTH) - INNER_BORDER_WIDTH);
|
||||
private static final int REAL_INVENTORY_HEIGHT =
|
||||
Math.ceilDiv(INVENTORY_HEIGHT, 2); // 2 pixels per terminal row
|
||||
|
||||
public InventoryRerenderHandler(DependencyManager dm) {
|
||||
super(dm);
|
||||
}
|
||||
|
||||
public static void renderInventoryRerender(DependencyManager dm) {
|
||||
StateManager stateManager = dm.getDependencyOrThrow(StateManager.class);
|
||||
ResourceManager resourceManager = dm.getDependencyOrThrow(ResourceManager.class);
|
||||
|
||||
GameState gameState = stateManager.getOrThrow(GameState.class);
|
||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
||||
BufferedImage room = resourceManager.getResource(currentRoom.getTexture());
|
||||
|
||||
TerminalState terminalState = stateManager.getOrThrow(TerminalState.class);
|
||||
TerminalSize terminalSize = terminalState.getTerminalScreen().getTerminalSize();
|
||||
|
||||
var inventory = gameState.getPlayer().getInventory();
|
||||
var buffer = stateManager.getOrThrow(ScreenBuffer.class).getRenderedBuffer();
|
||||
|
||||
var roomStart = RerenderUtils.getStart(room, terminalSize);
|
||||
int maxX = roomStart.getX() - 1;
|
||||
|
||||
final int OFFSET_Y =
|
||||
(((terminalSize.getRows() - 1) / 2) - (REAL_INVENTORY_HEIGHT / 2)) * 2;
|
||||
final int OFFSET_X =
|
||||
(maxX / 2) - (INVENTORY_WIDTH / 2);
|
||||
|
||||
BufferedImage[] textures = inventory.stream()
|
||||
.map(GameItem::getTexture)
|
||||
.toArray(BufferedImage[]::new);
|
||||
|
||||
Grid grid = new Grid(
|
||||
ITEMS_X,
|
||||
ITEMS_Y,
|
||||
OUTER_BORDER_WIDTH,
|
||||
INNER_BORDER_WIDTH,
|
||||
ITEM_SIZE,
|
||||
ITEM_PADDING,
|
||||
BORDER_COLOR,
|
||||
BACKGROUND_COLOR
|
||||
);
|
||||
|
||||
Pixel[][] internalBuffer = grid.render(textures);
|
||||
|
||||
for (int y = 0; y < grid.getHeight(); y++) {
|
||||
System.arraycopy(internalBuffer[y], 0, buffer[y + OFFSET_Y], OFFSET_X, grid.getWidth());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(InventoryRerender event) {
|
||||
renderInventoryRerender(dm);
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,16 @@ import cz.jzitnik.annotations.EventHandler;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.events.ExitEvent;
|
||||
import cz.jzitnik.events.FullRoomDraw;
|
||||
import cz.jzitnik.events.KeyboardPressEvent;
|
||||
import cz.jzitnik.events.PlayerMoveEvent;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.utils.DependencyManager;
|
||||
import cz.jzitnik.utils.events.AbstractEventHandler;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@EventHandler(KeyboardPressEvent.class)
|
||||
public class KeyboardPressEventHandler extends AbstractEventHandler<KeyboardPressEvent> {
|
||||
public KeyboardPressEventHandler(DependencyManager dm) {
|
||||
@@ -37,6 +40,10 @@ public class KeyboardPressEventHandler extends AbstractEventHandler<KeyboardPres
|
||||
case Escape:
|
||||
eventManager.emitEvent(new ExitEvent());
|
||||
break;
|
||||
case F5:
|
||||
log.debug("Fully rerendering screen");
|
||||
eventManager.emitEvent(new FullRoomDraw(true));
|
||||
break;
|
||||
case Character:
|
||||
switch (keyStroke.getCharacter()) {
|
||||
case 'w','a','s','d' -> eventManager.emitEvent(new PlayerMoveEvent(keyStroke));
|
||||
|
||||
@@ -32,7 +32,6 @@ public class GameRoom {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
overrideBuffer[y][x] = new Empty();
|
||||
overrideBuffer[y][x] = new Empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import cz.jzitnik.game.items.GameItem;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.ui.Grid;
|
||||
import cz.jzitnik.ui.pixels.ColoredPixel;
|
||||
import cz.jzitnik.ui.pixels.Empty;
|
||||
import cz.jzitnik.ui.pixels.Pixel;
|
||||
@@ -33,8 +34,10 @@ import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public final class Chest extends GameObject implements UIClickHandler {
|
||||
private static final TextColor BORDER_COLOR = new TextColor.RGB(0, 0, 0);
|
||||
private static final TextColor TRANSPARENT_COLOR = new TextColor.RGB(255, 255, 255);
|
||||
private static final TextColor BORDER_COLOR = new TextColor.RGB(255, 255, 255);
|
||||
private static final TextColor TRANSPARENT_COLOR = new TextColor.RGB(166, 166, 166);
|
||||
|
||||
private static final int RENDER_PADDING = 1;
|
||||
|
||||
private final List<GameItem> items;
|
||||
private final DependencyManager dependencyManager;
|
||||
@@ -43,6 +46,7 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
|
||||
private int actualDisplayStartX;
|
||||
private int actualDisplayStartY;
|
||||
|
||||
private int chestUISizeX;
|
||||
private int chestUISizeY;
|
||||
|
||||
@@ -78,6 +82,19 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
render(false);
|
||||
}
|
||||
|
||||
private Grid createGrid(int itemCount) {
|
||||
return new Grid(
|
||||
Math.max(1, itemCount), // Items X
|
||||
1, // Items Y
|
||||
2, // Outer Border
|
||||
2, // Inner Border
|
||||
16, // Item Size
|
||||
1, // Item Padding (Changed to 1 as per your request example)
|
||||
new ColoredPixel(BORDER_COLOR),
|
||||
new ColoredPixel(TRANSPARENT_COLOR)
|
||||
);
|
||||
}
|
||||
|
||||
private void render(boolean clear) {
|
||||
GameRoom currentRoom = gameState.getCurrentRoom();
|
||||
Player player = gameState.getPlayer();
|
||||
@@ -94,8 +111,9 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
terminalState.getTerminalScreen().getTerminalSize()
|
||||
);
|
||||
|
||||
int itemCount = items.size();
|
||||
calculateUISize(itemCount);
|
||||
Grid currentGrid = createGrid(items.size());
|
||||
this.chestUISizeX = currentGrid.getWidth();
|
||||
this.chestUISizeY = currentGrid.getHeight();
|
||||
|
||||
int chestUIStartX = getCords().getX();
|
||||
int chestUIStartY = getCords().getY();
|
||||
@@ -103,39 +121,39 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
int guiStartX = chestUIStartX + (chestTexture.getWidth() / 2) - (chestUISizeX / 2);
|
||||
int guiStartY = chestUIStartY - chestUISizeY - 1;
|
||||
|
||||
TerminalPosition guiStart = new TerminalPosition(guiStartX + start.getX(), guiStartY + start.getY());
|
||||
TerminalPosition guiEnd = new TerminalPosition(
|
||||
(guiStartX + chestUISizeX - 1) + start.getX(),
|
||||
(guiStartY + chestUISizeY - 1) + start.getY()
|
||||
);
|
||||
actualDisplayStartX = guiStartX + start.getX();
|
||||
actualDisplayStartY = guiStartY + start.getY();
|
||||
|
||||
actualDisplayStartX = guiStartX + start.getX() + 2;
|
||||
actualDisplayStartY = guiStartY + start.getY() + 2;
|
||||
int renderMinX = actualDisplayStartX;
|
||||
int renderMinY = actualDisplayStartY;
|
||||
int renderMaxX = actualDisplayStartX + chestUISizeX;
|
||||
int renderMaxY = actualDisplayStartY + chestUISizeY;
|
||||
|
||||
if (clear) {
|
||||
Grid previousGrid = createGrid(items.size() + 1);
|
||||
int prevWidth = previousGrid.getWidth();
|
||||
|
||||
int prevGuiStartX = chestUIStartX + (chestTexture.getWidth() / 2) - (prevWidth / 2);
|
||||
int prevDisplayStartX = prevGuiStartX + start.getX();
|
||||
|
||||
renderMinX = Math.min(renderMinX, prevDisplayStartX);
|
||||
renderMaxX = Math.max(renderMaxX, prevDisplayStartX + prevWidth);
|
||||
|
||||
clearPreviousUI(
|
||||
currentRoom,
|
||||
roomTexture,
|
||||
player,
|
||||
playerTexture,
|
||||
buffer,
|
||||
overrideBuffer,
|
||||
start,
|
||||
currentRoom, roomTexture, player, playerTexture,
|
||||
buffer, overrideBuffer, start,
|
||||
guiStartY,
|
||||
chestUIStartX,
|
||||
chestTexture.getWidth(),
|
||||
itemCount
|
||||
prevGuiStartX,
|
||||
prevWidth,
|
||||
chestUISizeY
|
||||
);
|
||||
|
||||
int clearWidth = 4 + (itemCount + 1) * 16 + itemCount * 2;
|
||||
int clearStartX = chestUIStartX + (chestTexture.getWidth() / 2) - (clearWidth / 2);
|
||||
|
||||
guiStart = new TerminalPosition(clearStartX + start.getX(), guiStartY + start.getY());
|
||||
guiEnd = new TerminalPosition(clearStartX + start.getX() + clearWidth, (guiStartY + chestUISizeY - 1) + start.getY());
|
||||
}
|
||||
|
||||
TerminalPosition guiStart = new TerminalPosition(renderMinX - RENDER_PADDING, renderMinY - RENDER_PADDING);
|
||||
TerminalPosition guiEnd = new TerminalPosition(renderMaxX + RENDER_PADDING, renderMaxY + RENDER_PADDING);
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
drawUI(buffer, overrideBuffer, start, guiStartX, guiStartY);
|
||||
drawUI(currentGrid, buffer, overrideBuffer, start, guiStartX, guiStartY);
|
||||
}
|
||||
|
||||
RerenderUtils.rerenderPart(
|
||||
@@ -156,18 +174,13 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
|
||||
RerenderScreen.ScreenPart sp = new RerenderScreen.ScreenPart(guiStart, guiEnd);
|
||||
|
||||
listenerHashCode = uiClickHandlerRepository.registerCurrentRoomHandler(sp, this);
|
||||
|
||||
//eventManager.emitEvent(RerenderScreen.full(terminalState.getTerminalScreen().getTerminalSize()));
|
||||
if (!items.isEmpty()) {
|
||||
listenerHashCode = uiClickHandlerRepository.registerCurrentRoomHandler(sp, this);
|
||||
}
|
||||
|
||||
eventManager.emitEvent(new RerenderScreen(sp));
|
||||
}
|
||||
|
||||
private void calculateUISize(int itemCount) {
|
||||
chestUISizeY = 20;
|
||||
chestUISizeX = 4 + itemCount * 16 + (itemCount - 1) * 2;
|
||||
}
|
||||
|
||||
private void clearPreviousUI(
|
||||
GameRoom room,
|
||||
BufferedImage roomTexture,
|
||||
@@ -177,14 +190,11 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
Pixel[][] overrideBuffer,
|
||||
RoomCords start,
|
||||
int guiStartY,
|
||||
int chestUIStartX,
|
||||
int chestTextureWidth,
|
||||
int itemCount
|
||||
int clearStartX,
|
||||
int clearWidth,
|
||||
int clearHeight
|
||||
) {
|
||||
int clearWidth = 4 + (itemCount + 1) * 16 + itemCount * 2;
|
||||
int clearStartX = chestUIStartX + (chestTextureWidth / 2) - (clearWidth / 2);
|
||||
|
||||
for (int y = guiStartY; y < guiStartY + chestUISizeY; y++) {
|
||||
for (int y = guiStartY; y < guiStartY + clearHeight; y++) {
|
||||
for (int x = clearStartX; x < clearStartX + clearWidth; x++) {
|
||||
int pixel = RerenderUtils.getPixel(
|
||||
room,
|
||||
@@ -205,17 +215,30 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
}
|
||||
|
||||
private void drawUI(
|
||||
Grid grid,
|
||||
Pixel[][] buffer,
|
||||
Pixel[][] overrideBuffer,
|
||||
RoomCords start,
|
||||
int guiStartX,
|
||||
int guiStartY
|
||||
) {
|
||||
for (int y = 0; y < chestUISizeY; y++) {
|
||||
for (int x = 0; x < chestUISizeX; x++) {
|
||||
Pixel pixel = getPixel(x, y, chestUISizeX, chestUISizeY);
|
||||
buffer[guiStartY + y + start.getY()][guiStartX + x + start.getX()] = pixel;
|
||||
overrideBuffer[guiStartY + y][guiStartX + x] = pixel;
|
||||
BufferedImage[] textures = items.stream()
|
||||
.map(GameItem::getTexture)
|
||||
.toArray(BufferedImage[]::new);
|
||||
|
||||
Pixel[][] uiPixels = grid.render(textures);
|
||||
|
||||
for (int y = 0; y < grid.getHeight(); y++) {
|
||||
for (int x = 0; x < grid.getWidth(); x++) {
|
||||
Pixel pixel = uiPixels[y][x];
|
||||
|
||||
int targetY = guiStartY + y + start.getY();
|
||||
int targetX = guiStartX + x + start.getX();
|
||||
|
||||
if (targetY >= 0 && targetY < buffer.length && targetX >= 0 && targetX < buffer[0].length) {
|
||||
buffer[targetY][targetX] = pixel;
|
||||
overrideBuffer[guiStartY + y][guiStartX + x] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,65 +250,23 @@ public final class Chest extends GameObject implements UIClickHandler {
|
||||
return new ColoredPixel(new TextColor.RGB(r, g, b));
|
||||
}
|
||||
|
||||
private Pixel getPixel(int objectX, int objectY, int width, int height) {
|
||||
if (isBorder(objectX, objectY, width, height)) {
|
||||
return new ColoredPixel(BORDER_COLOR);
|
||||
}
|
||||
|
||||
int screenX = objectX - 2;
|
||||
int screenY = objectY - 2;
|
||||
|
||||
int part = screenX / 18;
|
||||
int rest = screenX % 18;
|
||||
|
||||
if (rest >= 16) {
|
||||
return new ColoredPixel(BORDER_COLOR);
|
||||
}
|
||||
|
||||
GameItem item = items.get(part);
|
||||
BufferedImage texture = item.getTexture();
|
||||
|
||||
int pixel = texture.getRGB(rest, screenY);
|
||||
int alpha = (pixel >> 24) & 0xff;
|
||||
|
||||
if (alpha == 0) {
|
||||
return new ColoredPixel(TRANSPARENT_COLOR);
|
||||
}
|
||||
|
||||
return pixelToColored(pixel);
|
||||
}
|
||||
|
||||
private boolean isBorder(int x, int y, int width, int height) {
|
||||
return x <= 1 || x >= width - 2 || y <= 1 || y >= height - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(MouseAction mouseAction) {
|
||||
int mouseX = mouseAction.getPosition().getColumn();
|
||||
int mouseY = mouseAction.getPosition().getRow();
|
||||
|
||||
log.debug("Mouse: x: {}, y: {}", mouseX, mouseY);
|
||||
int localX = mouseX - actualDisplayStartX;
|
||||
int localY = (mouseY * 2) - actualDisplayStartY;
|
||||
|
||||
int screenX = mouseX - actualDisplayStartX;
|
||||
int screenY = (mouseY * 2) - actualDisplayStartY;
|
||||
Grid grid = createGrid(items.size());
|
||||
|
||||
log.debug("Screen: x: {}, y: {}", screenX, screenY);
|
||||
int itemIndex = grid.getItemIndexAt(localX, localY);
|
||||
|
||||
if (screenX < 0 || screenY < 0 || screenX > chestUISizeX || screenY > chestUISizeY) {
|
||||
if (itemIndex == -1 || itemIndex >= items.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int part = screenX / 18;
|
||||
if (part >= items.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rest = screenX % 18;
|
||||
if (rest >= 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
var item = items.get(part);
|
||||
GameItem item = items.get(itemIndex);
|
||||
gameState.getPlayer().getInventory().add(item);
|
||||
items.remove(item);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GameSetup {
|
||||
private DependencyManager dependencyManager;
|
||||
|
||||
public void setup() {
|
||||
gameState.setScreen(new IntroScene(dependencyManager));
|
||||
//gameState.setScreen(new IntroScene(dependencyManager));
|
||||
|
||||
GameRoom mainRoom = new MainRoom(dependencyManager, resourceManager);
|
||||
GameRoom rightRoom = new GameRoom(ResourceManager.Resource.ROOM2);
|
||||
|
||||
@@ -28,6 +28,6 @@ public class MainRoom extends GameRoom {
|
||||
addObject(chest);
|
||||
|
||||
Zombie zombie = new Zombie(resourceManager, new RoomCords(100, 100));
|
||||
addMob(zombie);
|
||||
//addMob(zombie);
|
||||
}
|
||||
}
|
||||
|
||||
157
src/main/java/cz/jzitnik/ui/Grid.java
Normal file
157
src/main/java/cz/jzitnik/ui/Grid.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package cz.jzitnik.ui;
|
||||
|
||||
import cz.jzitnik.ui.pixels.ColoredPixel;
|
||||
import cz.jzitnik.ui.pixels.Pixel;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class Grid {
|
||||
private final int itemsX;
|
||||
private final int itemsY;
|
||||
private final int outerBorderWidth;
|
||||
private final int innerBorderWidth;
|
||||
private final int itemPadding;
|
||||
|
||||
private final Pixel borderColor;
|
||||
private final Pixel backgroundColor;
|
||||
|
||||
private final int itemSlotSize;
|
||||
private final int cellSize;
|
||||
private final int gridWidth;
|
||||
private final int gridHeight;
|
||||
|
||||
public Grid(
|
||||
int itemsX,
|
||||
int itemsY,
|
||||
int outerBorderWidth,
|
||||
int innerBorderWidth,
|
||||
int itemSize,
|
||||
int itemPadding,
|
||||
Pixel borderColor,
|
||||
Pixel backgroundColor
|
||||
) {
|
||||
this.itemsX = itemsX;
|
||||
this.itemsY = itemsY;
|
||||
this.outerBorderWidth = outerBorderWidth;
|
||||
this.innerBorderWidth = innerBorderWidth;
|
||||
this.itemPadding = itemPadding;
|
||||
this.borderColor = borderColor;
|
||||
this.backgroundColor = backgroundColor;
|
||||
|
||||
this.itemSlotSize = itemSize + itemPadding * 2;
|
||||
this.cellSize = itemSlotSize + innerBorderWidth;
|
||||
|
||||
this.gridWidth =
|
||||
outerBorderWidth * 2 +
|
||||
(itemsX * (itemSlotSize + innerBorderWidth) - innerBorderWidth);
|
||||
|
||||
this.gridHeight =
|
||||
outerBorderWidth * 2 +
|
||||
(itemsY * (itemSlotSize + innerBorderWidth) - innerBorderWidth);
|
||||
}
|
||||
|
||||
public Pixel[][] render(BufferedImage[] textures) {
|
||||
Pixel[][] buffer = new Pixel[gridHeight][gridWidth];
|
||||
|
||||
// Background + borders
|
||||
for (int y = 0; y < gridHeight; y++) {
|
||||
for (int x = 0; x < gridWidth; x++) {
|
||||
|
||||
boolean isOuterBorder =
|
||||
x < outerBorderWidth ||
|
||||
y < outerBorderWidth ||
|
||||
x >= gridWidth - outerBorderWidth ||
|
||||
y >= gridHeight - outerBorderWidth;
|
||||
|
||||
boolean isInnerBorderX =
|
||||
x >= outerBorderWidth + itemSlotSize &&
|
||||
((x - outerBorderWidth - itemSlotSize) % cellSize) < innerBorderWidth;
|
||||
|
||||
boolean isInnerBorderY =
|
||||
y >= outerBorderWidth + itemSlotSize &&
|
||||
((y - outerBorderWidth - itemSlotSize) % cellSize) < innerBorderWidth;
|
||||
|
||||
buffer[y][x] = (isOuterBorder || isInnerBorderX || isInnerBorderY)
|
||||
? borderColor
|
||||
: backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
// Items
|
||||
int maxItems = Math.min(textures.length, itemsX * itemsY);
|
||||
|
||||
for (int index = 0; index < maxItems; index++) {
|
||||
BufferedImage texture = textures[index];
|
||||
if (texture == null) continue;
|
||||
|
||||
int itemX = index % itemsX;
|
||||
int itemY = index / itemsX;
|
||||
|
||||
int baseX =
|
||||
outerBorderWidth +
|
||||
itemX * cellSize +
|
||||
itemPadding;
|
||||
|
||||
int baseY =
|
||||
outerBorderWidth +
|
||||
itemY * cellSize +
|
||||
itemPadding;
|
||||
|
||||
for (int y = 0; y < texture.getHeight(); y++) {
|
||||
for (int x = 0; x < texture.getWidth(); x++) {
|
||||
int pixel = texture.getRGB(x, y);
|
||||
int alpha = (pixel >> 24) & 0xff;
|
||||
|
||||
if (alpha == 0) continue;
|
||||
|
||||
int r = (pixel >> 16) & 0xff;
|
||||
int g = (pixel >> 8) & 0xff;
|
||||
int b = pixel & 0xff;
|
||||
|
||||
buffer[baseY + y][baseX + x] =
|
||||
new ColoredPixel(new com.googlecode.lanterna.TextColor.RGB(r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates which item index corresponds to the given x/y coordinates relative to the Grid's top-left.
|
||||
* @param x X coordinate relative to the Grid (0 is left edge of the outer border)
|
||||
* @param y Y coordinate relative to the Grid (0 is top edge of the outer border)
|
||||
* @return The index of the item, or -1 if the click was on a border/background/out of bounds.
|
||||
*/
|
||||
public int getItemIndexAt(int x, int y) {
|
||||
if (x < 0 || x >= gridWidth || y < 0 || y >= gridHeight) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (x < outerBorderWidth || x >= gridWidth - outerBorderWidth ||
|
||||
y < outerBorderWidth || y >= gridHeight - outerBorderWidth) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int contentX = x - outerBorderWidth;
|
||||
int contentY = y - outerBorderWidth;
|
||||
|
||||
int col = contentX / cellSize;
|
||||
int row = contentY / cellSize;
|
||||
|
||||
if (contentX % cellSize >= itemSlotSize) return -1;
|
||||
if (contentY % cellSize >= itemSlotSize) return -1;
|
||||
|
||||
if (col >= itemsX || row >= itemsY) return -1;
|
||||
|
||||
return row * itemsX + col;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return gridWidth;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return gridHeight;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user