Improved ghost-move - now ghoest doesnt get stuck

This commit is contained in:
Urban Modig
2025-08-17 20:49:44 +02:00
parent 15757da2cf
commit a2b9b2264e
2 changed files with 28 additions and 27 deletions

View File

@ -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;
}

View File

@ -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) {
@ -80,24 +83,23 @@ 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 (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(direction, newPosition);
Point destination = collisionChecker.canMoveTo(intendedDirection, newPosition);
if (destination != null) {
position = destination;
}
@ -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<Direction> options, Point target) {
Direction best = options.getFirst();
private Direction chooseDirection(List<Direction> options, Point target, Direction prevDirection) {
List<Direction> 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);