const PAD = 14; const HP_W = 180; const HP_H = 16; const XP_W = 180; const XP_H = 10; const LIFE_R = 8; const LIFE_GAP = 22; export class HUD { constructor(scene, player, xpSystem) { this.scene = scene; this.player = player; this.xpSystem = xpSystem; // Fix to camera const cam = scene.cameras.main; const cx = cam.x; const cy = cam.y; // --- HP Bar --- this._hpLabel = scene.add.text(PAD, PAD, 'HP', { fontSize: '13px', fill: '#ffffff' }).setScrollFactor(0).setDepth(10); this._hpBg = scene.add.rectangle(PAD + HP_W / 2, PAD + 8, HP_W, HP_H, 0x333333).setScrollFactor(0).setDepth(10); this._hpFill = scene.add.rectangle(PAD + HP_W / 2, PAD + 8, HP_W, HP_H, 0xff3333).setScrollFactor(0).setDepth(10); this._hpLabel.setY(PAD - 2); this._hpBg.setY(PAD + 20); this._hpFill.setY(PAD + 20); // --- Life icons --- this._lifeIcons = []; for (let i = 0; i < 3; i++) { const lx = PAD + LIFE_R + i * LIFE_GAP; const icon = scene.add.circle(lx, PAD + 48, LIFE_R, 0x00ccff).setScrollFactor(0).setDepth(10); this._lifeIcons.push(icon); } // --- XP Bar --- const xpY = PAD + 64; this._xpBg = scene.add.rectangle(PAD + XP_W / 2, xpY, XP_W, XP_H, 0x333333).setScrollFactor(0).setDepth(10); this._xpFill = scene.add.rectangle(PAD + XP_W / 2, xpY, XP_W, XP_H, 0x44ffaa).setScrollFactor(0).setDepth(10); this._xpLabel = scene.add.text(PAD, xpY + 8, 'Level 1', { fontSize: '12px', fill: '#aaffcc' }).setScrollFactor(0).setDepth(10); // --- Zone/Wave indicator --- this._zoneText = scene.add.text(0, PAD, 'Zone 1 — Wave 1/3', { fontSize: '14px', fill: '#ffffff' }) .setScrollFactor(0).setDepth(10).setOrigin(1, 0); this._zoneText.setX(scene.scale.width - PAD); // Listen for wave/zone updates scene.events.on('wave-start', ({ zone, wave, totalWaves }) => { this._zoneText.setText(`Zone ${zone} — Wave ${wave}/${totalWaves}`); }); scene.events.on('zone-clear', ({ zone }) => { this._zoneText.setText(`Zone ${zone} Complete!`); }); } update() { // HP bar const hpRatio = Math.max(0, this.player.hp / this.player.stats.maxHp); this._hpFill.width = HP_W * hpRatio; this._hpFill.x = PAD + (HP_W * hpRatio) / 2; // Lives this._lifeIcons.forEach((icon, i) => { icon.setAlpha(i < this.player.lives ? 1 : 0.2); }); // XP bar const xpRatio = this.xpSystem.progress; this._xpFill.width = XP_W * xpRatio; this._xpFill.x = PAD + (XP_W * xpRatio) / 2; this._xpLabel.setText(`Level ${this.xpSystem.level}`); } destroy() { this.scene.events.off('wave-start'); this.scene.events.off('zone-clear'); [this._hpLabel, this._hpBg, this._hpFill, this._xpBg, this._xpFill, this._xpLabel, this._zoneText, ...this._lifeIcons] .forEach(o => o?.destroy()); } }