Moved speeds to LevelManager

This commit is contained in:
Urban Modig
2025-08-31 19:53:38 +02:00
parent 2e9e7cc45e
commit 3a4a0a1824
6 changed files with 53 additions and 31 deletions

View File

@ -11,6 +11,7 @@ import se.urmo.game.graphics.SpriteSheetManager;
import se.urmo.game.main.Game; import se.urmo.game.main.Game;
import se.urmo.game.map.GameMap; import se.urmo.game.map.GameMap;
import se.urmo.game.state.GhostManager; import se.urmo.game.state.GhostManager;
import se.urmo.game.state.LevelManager;
import se.urmo.game.util.Direction; import se.urmo.game.util.Direction;
import se.urmo.game.util.MiscUtil; import se.urmo.game.util.MiscUtil;
import se.urmo.game.util.MyPoint; import se.urmo.game.util.MyPoint;
@ -27,11 +28,8 @@ import java.util.stream.Collectors;
public class Ghost extends BaseAnimated { public class Ghost extends BaseAnimated {
private static final double BASE_SPEED = 0.40; private static final double BASE_SPEED = 0.40;
private static final int WARNING_THRESHOLD = 180; // 3 seconds of warning private static final int WARNING_THRESHOLD = 180; // 3 seconds of warning
private static final int COLLISION_BOX_SIZE = 16;
public static final int GHOST_SIZE = 32; public static final int GHOST_SIZE = 32;
private static final int ANIMATION_UPDATE_FREQUENCY = 25; private static final int ANIMATION_UPDATE_FREQUENCY = 25;
private static final int COLLISION_BOX_OFFSET = COLLISION_BOX_SIZE / 2;
private static final BufferedImage COLLISION_BOX = MiscUtil.createOutlinedBox(COLLISION_BOX_SIZE, COLLISION_BOX_SIZE, Color.black, 2);
private static final int FRIGHTENED_DURATION_TICKS = 10 * Game.UPS_SET; private static final int FRIGHTENED_DURATION_TICKS = 10 * Game.UPS_SET;
private final GhostCollisionChecker collisionChecker; private final GhostCollisionChecker collisionChecker;
@ -39,6 +37,7 @@ public class Ghost extends BaseAnimated {
private final MyPoint startPos; private final MyPoint startPos;
private final BufferedImage[] fearAnimation; private final BufferedImage[] fearAnimation;
private final BufferedImage[] baseAnimation; private final BufferedImage[] baseAnimation;
private final LevelManager levelManager;
private MyPoint position; private MyPoint position;
private final GhostStrategy scaterStrategy; private final GhostStrategy scaterStrategy;
@ -52,7 +51,7 @@ public class Ghost extends BaseAnimated {
private boolean isBlinking = false; private boolean isBlinking = false;
public Ghost(GhostCollisionChecker collisionChecker, GhostStrategy strategy, GhostStrategy scaterStrategy, int animation) { public Ghost(GhostCollisionChecker collisionChecker, GhostStrategy strategy, GhostStrategy scaterStrategy, int animation, LevelManager levelManager) {
super(ANIMATION_UPDATE_FREQUENCY, GhostManager.MAX_SPRITE_FRAMES); super(ANIMATION_UPDATE_FREQUENCY, GhostManager.MAX_SPRITE_FRAMES);
this.collisionChecker = collisionChecker; this.collisionChecker = collisionChecker;
this.chaseStrategy = strategy; this.chaseStrategy = strategy;
@ -66,6 +65,7 @@ public class Ghost extends BaseAnimated {
startPos = position; startPos = position;
this.currentStrategy = chaseStrategy; this.currentStrategy = chaseStrategy;
this.animation = baseAnimation; this.animation = baseAnimation;
this.levelManager = levelManager;
} }
public void draw(Graphics g) { public void draw(Graphics g) {
@ -123,7 +123,7 @@ public class Ghost extends BaseAnimated {
} }
private double getSpeed() { private double getSpeed() {
return BASE_SPEED * 0.75; return BASE_SPEED * levelManager.getGhostSpeed();
} }
private void moveTo(MyPoint newPosition) { private void moveTo(MyPoint newPosition) {
@ -190,20 +190,6 @@ public class Ghost extends BaseAnimated {
return best; return best;
} }
// private void updateAnimationTick() {
// if (moving) {
// aniTick++;
// if (aniTick >= ANIMATION_UPDATE_FREQUENCY) {
// aniTick = 0;
// aniIndex++;
// if (aniIndex >= GhostManager.MAX_SPRITE_FRAMES) {
// aniIndex = 0;
// }
//
// }
// }
// }
public void setMode(GhostMode mode) { public void setMode(GhostMode mode) {
this.mode = mode; this.mode = mode;
switch (mode) { switch (mode) {

View File

@ -5,6 +5,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import se.urmo.game.collision.CollisionChecker; import se.urmo.game.collision.CollisionChecker;
import se.urmo.game.entities.BaseAnimated; import se.urmo.game.entities.BaseAnimated;
import se.urmo.game.state.LevelManager;
import se.urmo.game.util.Direction; import se.urmo.game.util.Direction;
import se.urmo.game.map.GameMap; import se.urmo.game.map.GameMap;
import se.urmo.game.util.LoadSave; import se.urmo.game.util.LoadSave;
@ -28,18 +29,22 @@ public class PacMan extends BaseAnimated {
private final BufferedImage[][] spriteSheets; private final BufferedImage[][] spriteSheets;
private MyPoint position; private MyPoint position;
private final CollisionChecker collisionChecker; private final CollisionChecker collisionChecker;
private final LevelManager levelManager;
@Setter @Setter
@Getter @Getter
private Direction direction = Direction.NONE; private Direction direction = Direction.NONE;
private double pacmanLevelSpeed;
public PacMan(CollisionChecker collisionChecker) { public PacMan(CollisionChecker collisionChecker, LevelManager levelManager) {
super(ANIMATION_UPDATE_FREQUENCY, 4); super(ANIMATION_UPDATE_FREQUENCY, 4);
this.collisionChecker = collisionChecker; this.collisionChecker = collisionChecker;
this.levelManager = levelManager;
this.position = new MyPoint( this.position = new MyPoint(
26 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X, 26 * GameMap.MAP_TILESIZE + GameMap.OFFSET_X,
13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + ((double) GameMap.MAP_TILESIZE / 2)); 13 * GameMap.MAP_TILESIZE + GameMap.OFFSET_Y + ((double) GameMap.MAP_TILESIZE / 2));
this.startPosition = this.position; this.startPosition = this.position;
this.spriteSheets = loadAnimation(); this.spriteSheets = loadAnimation();
this.pacmanLevelSpeed = this.levelManager.getPacmanLevelSpeed();
} }
private BufferedImage[][] loadAnimation() { private BufferedImage[][] loadAnimation() {
@ -93,7 +98,7 @@ public class PacMan extends BaseAnimated {
} }
private double getSpeed() { private double getSpeed() {
return BASE_SPEED * 0.8; return BASE_SPEED * pacmanLevelSpeed;
} }
public double distanceTo(Point point) { public double distanceTo(Point point) {

View File

@ -19,7 +19,7 @@ public class FruitManager {
public void dotEaten() { public void dotEaten() {
dotsEaten++; dotsEaten++;
if (dotsEaten == 10 || dotsEaten == 170) { if (dotsEaten == 10 || dotsEaten == 170) {
spawnFruit(levelManager.getLevel()); spawnFruit(levelManager.getCurrentLevel().getLevel());
} }
} }

View File

@ -30,6 +30,7 @@ public class GhostManager {
public static final int CLYDE_ANIMATION = 3; public static final int CLYDE_ANIMATION = 3;
@Getter @Getter
private final List<Ghost> ghosts = new ArrayList<>(); private final List<Ghost> ghosts = new ArrayList<>();
private final LevelManager levelManager;
private long lastModeSwitchTime; private long lastModeSwitchTime;
private int phaseIndex = 0; private int phaseIndex = 0;
@ -42,15 +43,17 @@ public class GhostManager {
5000, Integer.MAX_VALUE // scatter 5s, then chase forever 5000, Integer.MAX_VALUE // scatter 5s, then chase forever
}; };
public GhostManager(GhostCollisionChecker ghostCollisionChecker, AnimationManager animationManager) { public GhostManager(GhostCollisionChecker ghostCollisionChecker, AnimationManager animationManager, LevelManager levelManager) {
this.levelManager = levelManager;
// Create ghosts with their strategies // Create ghosts with their strategies
Ghost blinky = new Ghost(ghostCollisionChecker, new BlinkyStrategy(), new ScatterToTopRight(), BLINKY_ANIMATION); Ghost blinky = new Ghost(ghostCollisionChecker, new BlinkyStrategy(), new ScatterToTopRight(), BLINKY_ANIMATION, levelManager);
ghosts.add(blinky); ghosts.add(blinky);
ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(), new ScatterToTopLeft(), PINKY_ANIMATION)); ghosts.add(new Ghost(ghostCollisionChecker, new PinkyStrategy(), new ScatterToTopLeft(), PINKY_ANIMATION, levelManager));
ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), INKY_ANIMATION)); ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), INKY_ANIMATION, levelManager));
ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), CLYDE_ANIMATION)); ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), CLYDE_ANIMATION, levelManager));
ghosts.forEach(animationManager::register); ghosts.forEach(animationManager::register);
setMode(GhostMode.CHASE); setMode(GhostMode.CHASE);
} }

View File

@ -3,6 +3,34 @@ package se.urmo.game.state;
import lombok.Getter; import lombok.Getter;
public class LevelManager { public class LevelManager {
@Getter @Getter
private int level = 1; public enum Level {
LEVEL1(1,6000, 0.75, 0.85, FruitType.CHERRY);
private final int frightendedDuration;
private final double ghostSpeed;
private final double pacmanSpeed;
private final FruitType fruitType;
private final int level;
Level(int level, int frightendedDuration, double ghostSpeed, double pacmanSpeed, FruitType fruitType) {
this.level = level;
this.frightendedDuration = frightendedDuration;
this.ghostSpeed = ghostSpeed;
this.pacmanSpeed = pacmanSpeed;
this.fruitType = fruitType;
}
public static Level forLevel(int i) {
return Level.values()[i];
}
}
@Getter
private Level currentLevel = Level.LEVEL1;
public double getPacmanLevelSpeed() {
return currentLevel.pacmanSpeed;
}
public double getGhostSpeed() {
return currentLevel.ghostSpeed;
}
} }

View File

@ -37,10 +37,10 @@ public class PlayingState implements GameState {
this.gameStateManager = gameStateManager; this.gameStateManager = gameStateManager;
this.map = new GameMap("maps/map1.csv"); this.map = new GameMap("maps/map1.csv");
this.animationManager = new AnimationManager(); this.animationManager = new AnimationManager();
this.pacman = new PacMan(new CollisionChecker(map));
animationManager.register(pacman);
this.ghostManager = new GhostManager(new GhostCollisionChecker(map), animationManager);
this.levelManager = new LevelManager(); this.levelManager = new LevelManager();
this.pacman = new PacMan(new CollisionChecker(map), levelManager);
this.animationManager.register(pacman);
this.ghostManager = new GhostManager(new GhostCollisionChecker(map), animationManager, levelManager);
this.fruitManager = new FruitManager(levelManager); this.fruitManager = new FruitManager(levelManager);
this.arcadeFont = loadArcadeFont(); this.arcadeFont = loadArcadeFont();
} }