Player HUD Health - UQcsse3200/2026-studio-2 GitHub Wiki

Player HUD: Health

Part of the Player HUD.

Purpose

Shows the player's health as a row of hearts in the top-left corner, over a health-bar background. Hearts disappear with a flicker animation as the player takes damage, and the row grows automatically when maximum health increases (e.g. an earned extra life).

HUD health bar

Class diagram

classDiagram
    class UIComponent {
        <<abstract>>
    }

    class PlayerStatsDisplay {
        -Table root
        -Group heartGroup
        -List~Image~ heartImages
        -Texture heartTexture
        -CombatStatsComponent combatStats
        +create()
        +updatePlayerHealthUI(int health)
        -growHeartsTo(int desiredCount)
        -flickerAndHide(Image heart)
    }

    class CombatStatsComponent {
        -int health
        -int maxHealth
        -int baseAttack
        +getHealth() int
        +getMaxHealth() int
        +setHealth(int)
        +addHealth(int)
        +addMaxHealth(int)
        +hit(CombatStatsComponent attacker)
    }

    UIComponent <|-- PlayerStatsDisplay
    PlayerStatsDisplay --> CombatStatsComponent : reads
    CombatStatsComponent ..> PlayerStatsDisplay : "updateHealth" event
Loading

UML class diagram of PlayerStatsDisplay: it extends UIComponent, reads CombatStatsComponent, composes Table/Group/Image/Texture actors, and depends on ServiceLocator

  • PlayerStatsDisplay is a UIComponent on the player entity. It owns the heart row (heart Image actors in a positioned Group, layered over the background with a Stack inside the root Table) and the gold counter (see the hub).
  • CombatStatsComponent is the data model. It tracks health and maxHealth separately; health is clamped to [0, maxHealth]. The HUD sizes itself against maxHealth.

Lifecycle

Each heart is worth HP_PER_HEART (2) health. The number of hearts is derived with ceiling division:

int maximumHearts = Math.max(1, (combatStats.getMaxHealth() + HP_PER_HEART - 1) / HP_PER_HEART);

10 HP shows five hearts, 9 HP still shows five, and 8 HP shows four.

updatePlayerHealthUI(int health) runs on every updateHealth event:

  1. Grow the heart row (growHeartsTo) if maxHealth has increased since the last update. This is what makes an earned extra life appear with no separate "add a heart" call.
  2. Clamp the supplied health and compute the visible heart count with (cappedHealth + HP_PER_HEART - 1) / HP_PER_HEART.
  3. Compare each heart's current visibility with what it should be:
    • visible, should hide: flicker, then hide;
    • hidden, should show: reappear instantly (health restored, new heart earned), no animation;
    • no change: left alone. This stops the flicker re-triggering every time the event fires.

The flicker uses libGDX Actions: fade out and in a few times, then hide and reset the colour so the heart can reappear at full opacity.

heart.addAction(
    Actions.sequence(
        Actions.repeat(FLICKER_COUNT,
            Actions.sequence(Actions.fadeOut(FLICKER_DURATION), Actions.fadeIn(FLICKER_DURATION))),
        Actions.run(() -> {
          heart.setVisible(false);
          heart.setColor(1f, 1f, 1f, 1f);
        })));

Public methods

Method Purpose
combatStats.getMaxHealth() Read the player's current max health
combatStats.addMaxHealth(amount) Increase max health and heal by amount; use this to grant an extra life/heart
combatStats.addHealth(amount) Heal or damage without changing the heart count
playerStatsDisplay.updatePlayerHealthUI(health) Normally driven by the updateHealth event; rarely called directly

Granting an extra life:

CombatStatsComponent stats = player.getComponent(CombatStatsComponent.class);
stats.addMaxHealth(2); // one more heart's worth of max health

The updateHealth event fired by addMaxHealth grows the row and shows the new heart as full.

Tuning constants

In PlayerStatsDisplay:

Constant Value Purpose
HP_PER_HEART 2 Health represented by each visible heart
FLICKER_COUNT 3 Repetitions when hiding a lost heart
FLICKER_DURATION 0.1 seconds Duration of each fade-out/fade-in step
HEART_SIDE_LENGTH / HEART_SIDE_HEIGHT 35px Size of each heart
HEART_SPACING 43.4px Distance between heart centres
HEALTH_BAR_WIDTH / HEALTH_BAR_HEIGHT 400px / 150px Size of the health-bar background

These UI values are separate from player health and i-frame configuration in Player Health and Damage.

Tests

Links

⚠️ **GitHub.com Fallback** ⚠️