Hud

The in-game heads-up display: a port of the original's bottom-of-screen information bar, drawn last over the 3D scene.

Location

Headersrc/GalaxyEggbert/Game/Hud.hpp
Sourcessrc/GalaxyEggbert/Game/Hud.cpp; helpers ObjectiveHint.hpp (compass arrows) and TextMetrics.hpp (proportional font widths) in the same folder
NamespaceGalaxyEggbert::Game
Engine dependencyCNA (GraphicsDevice, Texture2D, BasicEffect) and cna-engine's GpuMesh

Purpose

Hud draws what the player sees on top of the world during Play: lives, held keys, the treasure counter, glue shots, dynamite, decoys, the breath and power gauges, the training hint banner, the game-speed indicator, the "fly to the HUD" animation of a picked-up item, and the optional compass. Its layout reproduces the original's Decor::DrawInfo in the original's 640 x 480 reference space. The space is scaled uniformly by viewport height / 480 and centred horizontally, so the proportions are the same at any window size.

The HUD is drawn as textured quads through a BasicEffect with an orthographic pixel projection, not through SpriteBatch. That keeps the draw order explicit: quads submitted last are drawn on top on every renderer. Text uses Content/icons/text.png with the original's proportional glyph widths (TextMetrics, since 2026-10-25).

The class has no gameplay state of its own: the host passes every value to Draw each frame.

Collaborators

Uses

Used by

Key members

The complete public API of Hud.hpp is small; this is all of it.

MemberSignatureWhat it does
LoadContentvoid LoadContent(GraphicsDevice& device)Loads the HUD's own texture instances and effects.
DrawUnderwaterTintvoid DrawUnderwaterTint(GraphicsDevice& device, int viewportW, int viewportH, float immersion)A full-screen tint while the camera is under water; drawn after the world and before any HUD or menu quad.
Drawsee belowDraws the whole HUD. Call last, with depth testing off; restores the opaque blend state.
ProjectWorldToHudSpacestatic bool ProjectWorldToHudSpace(Vector3 worldPos, const Matrix& view, const Matrix& projection, int viewportW, int viewportH, float& outX, float& outY)Projects a 3D point into the 640 x 480 HUD space; returns false when it is behind the camera.
void Draw(GraphicsDevice& device, int viewportW, int viewportH,
          int lives, bool key1, bool key2, bool key3,
          int treasures, int totalTreasures, bool showTreasureCounter,
          int bullets, int dynamite, int perso,
          bool waterGaugeVisible, int waterGaugeLevel,
          bool powerGaugeVisible, int powerGaugeLevel,
          std::string_view trainingHint,
          const char* overlayMessage,
          int animIcon, bool animIconUsesElementSheet,
          bool voyageActive, int voyageIconId, bool voyageIsButtonChannel,
          bool voyageIsBlupiChannel,
          float voyageX, float voyageY,
          GalaxyEggbert::Def::GameSpeed gameSpeed, float animOpacity = 1.0f,
          std::optional<ObjectiveHint> objective = std::nullopt,
          bool rightTouchControls = false, float blupiYaw = 0);

What Draw shows

Positions are in the 640 x 480 reference space, taken from the constants in Hud.cpp.

ElementDrawn asShown when
Livesblupi.png icon 48 from (210, 417), 16 px apartalways in Play
Keyselement.png icons 215, 222, 229 at x 520, 530, 540while that key is held
Treasure counterpad.png panel (410, 445)-(510, 480) at 0.6 opacity, "N/M" centred at (460, 450)not in hubs (the host hides it for mission 1 and multiples of 10)
Glue shotselement.png icon 176 from (570, 442), 4 px apartwhile any are held
Dynamiteelement.png icon 252 at (505, 414)while dynamite > 0
Decoysbutton.png icon 108 at (0, 438) and "= N" at (32, 452)while perso > 0
Breath gaugejauge.png at (90, 450), blue, red at 25 or belowwhile swimming
Power gaugejauge.png at (90, 428), yellowduring a timed state: shield, power, cloud, hide, invert, balloon, squash (one shared count)
Training hintfull-width pad.png banner (0, 0)-(640, 40), text centred and shrunk to fitwhen the host passes a non-empty hint (TrainingHints or the world's hint zones)
Game speed"0.5x", "0.25x", "0.125x" or "Nx" on a panel at the lower leftwhen the speed is not normal
Pickup flightthe item's icon at voyageX, voyageYwhile the original's "voyage" animation runs
Compassthree rows at the lower right: rounded straight-line distance, turn (< | >), height (^ - v)when the compass cheat is on; it moves left to clear the touch buttons
Animation indicatorBlupi's current sprite icon, bottom rightfirst person only (the host passes -1 in third person)

overlayMessage would draw one large centred message instead of the HUD. As of 2026-11-10 the host's PhaseOverlayMessage() returns nullptr for every phase, because Pause, Win and Lost have real screens drawn by InputPad.

How it is used

The host calls Draw from GalaxyEggbertGame::DrawOverlay only when the current phase has no full screen of its own (Pause, Win, Lost, Setup, Resume, Wait, Init and Editor do), and after it has turned depth testing off. An excerpt from src/GalaxyEggbertCNA/GalaxyEggbertGameDraw.cpp:

const int hudMission = worldRuntime_.GetMissionNumber();
const bool showTreasureCounter = hudMission != 1 && hudMission % 10 != 0;
hud_.Draw(device, viewport.getWidthProperty(), viewport.getHeightProperty(),
          interaction_.Lives(),
          interaction_.Key1Count() > 0, interaction_.Key2Count() > 0,
          interaction_.Key3Count() > 0,
          interaction_.TreasuresCollected(), interaction_.TotalTreasures(), showTreasureCounter,
          interaction_.BulletCount(), interaction_.DynamiteCount(), interaction_.PersoCount(),
          blupi_.IsNage(), blupi_.GetWaterGaugeLevel(),
          ...
          cheatCompass_ && GalaxyEggbert::Game::kCheatsEnabled
              ? InteractionSystem::NearestObjective(
                  worldRuntime_, blupi_.GetX(), blupi_.GetY(), blupi_.GetZ()) : std::nullopt,
          tickInput_.touchControlsEnabled, blupi_.GetYaw());
Not drawn by Hud The on-screen touch pad, the list of active cheats in the top-left corner (which also shows "Demo" while a demo plays and "REC" while the player records one), the debug diagnostics panel (lines built by DebugOverlayLines in DebugOverlay.hpp), the F1 help and all menu screens are drawn by InputPad.

Rules and invariants

Tests

There is no dedicated Hud verifier. Coverage comes from:

Related pages