feat: Interacting with objects

This commit is contained in:
2025-12-15 22:44:32 +01:00
parent 196e82beca
commit 4f72f5e1f6
13 changed files with 191 additions and 8 deletions

View File

@@ -0,0 +1,7 @@
package cz.jzitnik.events;
import cz.jzitnik.events.handlers.FullRoomDrawHandler;
import cz.jzitnik.utils.events.Event;
public record RoomChangeEvent(FullRoomDrawHandler.DoorPosition door) implements Event {
}

View File

@@ -96,9 +96,10 @@ public class FullRoomDrawHandler extends AbstractEventHandler<FullRoomDraw> {
buffer[y + startY][x * 2 + 1 + startX] = pixel1;
}
}
partsToRerender.add(new RerenderScreen.ScreenPart(
new TerminalPosition(startX, startY),
new TerminalPosition(startY + height - 1, (startX + height - 1) * 2)
new TerminalPosition(startX + width * 2, startY + height - 1)
));
if (renderState.isFirstRender() || event.isFullRerender()) {

View File

@@ -2,9 +2,12 @@ package cz.jzitnik.events.handlers;
import com.googlecode.lanterna.input.KeyStroke;
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.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;
@@ -15,9 +18,18 @@ public class KeyboardPressEventHandler extends AbstractEventHandler<KeyboardPres
super(dm);
}
@InjectDependency
private EventManager eventManager;
@InjectState
private GameState gameState;
@Override
public void handle(KeyboardPressEvent event) {
EventManager eventManager = dm.getDependencyOrThrow(EventManager.class); // TODO: Migrate to InjectDependency
if (gameState.getScreen() != null) {
gameState.getScreen().handleKeybordAction(event);
return;
}
KeyStroke keyStroke = event.getKeyStroke();

View File

@@ -2,12 +2,18 @@ package cz.jzitnik.events.handlers;
import cz.jzitnik.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.MouseAction;
import cz.jzitnik.events.MouseMoveEvent;
import cz.jzitnik.game.GameState;
import cz.jzitnik.game.objects.GameObject;
import cz.jzitnik.game.objects.Interactable;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.EventManager;
import java.util.Optional;
@EventHandler(MouseAction.class)
public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> {
public MouseActionEventHandler(DependencyManager dm) {
@@ -17,10 +23,25 @@ public class MouseActionEventHandler extends AbstractEventHandler<MouseAction> {
@InjectDependency
private EventManager eventManager;
@InjectState
private GameState gameState;
@Override
public void handle(MouseAction event) {
if (gameState.getScreen() != null) {
gameState.getScreen().handleMouseAction(event);
return;
}
switch (event.getActionType()) {
case MOVE -> eventManager.emitEvent(new MouseMoveEvent(event));
case CLICK_RELEASE -> {
Optional<GameObject> object = gameState.getCurrentRoom().getObjects().stream().filter(GameObject::isSelected).findFirst();
if (object.isEmpty()) return;
((Interactable) object.get()).interact(dm);
}
}
}
}

View File

@@ -7,6 +7,7 @@ import cz.jzitnik.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.PlayerMoveEvent;
import cz.jzitnik.events.RerenderScreen;
import cz.jzitnik.events.RoomChangeEvent;
import cz.jzitnik.game.GameRoom;
import cz.jzitnik.game.GameState;
import cz.jzitnik.game.Player;
@@ -55,24 +56,45 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
int originalPlayerY = playerCords.getY();
switch (keyStroke.getCharacter()) {
case 'w' -> {
if (originalPlayerY <= 10) return;
if (originalPlayerY <= 10) {
if (originalPlayerX >= 80 && originalPlayerX <= 105) {
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.TOP));
}
return;
}
playerCords.updateCords(player.getPlayerCords().getX(), playerCords.getY() - 5);
}
case 'a' -> {
if (originalPlayerX <= 30) return;
if (originalPlayerX <= 30) {
if (originalPlayerY >= 35 && originalPlayerY <= 65) {
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.LEFT));
}
return;
}
playerCords.updateCords(player.getPlayerCords().getX() - 5, playerCords.getY());
}
case 's' -> {
if (originalPlayerY >= 110) return;
if (originalPlayerY >= 110) {
if (originalPlayerX >= 75 && originalPlayerX <= 105) {
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.BOTTOM));
}
return;
}
playerCords.updateCords(player.getPlayerCords().getX(), playerCords.getY() + 5);
}
case 'd' -> {
if (originalPlayerX >= 155) return;
if (originalPlayerX >= 155) {
if (originalPlayerY >= 40 && originalPlayerY <= 60) {
eventManager.emitEvent(new RoomChangeEvent(FullRoomDrawHandler.DoorPosition.RIGHT));
}
return;
}
playerCords.updateCords(player.getPlayerCords().getX() + 5, playerCords.getY());
}
}
int newPlayerX = playerCords.getX();
int newPlayerY = playerCords.getY();
log.debug("x: {}, y: {}", newPlayerX, newPlayerY);
BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, player);
int forStartX = Math.min(originalPlayerX, newPlayerX);
int forStartY = Math.min(originalPlayerY, newPlayerY);

View File

@@ -0,0 +1,54 @@
package cz.jzitnik.events.handlers;
import cz.jzitnik.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.FullRoomDraw;
import cz.jzitnik.events.RoomChangeEvent;
import cz.jzitnik.game.GameRoom;
import cz.jzitnik.game.GameState;
import cz.jzitnik.game.utils.RoomCords;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.events.AbstractEventHandler;
import cz.jzitnik.utils.events.EventManager;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@EventHandler(RoomChangeEvent.class)
public class RoomChangeEventHandler extends AbstractEventHandler<RoomChangeEvent> {
public RoomChangeEventHandler(DependencyManager dm) {
super(dm);
}
@InjectState
private GameState gameState;
@InjectDependency
private EventManager eventManager;
@Override
public void handle(RoomChangeEvent event) {
RoomCords playerCords = gameState.getPlayer().getPlayerCords();
GameRoom currentRoom = gameState.getCurrentRoom();
GameRoom newRoom = switch (event.door()) {
case LEFT -> currentRoom.getLeft();
case RIGHT -> currentRoom.getRight();
case TOP -> currentRoom.getUp();
case BOTTOM -> currentRoom.getDown();
};
if (newRoom == null) {
return;
}
switch (event.door()) {
case LEFT -> playerCords.updateCords(155, 60);
case RIGHT -> playerCords.updateCords(30, 50);
case TOP -> playerCords.updateCords(90, 110);
case BOTTOM -> playerCords.updateCords(85, 10);
}
gameState.setCurrentRoom(newRoom);
eventManager.emitEvent(new FullRoomDraw());
}
}

View File

@@ -41,6 +41,6 @@ public class TerminalResizeEventHandler extends AbstractEventHandler<TerminalRes
}
screenBuffer.setRenderedBuffer(buffer);
eventManager.emitEvent(new FullRoomDraw());
eventManager.emitEvent(new FullRoomDraw(true));
}
}

View File

@@ -17,9 +17,12 @@ public class GameSetup {
public void setup() {
GameRoom mainRoom = new GameRoom(ResourceManager.Resource.ROOM1);
GameRoom rightRoom = new GameRoom(ResourceManager.Resource.ROOM2);
GameRoom topRightRoom = new GameRoom(ResourceManager.Resource.ROOM3);
mainRoom.setRight(rightRoom);
rightRoom.setLeft(mainRoom);
rightRoom.setUp(topRightRoom);
topRightRoom.setDown(rightRoom);
Chest chest = new Chest(resourceManager, new RoomCords(100, 45));
mainRoom.addObject(chest);

View File

@@ -1,6 +1,8 @@
package cz.jzitnik.game;
import cz.jzitnik.annotations.State;
import cz.jzitnik.game.objects.Interactable;
import cz.jzitnik.screens.Screen;
import lombok.Getter;
import lombok.Setter;
@@ -10,4 +12,7 @@ import lombok.Setter;
public class GameState {
private GameRoom currentRoom;
private Player player;
private Interactable interacting;
private Screen screen;
}

View File

@@ -1,10 +1,28 @@
package cz.jzitnik.game.objects;
import cz.jzitnik.game.GameState;
import cz.jzitnik.game.ResourceManager;
import cz.jzitnik.game.utils.RoomCords;
import cz.jzitnik.screens.ChestScreen;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.StateManager;
import lombok.extern.slf4j.Slf4j;
public final class Chest extends GameObject {
@Slf4j
public final class Chest extends GameObject implements Interactable {
public Chest(ResourceManager resourceManager, RoomCords cords) {
super(resourceManager.getResource(ResourceManager.Resource.CHEST), cords, true);
}
@Override
public void interact(DependencyManager dm) {
log.debug("Interacted with chest");
StateManager sm = dm.getDependencyOrThrow(StateManager.class);
GameState gameState = sm.getOrThrow(GameState.class);
gameState.setInteracting(this);
ChestScreen chestScreen = dm.getDependencyOrThrow(ChestScreen.class);
gameState.setScreen(chestScreen);
chestScreen.initialRender();
}
}

View File

@@ -0,0 +1,7 @@
package cz.jzitnik.game.objects;
import cz.jzitnik.utils.DependencyManager;
public interface Interactable {
void interact(DependencyManager dm);
}

View File

@@ -0,0 +1,23 @@
package cz.jzitnik.screens;
import cz.jzitnik.annotations.Dependency;
import cz.jzitnik.events.KeyboardPressEvent;
import cz.jzitnik.events.MouseAction;
@Dependency
public final class ChestScreen extends Screen {
@Override
public void initialRender() {
}
@Override
public void handleMouseAction(MouseAction event) {
}
@Override
public void handleKeybordAction(KeyboardPressEvent event) {
}
}

View File

@@ -0,0 +1,10 @@
package cz.jzitnik.screens;
import cz.jzitnik.events.KeyboardPressEvent;
import cz.jzitnik.events.MouseAction;
public sealed abstract class Screen permits ChestScreen {
public abstract void initialRender();
public abstract void handleMouseAction(MouseAction event);
public abstract void handleKeybordAction(KeyboardPressEvent event);
}