Added remaining ghosts incl. movment-strategies
This commit is contained in:
@ -6,7 +6,7 @@ import java.awt.Point;
|
|||||||
|
|
||||||
public class BlinkyStrategy implements GhostStrategy {
|
public class BlinkyStrategy implements GhostStrategy {
|
||||||
@Override
|
@Override
|
||||||
public Point chooseTarget(PacMan pacman, GameMap map) {
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
return pacman.getTilePosition();
|
return pacman.getTilePosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/main/java/se/urmo/game/entities/ClydeStrategy.java
Normal file
21
src/main/java/se/urmo/game/entities/ClydeStrategy.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import se.urmo.game.map.GameMap;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
public class ClydeStrategy implements GhostStrategy {
|
||||||
|
@Override
|
||||||
|
public Point chooseTarget(Ghost clyde, PacMan pacman, GameMap map) {
|
||||||
|
Point pacTile = pacman.getTilePosition();
|
||||||
|
Point clydeTile = clyde.getPosition(); // ghost’s current tile
|
||||||
|
|
||||||
|
double distance = pacTile.distance(clydeTile);
|
||||||
|
|
||||||
|
if (distance > 8) {
|
||||||
|
return pacTile; // chase Pac-Man
|
||||||
|
} else {
|
||||||
|
return new Point(0, map.getHeight() - 1); // retreat to corner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package se.urmo.game.entities;
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import se.urmo.game.collision.GhostCollisionChecker;
|
import se.urmo.game.collision.GhostCollisionChecker;
|
||||||
import se.urmo.game.map.GameMap;
|
import se.urmo.game.map.GameMap;
|
||||||
@ -11,8 +12,6 @@ import java.awt.Color;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -29,6 +28,7 @@ public class Ghost {
|
|||||||
|
|
||||||
private final GhostCollisionChecker collisionChecker;
|
private final GhostCollisionChecker collisionChecker;
|
||||||
private final GhostStrategy chaseStrategy;
|
private final GhostStrategy chaseStrategy;
|
||||||
|
@Getter
|
||||||
private Point position;
|
private Point position;
|
||||||
|
|
||||||
private boolean moving = true;
|
private boolean moving = true;
|
||||||
@ -81,7 +81,7 @@ public class Ghost {
|
|||||||
prevDirection = direction;
|
prevDirection = direction;
|
||||||
direction = chooseDirection(
|
direction = chooseDirection(
|
||||||
prioritize(collisionChecker.calculateDirectionAlternatives(position)),
|
prioritize(collisionChecker.calculateDirectionAlternatives(position)),
|
||||||
currentStrategy.chooseTarget(pacman, map));
|
currentStrategy.chooseTarget(this, pacman, map));
|
||||||
log.info("selecting direction {}", direction);
|
log.info("selecting direction {}", direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,4 +167,5 @@ public class Ghost {
|
|||||||
case EATEN -> currentStrategy = null;
|
case EATEN -> currentStrategy = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,5 +5,5 @@ import se.urmo.game.map.GameMap;
|
|||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
|
||||||
public interface GhostStrategy {
|
public interface GhostStrategy {
|
||||||
Point chooseTarget(PacMan pacman, GameMap map);
|
Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map);
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/main/java/se/urmo/game/entities/InkyStrategy.java
Normal file
42
src/main/java/se/urmo/game/entities/InkyStrategy.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import se.urmo.game.map.GameMap;
|
||||||
|
import se.urmo.game.util.Direction;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
public class InkyStrategy implements GhostStrategy {
|
||||||
|
private final Ghost blinky;
|
||||||
|
|
||||||
|
public InkyStrategy(Ghost blinky) {
|
||||||
|
this.blinky = blinky;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
|
// 1. Two tiles ahead of pacman
|
||||||
|
Direction pacmanDir = pacman.getDirection();
|
||||||
|
Point pacmanPos = pacman.getTilePosition();
|
||||||
|
Point ahead = switch (pacmanDir){
|
||||||
|
case RIGHT -> new Point(pacmanPos.x + 8 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
||||||
|
case LEFT -> new Point(pacmanPos.x - 8 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
||||||
|
case DOWN -> new Point(pacmanPos.x, pacmanPos.y + 8 * GameMap.MAP_TILESIZE);
|
||||||
|
case UP -> new Point(pacmanPos.x, pacmanPos.y - 8 * GameMap.MAP_TILESIZE);
|
||||||
|
case NONE -> pacmanPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Vector from blinky to that tile
|
||||||
|
Point blinkyPos = blinky.getPosition();
|
||||||
|
int vx = ahead.x - blinkyPos.x;
|
||||||
|
int vy = ahead.y - blinkyPos.y;
|
||||||
|
|
||||||
|
// 3. Double the vector
|
||||||
|
Point target = new Point(
|
||||||
|
blinkyPos.x + 2 * vx,
|
||||||
|
blinkyPos.y + 2 * vy
|
||||||
|
);
|
||||||
|
|
||||||
|
return target;
|
||||||
|
// (Optional: clamp inside map boundaries)
|
||||||
|
//return map.clampToBounds(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,14 +7,14 @@ import java.awt.Point;
|
|||||||
|
|
||||||
public class PinkyStrategy implements GhostStrategy{
|
public class PinkyStrategy implements GhostStrategy{
|
||||||
@Override
|
@Override
|
||||||
public Point chooseTarget(PacMan pacman, GameMap map) {
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
Direction pacmanDir = pacman.getDirection();
|
Direction pacmanDir = pacman.getDirection();
|
||||||
Point pacmanPos = pacman.getTilePosition();
|
Point pacmanPos = pacman.getTilePosition();
|
||||||
return switch (pacmanDir){
|
return switch (pacmanDir){
|
||||||
case RIGHT -> new Point(pacmanPos.x + 4 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
case RIGHT -> new Point(pacmanPos.x + 8 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
||||||
case LEFT -> new Point(pacmanPos.x - 4 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
case LEFT -> new Point(pacmanPos.x - 8 * GameMap.MAP_TILESIZE, pacmanPos.y);
|
||||||
case DOWN -> new Point(pacmanPos.x, pacmanPos.y + 4 * GameMap.MAP_TILESIZE);
|
case DOWN -> new Point(pacmanPos.x, pacmanPos.y + 8 * GameMap.MAP_TILESIZE);
|
||||||
case UP -> new Point(pacmanPos.x, pacmanPos.y - 4 * GameMap.MAP_TILESIZE);
|
case UP -> new Point(pacmanPos.x, pacmanPos.y - 8 * GameMap.MAP_TILESIZE);
|
||||||
case NONE -> pacmanPos;
|
case NONE -> pacmanPos;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main/java/se/urmo/game/entities/ScatterToBottomLeft.java
Normal file
12
src/main/java/se/urmo/game/entities/ScatterToBottomLeft.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import se.urmo.game.map.GameMap;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
public class ScatterToBottomLeft implements GhostStrategy {
|
||||||
|
@Override
|
||||||
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
|
return new Point(GameMap.OFFSET_X, (map.columns() * GameMap.MAP_TILESIZE) + GameMap.OFFSET_Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import se.urmo.game.map.GameMap;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
public class ScatterToBottomRight implements GhostStrategy {
|
||||||
|
@Override
|
||||||
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
|
return new Point(map.getHeight() - 1, map.getHeight() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/java/se/urmo/game/entities/ScatterToTopLeft.java
Normal file
13
src/main/java/se/urmo/game/entities/ScatterToTopLeft.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package se.urmo.game.entities;
|
||||||
|
|
||||||
|
import se.urmo.game.map.GameMap;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
public class ScatterToTopLeft implements GhostStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
|
return new Point(GameMap.OFFSET_X, GameMap.OFFSET_Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import java.awt.Point;
|
|||||||
|
|
||||||
public class ScatterToTopRight implements GhostStrategy{
|
public class ScatterToTopRight implements GhostStrategy{
|
||||||
@Override
|
@Override
|
||||||
public Point chooseTarget(PacMan pacman, GameMap map) {
|
public Point chooseTarget(Ghost ghost, PacMan pacman, GameMap map) {
|
||||||
return new Point((map.columns() -1) * GameMap.MAP_TILESIZE, 0);
|
return new Point((map.columns() -1) * GameMap.MAP_TILESIZE + GameMap.OFFSET_X, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,6 +195,9 @@ public class GameMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int columns() {
|
public int columns() {
|
||||||
return (GamePanel.SCREEN_WIDTH - 2 * OFFSET_X) / MAP_TILESIZE;
|
return mapData[0].length;
|
||||||
|
}
|
||||||
|
public int rows() {
|
||||||
|
return mapData.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,15 @@ import lombok.Getter;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import se.urmo.game.collision.GhostCollisionChecker;
|
import se.urmo.game.collision.GhostCollisionChecker;
|
||||||
import se.urmo.game.entities.BlinkyStrategy;
|
import se.urmo.game.entities.BlinkyStrategy;
|
||||||
|
import se.urmo.game.entities.ClydeStrategy;
|
||||||
import se.urmo.game.entities.Ghost;
|
import se.urmo.game.entities.Ghost;
|
||||||
import se.urmo.game.entities.GhostMode;
|
import se.urmo.game.entities.GhostMode;
|
||||||
|
import se.urmo.game.entities.InkyStrategy;
|
||||||
import se.urmo.game.entities.PacMan;
|
import se.urmo.game.entities.PacMan;
|
||||||
import se.urmo.game.entities.PinkyStrategy;
|
import se.urmo.game.entities.PinkyStrategy;
|
||||||
|
import se.urmo.game.entities.ScatterToBottomLeft;
|
||||||
|
import se.urmo.game.entities.ScatterToBottomRight;
|
||||||
|
import se.urmo.game.entities.ScatterToTopLeft;
|
||||||
import se.urmo.game.entities.ScatterToTopRight;
|
import se.urmo.game.entities.ScatterToTopRight;
|
||||||
import se.urmo.game.map.GameMap;
|
import se.urmo.game.map.GameMap;
|
||||||
import se.urmo.game.util.LoadSave;
|
import se.urmo.game.util.LoadSave;
|
||||||
@ -39,11 +44,14 @@ public class GhostManager {
|
|||||||
|
|
||||||
public GhostManager(GhostCollisionChecker ghostCollisionChecker) {
|
public GhostManager(GhostCollisionChecker ghostCollisionChecker) {
|
||||||
loadAnimation();
|
loadAnimation();
|
||||||
|
|
||||||
// Create ghosts with their strategies
|
// Create ghosts with their strategies
|
||||||
ghosts.add(new Ghost(ghostCollisionChecker, new BlinkyStrategy(),new ScatterToTopLeft(), image[0]));
|
Ghost blinky = new Ghost(ghostCollisionChecker, new BlinkyStrategy(), new ScatterToTopRight(), image[0]);
|
||||||
ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(),new ScatterToTopRight(), image[1]));
|
ghosts.add(blinky);
|
||||||
//ghosts.add(new Ghost(240, 200, new InkyStrategy(), loader.getSprite("inky")));
|
ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(),new ScatterToTopLeft(), image[2]));
|
||||||
//ghosts.add(new Ghost(260, 200, new ClydeStrategy(), loader.getSprite("clyde")));
|
ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), image[1]));
|
||||||
|
Ghost clyde = new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), image[3]);
|
||||||
|
ghosts.add(clyde);
|
||||||
setMode(GhostMode.CHASE);
|
setMode(GhostMode.CHASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
package se.urmo.game.state;
|
|
||||||
|
|
||||||
import se.urmo.game.entities.GhostStrategy;
|
|
||||||
import se.urmo.game.entities.PacMan;
|
|
||||||
import se.urmo.game.map.GameMap;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public class ScatterToTopLeft implements GhostStrategy {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point chooseTarget(PacMan pacman, GameMap map) {
|
|
||||||
return new Point(1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user