GameOverState WIP
This commit is contained in:
@ -12,17 +12,17 @@ import se.urmo.game.map.GameMap;
|
||||
import se.urmo.game.map.MapTile;
|
||||
import se.urmo.game.map.TileType;
|
||||
import se.urmo.game.util.Direction;
|
||||
import se.urmo.game.util.GameFonts;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Slf4j
|
||||
public class PlayingState implements GameState {
|
||||
public static final int REMAINING_LIVES = 0;
|
||||
private final Game game;
|
||||
private final GameStateManager gameStateManager;
|
||||
private final Font arcadeFont;
|
||||
private final GameOverState gameOverState;
|
||||
|
||||
// Core components
|
||||
private final GhostManager ghostManager;
|
||||
@ -34,9 +34,9 @@ public class PlayingState implements GameState {
|
||||
private GameMap map;
|
||||
|
||||
// Durations (tune to taste)
|
||||
private static final int READY_MS = 1500;
|
||||
private static final int LEVEL_COMPLETE_MS= 1500;
|
||||
private static final int LIFE_LOST_MS = 2000;
|
||||
private static final int READY_MS = 1500;
|
||||
private static final int LEVEL_COMPLETE_MS = 1500;
|
||||
private static final int LIFE_LOST_MS = 2000;
|
||||
|
||||
// Score/Lives
|
||||
private int score = 0;
|
||||
@ -48,9 +48,10 @@ public class PlayingState implements GameState {
|
||||
private long phaseStartMs = System.currentTimeMillis();
|
||||
private boolean deathInProgress;
|
||||
|
||||
public PlayingState(Game game, GameStateManager gameStateManager) {
|
||||
public PlayingState(Game game, GameStateManager gameStateManager, GameOverState gameOverState) {
|
||||
this.game = game;
|
||||
this.gameStateManager = gameStateManager;
|
||||
this.gameOverState = gameOverState;
|
||||
this.map = new GameMap("maps/map1.csv");
|
||||
this.animationManager = new AnimationManager();
|
||||
this.levelManager = new LevelManager();
|
||||
@ -58,7 +59,6 @@ public class PlayingState implements GameState {
|
||||
this.animationManager.register(pacman);
|
||||
this.ghostManager = new GhostManager(new GhostCollisionChecker(map), animationManager, levelManager);
|
||||
this.fruitManager = new FruitManager(levelManager);
|
||||
this.arcadeFont = loadArcadeFont();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,16 +88,20 @@ public class PlayingState implements GameState {
|
||||
case LIFE_LOST -> {
|
||||
// Freeze, then reset round (keep dot state)
|
||||
if (phaseElapsed() >= LIFE_LOST_MS) {
|
||||
deathInProgress = false;
|
||||
resetAfterLifeLost();
|
||||
setPhase(RoundPhase.READY);
|
||||
if (lives <= 0) {
|
||||
endGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetAfterLifeLost() {
|
||||
pacman.reset(); // to start tile, direction stopped
|
||||
ghostManager.reset(); // to house
|
||||
pacman.reset(); // to start tile, direction stopped
|
||||
ghostManager.reset(); // to house
|
||||
}
|
||||
|
||||
private void advanceLevel() {
|
||||
@ -122,14 +126,14 @@ public class PlayingState implements GameState {
|
||||
Point pacmanScreenPos = pacman.getPosition();
|
||||
MapTile tile = map.getTile(pacmanScreenPos);
|
||||
boolean wasRemoved = map.removeTileImage(pacmanScreenPos);
|
||||
if(wasRemoved && tile.getTileType() == TileType.LARGE_PELLET){
|
||||
if (wasRemoved && tile.getTileType() == TileType.LARGE_PELLET) {
|
||||
ghostManager.setFrightMode();
|
||||
}
|
||||
if(wasRemoved){
|
||||
if (wasRemoved) {
|
||||
dotsEaten++;
|
||||
fruitManager.dotEaten(dotsEaten);
|
||||
score+=tile.getTileType().getScore();
|
||||
if(dotsEaten == map.numberOfDots()){
|
||||
score += tile.getTileType().getScore();
|
||||
if (dotsEaten == map.numberOfDots()) {
|
||||
setPhase(RoundPhase.LEVEL_COMPLETE);
|
||||
}
|
||||
}
|
||||
@ -153,17 +157,17 @@ public class PlayingState implements GameState {
|
||||
}
|
||||
|
||||
private void drawCenterText(Graphics2D g, String text) {
|
||||
g.setFont(arcadeFont.deriveFont(18F));
|
||||
g.setFont(GameFonts.arcade(18F));
|
||||
g.setColor(Color.YELLOW);
|
||||
var fm = g.getFontMetrics();
|
||||
int cx = GameMap.OFFSET_X + map.columns() * GameMap.MAP_TILESIZE/2;
|
||||
int cy = GameMap.OFFSET_Y + map.rows() * GameMap.MAP_TILESIZE/2;
|
||||
g.drawString(text, cx - fm.stringWidth(text)/2, cy);
|
||||
int cx = GameMap.OFFSET_X + map.columns() * GameMap.MAP_TILESIZE / 2;
|
||||
int cy = GameMap.OFFSET_Y + map.rows() * GameMap.MAP_TILESIZE / 2;
|
||||
g.drawString(text, cx - fm.stringWidth(text) / 2, cy);
|
||||
}
|
||||
|
||||
private void drawUI(Graphics2D g) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.setFont(arcadeFont);
|
||||
g.setFont(GameFonts.arcade(18F));
|
||||
|
||||
// Score (above map, left)
|
||||
g.drawString("Your Score", 48, 48);
|
||||
@ -202,6 +206,7 @@ public class PlayingState implements GameState {
|
||||
private void checkCollisions() {
|
||||
for (Ghost ghost : ghostManager.getGhosts()) {
|
||||
if (deathInProgress) return; // guard
|
||||
//if(overlap(pacman, ghost)
|
||||
double dist = pacman.distanceTo(ghost.getPosition());
|
||||
if (dist < GameMap.MAP_TILESIZE / 2.0) {
|
||||
if (ghost.isFrightened()) {
|
||||
@ -213,26 +218,24 @@ public class PlayingState implements GameState {
|
||||
deathInProgress = true;
|
||||
// Pac-Man loses a life
|
||||
lives--;
|
||||
if(lives >= REMAINING_LIVES)
|
||||
setPhase(RoundPhase.LIFE_LOST);
|
||||
else
|
||||
endGame();
|
||||
setPhase(RoundPhase.LIFE_LOST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void endGame() {
|
||||
setPhase(RoundPhase.GAME_OVER);
|
||||
gameStateManager.setState(GameStateType.GAME_OVER);
|
||||
}
|
||||
// private boolean overlaps(PacMan p, Ghost g) {
|
||||
// // center-distance or AABB; center distance keeps the arcade feel
|
||||
// double dx = p.getCenterX() - g.getCenterX();
|
||||
// double dy = p.getCenterY() - g.getCenterY();
|
||||
// double r = map.getTileSize() * 0.45; // tune threshold
|
||||
// return (dx*dx + dy*dy) <= r*r;
|
||||
// }
|
||||
|
||||
private Font loadArcadeFont() {
|
||||
try (InputStream is = getClass().getResourceAsStream("/fonts/PressStart2P-Regular.ttf")) {
|
||||
return Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(16f);
|
||||
} catch (Exception e) {
|
||||
return new Font("Monospaced", Font.BOLD, 16);
|
||||
}
|
||||
private void endGame() {
|
||||
gameOverState.setScore(score);
|
||||
gameOverState.setLevel(levelManager.getCurrentLevel().getLevel());
|
||||
gameStateManager.setState(GameStateType.GAME_OVER);
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
|
||||
Reference in New Issue
Block a user