diff --git a/src/default-test/java/nl/tudelft/jpacman/LauncherSmokeTest.java b/src/default-test/java/nl/tudelft/jpacman/LauncherSmokeTest.java index 441e7d35..040619b7 100644 --- a/src/default-test/java/nl/tudelft/jpacman/LauncherSmokeTest.java +++ b/src/default-test/java/nl/tudelft/jpacman/LauncherSmokeTest.java @@ -93,7 +93,7 @@ void smokeTest() throws InterruptedException { // we're close to monsters, this will get us killed. move(game, Direction.WEST, 10); move(game, Direction.EAST, 10); - assertThat(player.isAlive()).isFalse(); + assertThat(player.getLives()).isLessThan(3); game.stop(); assertThat(game.isInProgress()).isFalse(); diff --git a/src/main/java/nl/tudelft/jpacman/level/DefaultPlayerInteractionMap.java b/src/main/java/nl/tudelft/jpacman/level/DefaultPlayerInteractionMap.java index 9c2ea625..8e34bd23 100644 --- a/src/main/java/nl/tudelft/jpacman/level/DefaultPlayerInteractionMap.java +++ b/src/main/java/nl/tudelft/jpacman/level/DefaultPlayerInteractionMap.java @@ -49,8 +49,10 @@ private CollisionInteractionMap defaultCollisions() { collisionMap.onCollision(Player.class, Ghost.class, (player, ghost) -> { pointCalculator.collidedWithAGhost(player, ghost); - player.setAlive(false); - player.setKiller(ghost); + player.decrementLives(); + if (!player.isAlive()) { + player.setKiller(ghost); + } }); collisionMap.onCollision(Player.class, Pellet.class, diff --git a/src/main/java/nl/tudelft/jpacman/level/Player.java b/src/main/java/nl/tudelft/jpacman/level/Player.java index 95f2b277..66ebc277 100644 --- a/src/main/java/nl/tudelft/jpacman/level/Player.java +++ b/src/main/java/nl/tudelft/jpacman/level/Player.java @@ -33,6 +33,8 @@ public class Player extends Unit { * true iff this player is alive. */ private boolean alive; + public static final int INITIAL_LIVES = 3; + private int lives; /** * {@link Unit} iff this player died by collision, null otherwise. @@ -49,7 +51,7 @@ public class Player extends Unit { */ protected Player(Map spriteMap, AnimatedSprite deathAnimation) { this.score = 0; - this.alive = true; + this.lives = INITIAL_LIVES; this.sprites = spriteMap; this.deathSprite = deathAnimation; deathSprite.setAnimating(false); @@ -61,26 +63,26 @@ protected Player(Map spriteMap, AnimatedSprite deathAnimation * @return true iff the player is alive. */ public boolean isAlive() { - return alive; + return lives > 0; } - /** - * Sets whether this player is alive or not. - * - * If the player comes back alive, the {@link killer} will be reset. - * - * @param isAlive - * true iff this player is alive. - */ - public void setAlive(boolean isAlive) { - if (isAlive) { + public int getLives() { + return this.lives; + } + + public void setLives(int lives) { + if (lives == 0) { + deathSprite.restart(); + } else { deathSprite.setAnimating(false); this.killer = null; } - if (!isAlive) { - deathSprite.restart(); - } - this.alive = isAlive; + + if (lives >= 0) this.lives = lives; + } + + public void decrementLives() { + setLives((lives - 1)); } /** diff --git a/src/main/java/nl/tudelft/jpacman/level/PlayerCollisions.java b/src/main/java/nl/tudelft/jpacman/level/PlayerCollisions.java index 309fced7..a8f7db41 100644 --- a/src/main/java/nl/tudelft/jpacman/level/PlayerCollisions.java +++ b/src/main/java/nl/tudelft/jpacman/level/PlayerCollisions.java @@ -75,8 +75,10 @@ private void pelletColliding(Pellet pellet, Unit collidedOn) { */ public void playerVersusGhost(Player player, Ghost ghost) { pointCalculator.collidedWithAGhost(player, ghost); - player.setAlive(false); - player.setKiller(ghost); + player.decrementLives(); + if (!player.isAlive()) { + player.setKiller(ghost); + } } /** diff --git a/src/main/java/nl/tudelft/jpacman/ui/ScorePanel.java b/src/main/java/nl/tudelft/jpacman/ui/ScorePanel.java index 36e559cb..c1823957 100644 --- a/src/main/java/nl/tudelft/jpacman/ui/ScorePanel.java +++ b/src/main/java/nl/tudelft/jpacman/ui/ScorePanel.java @@ -29,6 +29,11 @@ public class ScorePanel extends JPanel { */ private final Map scoreLabels; + /** + * The map of players and the labels their lives are on. + */ + private final Map livesLabels; + /** * The default way in which the score is shown. */ @@ -61,6 +66,13 @@ public ScorePanel(List players) { scoreLabels.put(player, scoreLabel); add(scoreLabel); } + + livesLabels = new LinkedHashMap<>(); + for (Player player : players) { + JLabel livesLabel = new JLabel(Integer.toString(player.getLives()), JLabel.CENTER); + livesLabels.put(player, livesLabel); + add(livesLabel); + } } /** @@ -76,6 +88,12 @@ protected void refresh() { score += scoreFormatter.format(player); entry.getValue().setText(score); } + + for (Map.Entry entry : livesLabels.entrySet()) { + Player player = entry.getKey(); + String lives = "Lives : " + player.getLives(); + entry.getValue().setText(lives); + } } /**