mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
- Added hand frames PNG for interaction modes. - Updated HUD CSS to support new player HUD buttons and styles. - Enhanced combat configuration to define interaction modes: interact, jab, and cross. - Integrated player HUD creation and management in the game core. - Improved player combat system to handle interaction modes and associated animations. - Modified interaction handling to auto-switch modes for chairs and hostile NPCs. - Updated health UI to always display health status. - Created a new HUD JavaScript module to manage avatar and interaction mode toggle. - Added a test HTML file for the three-mode toggle functionality.
117 lines
3.1 KiB
JavaScript
117 lines
3.1 KiB
JavaScript
/**
|
|
* Health UI System
|
|
* Displays player health as hearts above the inventory
|
|
*/
|
|
|
|
import { COMBAT_CONFIG } from '../config/combat-config.js';
|
|
import { CombatEvents } from '../events/combat-events.js';
|
|
|
|
export class HealthUI {
|
|
constructor() {
|
|
this.container = null;
|
|
this.hearts = [];
|
|
this.currentHP = COMBAT_CONFIG.player.maxHP;
|
|
this.maxHP = COMBAT_CONFIG.player.maxHP;
|
|
this.isVisible = false;
|
|
|
|
this.createUI();
|
|
this.setupEventListeners();
|
|
|
|
console.log('✅ Health UI initialized');
|
|
}
|
|
|
|
createUI() {
|
|
// Create main container div
|
|
this.container = document.createElement('div');
|
|
this.container.id = 'health-ui-container';
|
|
|
|
// Create hearts container
|
|
const heartsContainer = document.createElement('div');
|
|
heartsContainer.id = 'health-ui';
|
|
heartsContainer.className = 'health-ui-display';
|
|
|
|
// Create 5 heart slots
|
|
for (let i = 0; i < COMBAT_CONFIG.ui.maxHearts; i++) {
|
|
const heart = document.createElement('img');
|
|
heart.className = 'health-heart';
|
|
heart.src = '/break_escape/assets/icons/heart.png';
|
|
heart.alt = 'HP';
|
|
heartsContainer.appendChild(heart);
|
|
this.hearts.push(heart);
|
|
}
|
|
|
|
this.container.appendChild(heartsContainer);
|
|
document.body.appendChild(this.container);
|
|
|
|
// Always show hearts (changed from MVP requirement)
|
|
this.show();
|
|
}
|
|
|
|
setupEventListeners() {
|
|
if (!window.eventDispatcher) {
|
|
console.warn('Event dispatcher not found, health UI will not update automatically');
|
|
return;
|
|
}
|
|
|
|
// Listen for HP changes
|
|
window.eventDispatcher.on(CombatEvents.PLAYER_HP_CHANGED, (data) => {
|
|
this.updateHP(data.hp, data.maxHP);
|
|
});
|
|
|
|
// Listen for player KO
|
|
window.eventDispatcher.on(CombatEvents.PLAYER_KO, () => {
|
|
this.show(); // Always show when KO
|
|
});
|
|
}
|
|
|
|
updateHP(hp, maxHP) {
|
|
this.currentHP = hp;
|
|
this.maxHP = maxHP;
|
|
|
|
// Always keep hearts visible (changed from MVP requirement)
|
|
this.show();
|
|
|
|
// Update heart visuals
|
|
const heartsPerHP = maxHP / COMBAT_CONFIG.ui.maxHearts; // 20 HP per heart (100 / 5)
|
|
const fullHearts = Math.floor(hp / heartsPerHP);
|
|
const remainder = hp % heartsPerHP;
|
|
const halfHeart = remainder >= (heartsPerHP / 2);
|
|
|
|
this.hearts.forEach((heart, index) => {
|
|
if (index < fullHearts) {
|
|
// Full heart
|
|
heart.src = '/break_escape/assets/icons/heart.png';
|
|
heart.style.opacity = '1';
|
|
} else if (index === fullHearts && halfHeart) {
|
|
// Half heart
|
|
heart.src = '/break_escape/assets/icons/heart-half.png';
|
|
heart.style.opacity = '1';
|
|
} else {
|
|
// Empty heart
|
|
heart.src = '/break_escape/assets/icons/heart.png';
|
|
heart.style.opacity = '0.2';
|
|
}
|
|
});
|
|
}
|
|
|
|
show() {
|
|
if (!this.isVisible) {
|
|
this.container.style.display = 'flex';
|
|
this.isVisible = true;
|
|
}
|
|
}
|
|
|
|
hide() {
|
|
if (this.isVisible) {
|
|
this.container.style.display = 'none';
|
|
this.isVisible = false;
|
|
}
|
|
}
|
|
|
|
destroy() {
|
|
if (this.container && this.container.parentNode) {
|
|
this.container.parentNode.removeChild(this.container);
|
|
}
|
|
}
|
|
}
|