From a2b9b2264e70cf8b343ed4c26a99759ba8f7758c Mon Sep 17 00:00:00 2001 From: Urban Modig Date: Sun, 17 Aug 2025 20:49:44 +0200 Subject: [PATCH] Improved ghost-move - now ghoest doesnt get stuck --- .../game/collision/GhostCollisionChecker.java | 4 +- .../java/se/urmo/game/entities/Ghost.java | 51 ++++++++++--------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java b/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java index 91489a2..18885e9 100644 --- a/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java +++ b/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java @@ -5,7 +5,6 @@ import se.urmo.game.map.GameMap; import se.urmo.game.util.Direction; import java.awt.Point; -import java.util.Collections; import java.util.List; @Slf4j @@ -23,7 +22,8 @@ public class GhostCollisionChecker { } public Point canMoveTo(Direction dir, Point pos) { - Point pp = new Point(pos.x + dir.dx * GameMap.MAP_TILESIZE/2, pos.y + dir.dy * GameMap.MAP_TILESIZE/2); + // -1 is because else we endup in next tile + Point pp = new Point(pos.x + dir.dx * (GameMap.MAP_TILESIZE/2 - 1), pos.y + dir.dy * (GameMap.MAP_TILESIZE/2 -1) ); return ! map.isSolid(pp.x, pp.y) ? pos : null; } diff --git a/src/main/java/se/urmo/game/entities/Ghost.java b/src/main/java/se/urmo/game/entities/Ghost.java index 5deb5e0..06b0acf 100644 --- a/src/main/java/se/urmo/game/entities/Ghost.java +++ b/src/main/java/se/urmo/game/entities/Ghost.java @@ -13,6 +13,7 @@ import java.awt.Graphics; import java.awt.Point; import java.awt.image.BufferedImage; import java.util.List; +import java.util.stream.Collectors; @Slf4j public class Ghost { @@ -35,6 +36,8 @@ public class Ghost { private int aniIndex = 0; private BufferedImage[] animation; private int movementTick = 0; + private Direction direction; + private Direction prevDirection; public Ghost(Game game, GhostCollisionChecker collisionChecker, GhostStrategy strategy) { @@ -79,26 +82,25 @@ public class Ghost { } private void updatePosition(PacMan pacman) { - if(movementTick >= GHOST_MOVEMENT_UPDATE_FREQUENCY) { - if(!isAlligned(position)){ - position = align(position); - log.debug("Aligned: {}", position); - return; + if (movementTick >= GHOST_MOVEMENT_UPDATE_FREQUENCY) { + if (isAlligned(position)) { + log.info("Evaluating possible directions"); + prevDirection = direction; + direction = chooseDirection( + collisionChecker.calculateDirectionAlternatives(position), + strategy.chooseTarget(pacman, null, null), + prevDirection); + log.info("selecting direction {}", direction); } - log.info("Evaluating possible directions"); - Direction intendedDirection = chooseDirection( - collisionChecker.calculateDirectionAlternatives(position), - strategy.chooseTarget(pacman, null, null)); - - - log.info("selecting direction {}", intendedDirection); Point newPosition = new Point( - position.x + intendedDirection.dx * GHOST_SPEED, - position.y + intendedDirection.dy * GHOST_SPEED); + position.x + direction.dx * GHOST_SPEED, + position.y + direction.dy * GHOST_SPEED); + log.debug("Next position {}", newPosition); - Point destination = collisionChecker.canMoveTo(intendedDirection, newPosition); - if(destination != null) { + Point destination = collisionChecker.canMoveTo(direction, newPosition); + + if (destination != null) { position = destination; } movementTick = 0; @@ -108,19 +110,18 @@ public class Ghost { private boolean isAlligned(Point pos) { int row = pos.x % GameMap.MAP_TILESIZE; int col = pos.y % GameMap.MAP_TILESIZE; - return row == GameMap.MAP_TILESIZE/2 || col == GameMap.MAP_TILESIZE /2; - } - private Point align(Point point){ - int row = point.x / GameMap.MAP_TILESIZE; - int col = point.y / GameMap.MAP_TILESIZE; - return new Point(row * GameMap.MAP_TILESIZE + GameMap.MAP_TILESIZE /2, col * GameMap.MAP_TILESIZE + GameMap.MAP_TILESIZE /2); + return row == GameMap.MAP_TILESIZE / 2 && col == GameMap.MAP_TILESIZE / 2; } - private Direction chooseDirection(List options, Point target) { - Direction best = options.getFirst(); + private Direction chooseDirection(List options, Point target, Direction prevDirection) { + List l = options.stream() + // remove any option to go back + .filter(d -> !(prevDirection != null && d.equals(prevDirection.opposite()))) + .toList(); + Direction best = l.getFirst(); double bestDist = Double.MAX_VALUE; - for (Direction d : options) { + for (Direction d : l) { int nx = position.x + d.dx * GameMap.MAP_TILESIZE; int ny = position.y + d.dy * GameMap.MAP_TILESIZE; double dist = target.distance(nx, ny);