refactor: Reworked collision system
This commit is contained in:
@@ -6,6 +6,6 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@Config
|
||||
public class Debugging {
|
||||
private final boolean renderColliders = false;
|
||||
private final boolean renderPlayerCollider = false;
|
||||
private final boolean renderColliders = true;
|
||||
private final boolean renderPlayerCollider = true;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
|
||||
}
|
||||
return;
|
||||
}
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() - moveStep);
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() - moveStep, player.getCollider());
|
||||
player.setPlayerRotation(Player.PlayerRotation.BACK);
|
||||
}
|
||||
case 'a' -> {
|
||||
@@ -98,7 +98,7 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
|
||||
}
|
||||
return;
|
||||
}
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() - moveStep, playerCords.getY());
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() - moveStep, playerCords.getY(), player.getCollider());
|
||||
player.setPlayerRotation(Player.PlayerRotation.LEFT);
|
||||
}
|
||||
case 's' -> {
|
||||
@@ -109,7 +109,7 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
|
||||
}
|
||||
return;
|
||||
}
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() + moveStep);
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX(), playerCords.getY() + moveStep, player.getCollider());
|
||||
player.setPlayerRotation(Player.PlayerRotation.FRONT);
|
||||
}
|
||||
case 'd' -> {
|
||||
@@ -120,7 +120,7 @@ public class PlayerMoveEventHandler extends AbstractEventHandler<PlayerMoveEvent
|
||||
}
|
||||
return;
|
||||
}
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() + moveStep, playerCords.getY());
|
||||
playerCords.updateCordsWithColliders(currentRoom.getColliders(), player.getPlayerCords().getX() + moveStep, playerCords.getY(), player.getCollider());
|
||||
player.setPlayerRotation(Player.PlayerRotation.RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,19 @@ public class GameRoomPart {
|
||||
private RoomCords end;
|
||||
|
||||
public boolean isWithin(RoomCords cords) {
|
||||
return
|
||||
cords.getX() >= start.getX() &&
|
||||
cords.getX() <= end.getX() &&
|
||||
cords.getY() >= start.getY() &&
|
||||
cords.getY() <= end.getY();
|
||||
return cords.getX() >= start.getX() &&
|
||||
cords.getX() <= end.getX() &&
|
||||
cords.getY() >= start.getY() &&
|
||||
cords.getY() <= end.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this GameRoomPart overlaps with another.
|
||||
*/
|
||||
public boolean isOverlapping(GameRoomPart other) {
|
||||
return start.getX() <= other.getEnd().getX() &&
|
||||
end.getX() >= other.getStart().getX() &&
|
||||
start.getY() <= other.getEnd().getY() &&
|
||||
end.getY() >= other.getStart().getY();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public class Player {
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
|
||||
private final RoomCords playerCords;
|
||||
private final GameRoomPart collider;
|
||||
private final GameItem[] inventory = new GameItem[Inventory.ITEMS_X * Inventory.ITEMS_Y];
|
||||
@Setter
|
||||
private PlayerRotation playerRotation = PlayerRotation.FRONT;
|
||||
|
||||
@@ -2,6 +2,7 @@ package cz.jzitnik.game.mobs;
|
||||
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.dialog.Dialog;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.states.DialogState;
|
||||
@@ -16,13 +17,13 @@ import java.awt.image.BufferedImage;
|
||||
public abstract class DialogMob extends Mob {
|
||||
protected Dialog dialog;
|
||||
|
||||
public DialogMob(BufferedImage texture, RoomTask[] tasks, RoomCords cords, Dialog dialog) {
|
||||
super(texture, tasks, cords);
|
||||
public DialogMob(BufferedImage texture, RoomTask[] tasks, RoomCords cords, GameRoomPart collider, Dialog dialog) {
|
||||
super(texture, tasks, cords, collider);
|
||||
this.dialog = dialog;
|
||||
}
|
||||
|
||||
public DialogMob(BufferedImage texture, RoomTask task, RoomCords cords, Dialog dialog) {
|
||||
super(texture, task, cords);
|
||||
public DialogMob(BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider, Dialog dialog) {
|
||||
super(texture, task, cords, collider);
|
||||
this.dialog = dialog;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package cz.jzitnik.game.mobs;
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.events.RerenderPart;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.utils.DependencyManager;
|
||||
@@ -67,8 +68,8 @@ public abstract class HittableMob extends Mob {
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
|
||||
public HittableMob(BufferedImage texture, RoomTask task, RoomCords cords, int initialHealth) {
|
||||
super(texture, task, cords);
|
||||
public HittableMob(BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider, int initialHealth) {
|
||||
super(texture, task, cords, collider);
|
||||
health = initialHealth;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import cz.jzitnik.annotations.injectors.InjectState;
|
||||
import cz.jzitnik.events.DroppedItemRerender;
|
||||
import cz.jzitnik.events.InventoryRerender;
|
||||
import cz.jzitnik.game.GameRoom;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.GameState;
|
||||
import cz.jzitnik.game.Player;
|
||||
import cz.jzitnik.game.items.GameItem;
|
||||
@@ -29,13 +30,13 @@ public abstract class HittableMobDrops extends HittableMob {
|
||||
|
||||
private final Supplier<GameItem[]> itemDropSupplier;
|
||||
|
||||
public HittableMobDrops(BufferedImage texture, RoomTask task, RoomCords cords, int initialHealth, Supplier<GameItem[]> itemDropSupplier) {
|
||||
super(texture, task, cords, initialHealth);
|
||||
public HittableMobDrops(BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider, int initialHealth, Supplier<GameItem[]> itemDropSupplier) {
|
||||
super(texture, task, cords, collider, initialHealth);
|
||||
this.itemDropSupplier = itemDropSupplier;
|
||||
}
|
||||
|
||||
public HittableMobDrops(Supplier<GameItem> itemDropSupplier, BufferedImage texture, RoomTask task, RoomCords cords, int initialHealth) {
|
||||
super(texture, task, cords, initialHealth);
|
||||
public HittableMobDrops(Supplier<GameItem> itemDropSupplier, BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider, int initialHealth) {
|
||||
super(texture, task, cords, collider, initialHealth);
|
||||
this.itemDropSupplier = () -> new GameItem[]{
|
||||
itemDropSupplier.get()
|
||||
};
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package cz.jzitnik.game.mobs;
|
||||
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public abstract class HittableMobNoDrops extends HittableMob {
|
||||
public HittableMobNoDrops(BufferedImage texture, RoomTask task, RoomCords cords, int initialHealth) {
|
||||
super(texture, task, cords, initialHealth);
|
||||
public HittableMobNoDrops(BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider, int initialHealth) {
|
||||
super(texture, task, cords, collider, initialHealth);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cz.jzitnik.game.mobs;
|
||||
|
||||
import cz.jzitnik.annotations.injectors.InjectDependency;
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.utils.Renderable;
|
||||
import cz.jzitnik.game.utils.RoomCords;
|
||||
import cz.jzitnik.game.utils.Selectable;
|
||||
@@ -17,6 +18,7 @@ public abstract class Mob implements Renderable, Selectable {
|
||||
|
||||
protected RoomTask[] tasks;
|
||||
protected final RoomCords cords;
|
||||
protected final GameRoomPart collider;
|
||||
|
||||
@InjectDependency
|
||||
private RoomTaskScheduler roomTaskScheduler;
|
||||
@@ -28,16 +30,18 @@ public abstract class Mob implements Renderable, Selectable {
|
||||
roomTaskScheduler.registerNewMob(this, oldTasks);
|
||||
}
|
||||
|
||||
public Mob(BufferedImage texture, RoomTask task, RoomCords cords) {
|
||||
public Mob(BufferedImage texture, RoomTask task, RoomCords cords, GameRoomPart collider) {
|
||||
this.texture = texture;
|
||||
this.tasks = new RoomTask[] {task};
|
||||
this.cords = cords;
|
||||
this.collider = collider;
|
||||
}
|
||||
|
||||
public Mob(BufferedImage texture, RoomTask[] tasks, RoomCords cords) {
|
||||
public Mob(BufferedImage texture, RoomTask[] tasks, RoomCords cords, GameRoomPart collider) {
|
||||
this.texture = texture;
|
||||
this.tasks = tasks;
|
||||
this.cords = cords;
|
||||
this.collider = collider;
|
||||
}
|
||||
|
||||
@Setter
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MobFollowingPlayerTask extends RoomTask {
|
||||
protected static void moveMob(RoomCords playerCords, Mob mob, GameState gameState, int speed, ResourceManager resourceManager, TerminalState terminalState, ScreenBuffer screenBuffer, Debugging debugging, EventManager eventManager) {
|
||||
RoomCords mobCords = mob.getCords();
|
||||
List<GameRoomPart> solidParts = gameState.getCurrentRoom().getColliders();
|
||||
List<RoomCords> path = AStarAlg.findPath(mobCords, playerCords, solidParts);
|
||||
List<RoomCords> path = AStarAlg.findPath(mobCords, playerCords, solidParts, mob.getCollider());
|
||||
|
||||
if (path.size() > 1) {
|
||||
int targetIndex = Math.min(speed, path.size() - 1);
|
||||
|
||||
@@ -12,7 +12,7 @@ public class AStarAlg {
|
||||
private static final int MIN_Y = 10;
|
||||
private static final int MAX_Y = 113;
|
||||
|
||||
public static List<RoomCords> findPath(RoomCords start, RoomCords target, List<GameRoomPart> colliders) {
|
||||
public static List<RoomCords> findPath(RoomCords start, RoomCords target, List<GameRoomPart> colliders, GameRoomPart mobCollider) {
|
||||
PriorityQueue<Node> openSet = new PriorityQueue<>(Comparator.comparingInt(n -> n.f));
|
||||
Set<String> closedSet = new HashSet<>();
|
||||
|
||||
@@ -34,7 +34,7 @@ public class AStarAlg {
|
||||
String neighborKey = neighbor.x + "," + neighbor.y;
|
||||
if (closedSet.contains(neighborKey)) continue;
|
||||
|
||||
if (!isValidPosition(neighbor.x, neighbor.y, colliders)) {
|
||||
if (!isValidPosition(neighbor.x, neighbor.y, colliders, mobCollider)) {
|
||||
if (neighbor.x != target.getX() || neighbor.y != target.getY()) {
|
||||
continue;
|
||||
}
|
||||
@@ -68,14 +68,17 @@ public class AStarAlg {
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
private static boolean isValidPosition(int x, int y, List<GameRoomPart> colliders) {
|
||||
private static boolean isValidPosition(int x, int y, List<GameRoomPart> colliders, GameRoomPart mobCollider) {
|
||||
if (x < MIN_X || x > MAX_X) return false;
|
||||
|
||||
if (y < MIN_Y || y > MAX_Y) return false;
|
||||
|
||||
RoomCords temp = new RoomCords(x, y);
|
||||
var temp = new GameRoomPart(
|
||||
new RoomCords(mobCollider.getStart().getX() + x, mobCollider.getStart().getY() + y),
|
||||
new RoomCords(mobCollider.getEnd().getX() + x, mobCollider.getEnd().getY() + y)
|
||||
);
|
||||
for (GameRoomPart part : colliders) {
|
||||
if (part.isWithin(temp)) {
|
||||
if (part.isOverlapping(temp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ public class GameSetup {
|
||||
|
||||
gameState.setCurrentRoom(mainRoom);
|
||||
|
||||
gameState.setPlayer(new Player(new RoomCords(90, 100)));
|
||||
gameState.setPlayer(new Player(
|
||||
new RoomCords(90, 100),
|
||||
new GameRoomPart(
|
||||
new RoomCords(0, 52),
|
||||
new RoomCords(44, 78)
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cz.jzitnik.game.setup.enemies;
|
||||
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.dialog.Dialog;
|
||||
import cz.jzitnik.game.dialog.OnEnd;
|
||||
@@ -11,7 +12,12 @@ import cz.jzitnik.utils.roomtasks.RoomTask;
|
||||
|
||||
public class Pepa extends DialogMob {
|
||||
public Pepa(ResourceManager resourceManager, RoomCords cords) {
|
||||
super(resourceManager.getResource(ResourceManager.Resource.PLAYER_FRONT), new RoomTask[]{}, cords, null
|
||||
super(resourceManager.getResource(ResourceManager.Resource.PLAYER_FRONT), new RoomTask[]{}, cords,
|
||||
new GameRoomPart(
|
||||
new RoomCords(0, 52),
|
||||
new RoomCords(44, 78)
|
||||
),
|
||||
null
|
||||
);
|
||||
|
||||
dialog = new Dialog(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cz.jzitnik.game.setup.enemies;
|
||||
|
||||
import cz.jzitnik.game.GameRoomPart;
|
||||
import cz.jzitnik.game.ResourceManager;
|
||||
import cz.jzitnik.game.mobs.HittableMobDrops;
|
||||
import cz.jzitnik.game.mobs.tasks.EnemyPlayerHittingTask;
|
||||
@@ -12,7 +13,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class Zombie extends HittableMobDrops {
|
||||
public Zombie(ResourceManager resourceManager, RoomCords cords) {
|
||||
super(() -> new Apple(resourceManager), resourceManager.getResource(ResourceManager.Resource.PLAYER_FRONT), null, cords, 10);
|
||||
super(() -> new Apple(resourceManager), resourceManager.getResource(ResourceManager.Resource.PLAYER_FRONT), null, cords,
|
||||
new GameRoomPart(
|
||||
new RoomCords(0, 52),
|
||||
new RoomCords(44, 78)
|
||||
),
|
||||
10
|
||||
);
|
||||
tasks = new RoomTask[]{
|
||||
new MobFollowingPlayerTask(this, 1, 100),
|
||||
new EnemyPlayerHittingTask(this, 500, 15, () -> 5)
|
||||
|
||||
@@ -22,8 +22,8 @@ public class MainRoom extends GameRoom {
|
||||
new Apple(resourceManager)
|
||||
});
|
||||
addCollider(new GameRoomPart(
|
||||
new RoomCords(60, 10),
|
||||
new RoomCords(135, 15)
|
||||
new RoomCords(100, 45),
|
||||
new RoomCords(140, 67)
|
||||
));
|
||||
addObject(chest);
|
||||
|
||||
|
||||
@@ -23,8 +23,13 @@ public class RoomCords implements Cloneable {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void updateCordsWithColliders(List<GameRoomPart> colliders, int x, int y) {
|
||||
if (colliders.stream().anyMatch(collider -> collider.isWithin(new RoomCords(x, y)))) {
|
||||
public void updateCordsWithColliders(List<GameRoomPart> colliders, int x, int y, GameRoomPart playerCollider) {
|
||||
var normalizedPlayerCollider = new GameRoomPart(
|
||||
new RoomCords(playerCollider.getStart().getX() + x, playerCollider.getStart().getY() + y),
|
||||
new RoomCords(playerCollider.getEnd().getX() + x, playerCollider.getEnd().getY() + y)
|
||||
);
|
||||
|
||||
if (colliders.stream().anyMatch(collider -> collider.isOverlapping(normalizedPlayerCollider))) {
|
||||
return;
|
||||
}
|
||||
updateCords(x, y);
|
||||
|
||||
@@ -73,9 +73,9 @@ public class RerenderUtils {
|
||||
if (x >= player.getPlayerCords().getX() && x < player.getPlayerCords().getX() + playerTexture.getWidth() - 1 && y >= player.getPlayerCords().getY() && y <= player.getPlayerCords().getY() + playerTexture.getHeight() - 1) {
|
||||
int relativeX = x - player.getPlayerCords().getX();
|
||||
int relativeY = y - player.getPlayerCords().getY();
|
||||
var playerCollider = player.getCollider();
|
||||
|
||||
|
||||
if (debugging.isRenderPlayerCollider() && relativeX == 0 && relativeY == 0) {
|
||||
if (debugging.isRenderPlayerCollider() && playerCollider.isWithin(new RoomCords(relativeX, relativeY))) {
|
||||
return new PixelResult(0xFFFF0000, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user