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