feat: Recalculate mouse after player/enemy move
This commit is contained in:
@@ -42,7 +42,7 @@ public class Cli implements Runnable {
|
||||
terminal.setCursorPosition(null);
|
||||
terminal.doResizeIfNecessary();
|
||||
|
||||
terminal.getTerminal().addResizeListener((_, terminalSize) -> {
|
||||
terminal.getTerminal().addResizeListener((ignored, terminalSize) -> {
|
||||
terminal.doResizeIfNecessary();
|
||||
eventManager.emitEvent(new TerminalResizeEvent(terminalSize));
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import cz.jzitnik.annotations.EventHandler;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.events.RerenderScreen;
|
||||
import cz.jzitnik.game.Constants;
|
||||
import cz.jzitnik.states.RenderState;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.ui.pixels.Empty;
|
||||
@@ -25,12 +26,19 @@ public class CliHandler extends AbstractEventHandler<RerenderScreen> {
|
||||
@InjectState
|
||||
private ScreenBuffer screenBuffer;
|
||||
|
||||
@InjectState
|
||||
private RenderState renderState;
|
||||
|
||||
public CliHandler(DependencyManager dm) {
|
||||
super(dm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(RerenderScreen event) {
|
||||
if (renderState.isTerminalTooSmall()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var parts = event.parts();
|
||||
var buffer = screenBuffer.getRenderedBuffer();
|
||||
var terminalScreen = terminalState.getTerminalScreen();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cz.jzitnik.events.handlers;
|
||||
|
||||
import com.googlecode.lanterna.TerminalPosition;
|
||||
import com.googlecode.lanterna.input.MouseActionType;
|
||||
import cz.jzitnik.annotations.EventHandler;
|
||||
import cz.jzitnik.annotations.injectors.InjectConfig;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
@@ -29,7 +30,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -40,6 +40,8 @@ public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent>
|
||||
super(dm);
|
||||
}
|
||||
|
||||
private MouseMoveEvent lastEvent = new MouseMoveEvent(new MouseAction(MouseActionType.MOVE, 1, new TerminalPosition(0, 0)));
|
||||
|
||||
@InjectState
|
||||
private GameState gameState;
|
||||
|
||||
@@ -63,22 +65,34 @@ public class MouseMoveEventHandler extends AbstractEventHandler<MouseMoveEvent>
|
||||
|
||||
private double distancePointToRect(
|
||||
double px, double py,
|
||||
double left, double top,
|
||||
double right, double bottom) {
|
||||
double rectTopLeftX, double rectTopLeftY,
|
||||
double rectBottomRightX, double rectBottomRightY) {
|
||||
double minX = Math.min(rectTopLeftX, rectBottomRightX);
|
||||
double maxX = Math.max(rectTopLeftX, rectBottomRightX);
|
||||
double minY = Math.min(rectTopLeftY, rectBottomRightY);
|
||||
double maxY = Math.max(rectTopLeftY, rectBottomRightY);
|
||||
|
||||
// Clamp point to rectangle
|
||||
double closestX = Math.max(left, Math.min(px, right));
|
||||
double closestY = Math.max(top, Math.min(py, bottom));
|
||||
boolean isInside = (px > minX && px < maxX && py > minY && py < maxY);
|
||||
|
||||
double dx = px - closestX;
|
||||
double dy = py - closestY;
|
||||
if (isInside) {
|
||||
return 0;
|
||||
} else {
|
||||
double closestX = Math.max(minX, Math.min(px, maxX));
|
||||
double closestY = Math.max(minY, Math.min(py, maxY));
|
||||
double dx = px - closestX;
|
||||
double dy = py - closestY;
|
||||
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MouseMoveEvent event) {
|
||||
MouseAction mouseAction = event.getMouseAction();
|
||||
if (event.getMouseAction() != null) {
|
||||
this.lastEvent = event;
|
||||
}
|
||||
|
||||
MouseAction mouseAction = lastEvent.getMouseAction();
|
||||
int mouseX = mouseAction.getPosition().getColumn();
|
||||
int mouseY = mouseAction.getPosition().getRow();
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.config.Debugging;
|
||||
import cz.jzitnik.config.Logging;
|
||||
import cz.jzitnik.config.PlayerConfig;
|
||||
import cz.jzitnik.events.MouseMoveEvent;
|
||||
import cz.jzitnik.events.PlayerMoveEvent;
|
||||
import cz.jzitnik.events.RerenderScreen;
|
||||
import cz.jzitnik.events.RoomChangeEvent;
|
||||
@@ -25,6 +26,7 @@ import cz.jzitnik.ui.Stats;
|
||||
import cz.jzitnik.utils.DependencyManager;
|
||||
import cz.jzitnik.utils.RerenderUtils;
|
||||
import cz.jzitnik.utils.events.AbstractEventHandler;
|
||||
import cz.jzitnik.utils.events.Event;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -151,18 +153,21 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
|
||||
|
||||
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, currentRoom, room, player, playerTexture, screenBuffer, resourceManager, debugging);
|
||||
|
||||
eventManager.emitEvent(new RerenderScreen(
|
||||
new RerenderScreen.ScreenPart[]{
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
||||
),
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(Stats.OFFSET_X, Stats.OFFSET_X),
|
||||
new TerminalPosition(Stats.OFFSET_X + Stats.WIDTH, Stats.OFFSET_Y + Stats.HEIGHT)
|
||||
)
|
||||
}
|
||||
));
|
||||
eventManager.emitEvent(new Event[]{
|
||||
new MouseMoveEvent(null),
|
||||
new RerenderScreen(
|
||||
new RerenderScreen.ScreenPart[]{
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
||||
),
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(Stats.OFFSET_X, Stats.OFFSET_X),
|
||||
new TerminalPosition(Stats.OFFSET_X + Stats.WIDTH, Stats.OFFSET_Y + Stats.HEIGHT)
|
||||
)
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
public static enum SprintKey {
|
||||
|
||||
@@ -5,6 +5,7 @@ import cz.jzitnik.annotations.injectors.InjectConfig;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.config.Debugging;
|
||||
import cz.jzitnik.events.MouseMoveEvent;
|
||||
import cz.jzitnik.events.RerenderScreen;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.GameState;
|
||||
@@ -16,6 +17,7 @@ import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.states.ScreenBuffer;
|
||||
import cz.jzitnik.states.TerminalState;
|
||||
import cz.jzitnik.utils.RerenderUtils;
|
||||
import cz.jzitnik.utils.events.Event;
|
||||
import cz.jzitnik.utils.events.EventManager;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -81,12 +83,15 @@ public class MobFollowingPlayerTask extends RoomTask {
|
||||
|
||||
RerenderUtils.rerenderPart(forStartX, forEndX, forStartY, forEndY, startX, startY, gameState.getCurrentRoom(), room, player, playerTexture, screenBuffer, resourceManager, debugging);
|
||||
|
||||
eventManager.emitEvent(new RerenderScreen(
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
||||
eventManager.emitEvent(new Event[]{
|
||||
new MouseMoveEvent(null),
|
||||
new RerenderScreen(
|
||||
new RerenderScreen.ScreenPart(
|
||||
new TerminalPosition(forStartX + startX, forStartY + startY),
|
||||
new TerminalPosition(forEndX + 1 + startX, forEndY + startY)
|
||||
)
|
||||
)
|
||||
));
|
||||
});
|
||||
} else {
|
||||
log.debug("Mob is effectively at the target or trapped.");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class EventManager extends Thread {
|
||||
|
||||
private ExecutorService eventExecutor;
|
||||
private final HashMap<Class<? extends Event>, AbstractEventHandler<? extends Event>> handlers = new HashMap<>();
|
||||
private final BlockingQueue<Event> eventQueue = new LinkedBlockingQueue<>();
|
||||
private final BlockingQueue<EventRecord> eventQueue = new LinkedBlockingQueue<>();
|
||||
private final DependencyManager dependencyManager;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -33,7 +33,26 @@ public class EventManager extends Thread {
|
||||
}
|
||||
|
||||
public void emitEvent(Event event) {
|
||||
eventQueue.add(event);
|
||||
eventQueue.add(new EventRecord(new Event[]{event}));
|
||||
}
|
||||
|
||||
public void emitEvent(Event event, Runnable callback) {
|
||||
eventQueue.add(new EventRecord(new Event[]{event}, callback));
|
||||
}
|
||||
|
||||
public void emitEvent(Event[] events) {
|
||||
eventQueue.add(new EventRecord(events));
|
||||
}
|
||||
|
||||
public void emitEvent(Event[] events, Runnable callback) {
|
||||
eventQueue.add(new EventRecord(events, callback));
|
||||
}
|
||||
|
||||
private record EventRecord(Event[] events, Runnable callback) {
|
||||
public EventRecord(Event[] events) {
|
||||
this(events, () -> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -64,7 +83,7 @@ public class EventManager extends Thread {
|
||||
eventExecutor = Executors.newFixedThreadPool(threadPoolConfig.getEventThreadCount());
|
||||
while (runningState.isRunning()) {
|
||||
try {
|
||||
Event event = eventQueue.take();
|
||||
EventRecord event = eventQueue.take();
|
||||
handleEvent(event);
|
||||
} catch (InterruptedException e) {
|
||||
// The game is shutting down.
|
||||
@@ -76,18 +95,17 @@ public class EventManager extends Thread {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Event> void handleEvent(Event event) {
|
||||
T typedEvent = (T) event;
|
||||
AbstractEventHandler<T> handler = getHandler((Class<T>) event.getClass());
|
||||
|
||||
if (handler != null) {
|
||||
eventExecutor.submit(() -> {
|
||||
try {
|
||||
handler.handle(typedEvent);
|
||||
} catch (Exception e) {
|
||||
log.error("Error", e);
|
||||
private void handleEvent(EventRecord eventRecord) {
|
||||
eventExecutor.submit(() -> {
|
||||
try {
|
||||
for (Event event : eventRecord.events) {
|
||||
AbstractEventHandler<Event> handler = getHandler((Class<Event>) event.getClass());
|
||||
handler.handle(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
eventRecord.callback.run();
|
||||
} catch (Exception e) {
|
||||
log.error("Error", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user