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.map.GameMap;
import se.urmo.game.state.GhostManager;
import se.urmo.game.state.LevelManager;
import se.urmo.game.util.Direction;
import se.urmo.game.util.MiscUtil;
import se.urmo.game.util.MyPoint;
@ -27,11 +28,8 @@ import java.util.stream.Collectors;
public class Ghost extends BaseAnimated {
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;
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;
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 final GhostCollisionChecker collisionChecker;
@ -39,6 +37,7 @@ public class Ghost extends BaseAnimated {
private final MyPoint startPos;
private final BufferedImage[] fearAnimation;
private final BufferedImage[] baseAnimation;
private final LevelManager levelManager;
private MyPoint position;
private final GhostStrategy scaterStrategy;
@ -52,7 +51,7 @@ public class Ghost extends BaseAnimated {
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);
this.collisionChecker = collisionChecker;
this.chaseStrategy = strategy;
@ -66,6 +65,7 @@ public class Ghost extends BaseAnimated {
startPos = position;
this.currentStrategy = chaseStrategy;
this.animation = baseAnimation;
this.levelManager = levelManager;
}
public void draw(Graphics g) {
@ -123,7 +123,7 @@ public class Ghost extends BaseAnimated {
}
private double getSpeed() {
return BASE_SPEED * 0.75;
return BASE_SPEED * levelManager.getGhostSpeed();
}
private void moveTo(MyPoint newPosition) {
@ -190,20 +190,6 @@ public class Ghost extends BaseAnimated {
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) {
this.mode = mode;
switch (mode) {

View File

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

View File

@ -19,7 +19,7 @@ public class FruitManager {
public void dotEaten() {
dotsEaten++;
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;
@Getter
private final List<Ghost> ghosts = new ArrayList<>();
private final LevelManager levelManager;
private long lastModeSwitchTime;
private int phaseIndex = 0;
@ -42,15 +43,17 @@ public class GhostManager {
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
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(new Ghost(ghostCollisionChecker, new PinkyStrategy(), new ScatterToTopLeft(), PINKY_ANIMATION));
ghosts.add(new Ghost(ghostCollisionChecker,new InkyStrategy(blinky), new ScatterToBottomRight(), INKY_ANIMATION));
ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), CLYDE_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, levelManager));
ghosts.add(new Ghost(ghostCollisionChecker, new ClydeStrategy(), new ScatterToBottomLeft(), CLYDE_ANIMATION, levelManager));
ghosts.forEach(animationManager::register);
setMode(GhostMode.CHASE);
}

View File

@ -3,6 +3,34 @@ package se.urmo.game.state;
import lombok.Getter;
public class LevelManager {
@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.map = new GameMap("maps/map1.csv");
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.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.arcadeFont = loadArcadeFont();
}