diff --git a/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java b/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java index 7743e1b..f64323a 100644 --- a/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java +++ b/src/main/java/se/urmo/game/collision/GhostCollisionChecker.java @@ -1,6 +1,7 @@ package se.urmo.game.collision; import lombok.extern.slf4j.Slf4j; +import se.urmo.game.entities.MyPoint; import se.urmo.game.map.GameMap; import se.urmo.game.map.MapTile; import se.urmo.game.util.Direction; @@ -17,18 +18,20 @@ public class GhostCollisionChecker { this.map = map; } - public List calculateDirectionAlternatives(Point position) { - List intersection = map.directionAlternatives(position); + public List calculateDirectionAlternatives(MyPoint position) { + List intersection = map.directionAlternatives((int) position.x, (int) position.y); log.info("Possible travel directions: {}", intersection); return intersection; } - public Point canMoveTo(Direction dir, Point pos) { + public MyPoint canMoveTo(Direction dir, double x, double y) { // -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) ); + //Point pp = new Point((int) (x + dir.dx * (GameMap.MAP_TILESIZE/2 - 1)), (int) (y + dir.dy * (GameMap.MAP_TILESIZE/2 -1))); - return ! map.isSolid(pp) ? pos : null; + return ! map.isSolidXY( + (int) (x) + dir.dx * (GameMap.MAP_TILESIZE/2 - 1), + (int) (y) + dir.dy * (GameMap.MAP_TILESIZE/2 - 1)) ? new MyPoint(x,y) : null; } } diff --git a/src/main/java/se/urmo/game/entities/FearStrategy.java b/src/main/java/se/urmo/game/entities/FearStrategy.java index 8747a86..2b9ee77 100644 --- a/src/main/java/se/urmo/game/entities/FearStrategy.java +++ b/src/main/java/se/urmo/game/entities/FearStrategy.java @@ -14,7 +14,8 @@ public class FearStrategy implements GhostStrategy { public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) { // Frightened ghosts do not target Pacman. // Instead, they pick a random adjacent valid tile. - List neighbors = map.directionAlternatives(ghost.getPosition()); + Point ghostPos = ghost.getPosition(); + List neighbors = map.directionAlternatives(ghostPos.x, ghostPos.y); if (neighbors.isEmpty()) { return ghost.getPosition(); // stuck diff --git a/src/main/java/se/urmo/game/entities/Ghost.java b/src/main/java/se/urmo/game/entities/Ghost.java index 3edee17..2d7173a 100644 --- a/src/main/java/se/urmo/game/entities/Ghost.java +++ b/src/main/java/se/urmo/game/entities/Ghost.java @@ -21,9 +21,9 @@ import java.util.stream.Collectors; @Slf4j public class Ghost { + private static final double BASE_SPEED = 0.40; private static final int WARNING_THRESHOLD = 180; // 3 seconds of warning private static final int COLLISION_BOX_SIZE = 16; - private static final int GHOST_MOVEMENT_UPDATE_FREQUENCY = 2; public static final int GHOST_SIZE = 32; private static final int ANIMATION_UPDATE_FREQUENCY = 25; private static final int COLLISION_BOX_OFFSET = COLLISION_BOX_SIZE / 2; @@ -32,11 +32,12 @@ public class Ghost { private final GhostCollisionChecker collisionChecker; private final GhostStrategy chaseStrategy; - private final Point startPos; + private final MyPoint startPos; private final BufferedImage[] fearAnimation; private final BufferedImage[] baseAnimation; - @Getter - private Point position; + //@Getter + //private Point position; + private MyPoint position2; private boolean moving = true; private int aniTick = 0; @@ -53,18 +54,17 @@ public class Ghost { private boolean isBlinking = false; - public Ghost(GhostCollisionChecker collisionChecker, GhostStrategy strategy, GhostStrategy scaterStrategy, int animation) { this.collisionChecker = collisionChecker; this.chaseStrategy = strategy; this.scaterStrategy = scaterStrategy; - this.baseAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(animation);; - this.fearAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(8);; + this.baseAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(animation); + this.fearAnimation = SpriteSheetManager.get(SpriteLocation.GHOST).getAnimation(8); - position = new Point( - 13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X + (GameMap.MAP_TILESIZE / 2), - 4 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + (GameMap.MAP_TILESIZE / 2) ); - startPos = position; + position2 = new MyPoint( + 13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X + ((double) GameMap.MAP_TILESIZE / 2), + 4 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + ((double) GameMap.MAP_TILESIZE / 2)); + startPos = position2; this.currentStrategy = chaseStrategy; this.animation = baseAnimation; } @@ -72,20 +72,20 @@ public class Ghost { public void draw(Graphics g) { g.drawImage( animation[aniIndex], - position.x - GHOST_SIZE / 2, - position.y - GHOST_SIZE / 2, + (int) (position2.x - GHOST_SIZE / 2), + (int) (position2.y - GHOST_SIZE / 2), GHOST_SIZE, GHOST_SIZE, null); g.drawImage(COLLISION_BOX, - position.x - COLLISION_BOX_OFFSET, - position.y - COLLISION_BOX_OFFSET, + (int) (position2.x - COLLISION_BOX_OFFSET), + (int) (position2.y - COLLISION_BOX_OFFSET), COLLISION_BOX_SIZE, COLLISION_BOX_SIZE, null); } public void update(PacMan pacman, GameMap map) { updateAnimationTick(); - if(mode == GhostMode.FRIGHTENED){ + if (mode == GhostMode.FRIGHTENED) { updateInFrightendMode(); } updatePosition(pacman, map); @@ -93,31 +93,29 @@ public class Ghost { private void updateInFrightendMode() { frightenedTimer--; - if(frightenedTimer <= WARNING_THRESHOLD){ + if (frightenedTimer <= WARNING_THRESHOLD) { isBlinking = (frightenedTimer / 25) % 2 == 0; animation = isBlinking ? fearAnimation : baseAnimation; } - if(frightenedTimer <= 0){ + if (frightenedTimer <= 0) { setMode(GhostMode.CHASE); } } private void updatePosition(PacMan pacman, GameMap map) { - // only move ghost on update interval - this is basically ghost speed; - if (movementTick >= GHOST_MOVEMENT_UPDATE_FREQUENCY) { - if (map.isAligned(position)) { - //log.info("Evaluating possible directions"); - prevDirection = direction; - direction = chooseDirection( - prioritize(collisionChecker.calculateDirectionAlternatives(position)), - currentStrategy.chooseTarget(this, pacman, map)); - //log.info("selecting direction {}", direction); - } + if (map.isAligned(new Point((int) position2.x, (int) position2.y))) { + log.info("Evaluating possible directions"); + prevDirection = direction; + direction = chooseDirection( + prioritize(collisionChecker.calculateDirectionAlternatives(position2)), + currentStrategy.chooseTarget(this, pacman, map)); + log.info("selecting direction {}", direction); + } - moveTo(getNewPosition()); + moveTo(getNewPosition()); + + movementTick = 0; - movementTick = 0; - } else movementTick++; } /** @@ -126,20 +124,22 @@ public class Ghost { * * @return new position */ - private Point getNewPosition() { - Point point = new Point( - position.x + direction.dx, - position.y + direction.dy); - //log.debug("Next position {}", point); - return point; + private MyPoint getNewPosition() { + return new MyPoint( + position2.x + direction.dx * getSpeed(), + position2.y + direction.dy * getSpeed()); } - private void moveTo(Point newPosition) { - Point destination = collisionChecker.canMoveTo(direction, newPosition); + private double getSpeed() { + return BASE_SPEED * 0.75; + } + private void moveTo(MyPoint newPosition) { + MyPoint destination = collisionChecker.canMoveTo(direction, newPosition.x, newPosition.y); +log.info("Moving to {} from {}. Destination: {}", direction, position2, newPosition); if (destination != null) { - position = destination; + position2 = destination; } } @@ -170,8 +170,8 @@ public class Ghost { double bestDist = Double.MAX_VALUE; for (Direction d : directions) { - int nx = position.x + d.dx * GameMap.MAP_TILESIZE; - int ny = position.y + d.dy * GameMap.MAP_TILESIZE; + int nx = (int) position2.x + d.dx * GameMap.MAP_TILESIZE; + int ny = (int) position2.y + d.dy * GameMap.MAP_TILESIZE; double dist = target.distance(nx, ny); if (dist < bestDist) { bestDist = dist; @@ -218,6 +218,10 @@ public class Ghost { } public void resetPosition() { - position = startPos; + position2 = startPos; + } + + public Point getPosition() { + return new Point((int) position2.x, (int) position2.y); } } diff --git a/src/main/java/se/urmo/game/map/GameMap.java b/src/main/java/se/urmo/game/map/GameMap.java index 2b92d91..bcce658 100644 --- a/src/main/java/se/urmo/game/map/GameMap.java +++ b/src/main/java/se/urmo/game/map/GameMap.java @@ -94,8 +94,8 @@ public class GameMap { return b; } - public boolean isSolid(Point pos) { - return isSolid(screenToRow(pos), screenToCol(pos)); + public boolean isSolidXY(int screenX, int screenY) { + return isSolid(screenToRow(screenY), screenToCol(screenX)); } @@ -198,9 +198,9 @@ public class GameMap { } - public List directionAlternatives(Point screen) { - int row = (screen.y - GameMap.OFFSET_Y) / GameMap.MAP_TILESIZE; - int col = (screen.x - GameMap.OFFSET_X) / GameMap.MAP_TILESIZE; + public List directionAlternatives(int screenX, int screenY) { + int row = (screenY - GameMap.OFFSET_Y) / GameMap.MAP_TILESIZE; + int col = (screenX - GameMap.OFFSET_X) / GameMap.MAP_TILESIZE; record DirectionCheck(int rowOffset, int colOffset, Direction direction) {} log.debug("At [{}][{}]", row, col);