DungeonCrawler/hud.gd
Andre b01059de50 Loot-System, Gegner-Drops und Gold-Anzeige hinzugefügt
- Enemy droppt Loot bei Tod (Gold + Items basierend auf LootTable)
- LootWindow zeigt Beute an mit "Alles aufheben" Button
- Gold-Anzeige im HUD unter XP-Leiste
- Beispiel LootTables: Goblin (2-8 Gold) und Skeleton (5-15 Gold)
- Loot-System in World verdrahtet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 20:14:22 +01:00

168 lines
5.1 KiB
GDScript

# HUD.gd
# Verwaltet die Spieler-UI: HP-Leiste, XP-Leiste, Aktionsleiste (Slots 1-9)
extends CanvasLayer
signal slot_clicked(slot_index: int)
@onready var health_bar = $Control/HealthBar
@onready var health_label = $Control/HealthBar/HealthLabel
# Level/XP UI (wird dynamisch erstellt)
var level_label: Label
var xp_bar: ProgressBar
var gold_label: Label
@onready var action_slots = [
$Control/ActionBar/A1,
$Control/ActionBar/A2,
$Control/ActionBar/A3,
$Control/ActionBar/A4,
$Control/ActionBar/A5,
$Control/ActionBar/A6,
$Control/ActionBar/A7,
$Control/ActionBar/A8,
$Control/ActionBar/A9
]
var active_slot = 0
var slot_icons = [] # TextureRect nodes für Icons
var slot_cooldown_overlays = [] # ColorRect für Cooldown-Anzeige
var slot_cooldown_labels = [] # Label für Cooldown-Text
func _ready():
_create_level_ui()
for i in range(9):
# Icon erstellen
var icon = TextureRect.new()
icon.name = "Icon"
icon.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.custom_minimum_size = Vector2(40, 40)
icon.position = Vector2(5, 5)
action_slots[i].add_child(icon)
slot_icons.append(icon)
# Cooldown-Overlay erstellen (dunkle Überlagerung)
var cooldown_overlay = ColorRect.new()
cooldown_overlay.name = "CooldownOverlay"
cooldown_overlay.color = Color(0, 0, 0, 0.7)
cooldown_overlay.size = Vector2(50, 50)
cooldown_overlay.position = Vector2(0, 0)
cooldown_overlay.visible = false
cooldown_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
action_slots[i].add_child(cooldown_overlay)
slot_cooldown_overlays.append(cooldown_overlay)
# Cooldown-Text erstellen
var cooldown_label = Label.new()
cooldown_label.name = "CooldownLabel"
cooldown_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
cooldown_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
cooldown_label.size = Vector2(50, 50)
cooldown_label.position = Vector2(0, 0)
cooldown_label.add_theme_font_size_override("font_size", 16)
cooldown_label.visible = false
cooldown_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
action_slots[i].add_child(cooldown_label)
slot_cooldown_labels.append(cooldown_label)
# Button für Klicks erstellen
var button = Button.new()
button.name = "SlotButton"
button.flat = true
button.size = Vector2(50, 50)
button.position = Vector2(0, 0)
button.modulate = Color(1, 1, 1, 0) # Unsichtbar
var slot_index = i
button.pressed.connect(func(): _on_slot_clicked(slot_index))
action_slots[i].add_child(button)
# Slot-Klick Handler
func _on_slot_clicked(slot_index: int):
set_active_slot(slot_index)
slot_clicked.emit(slot_index)
# Icon für einen Slot setzen
func set_slot_icon(slot_index: int, icon_path: String):
if slot_index >= 0 and slot_index < 9:
var texture = load(icon_path)
if texture:
slot_icons[slot_index].texture = texture
else:
print("Icon nicht gefunden: ", icon_path)
# Cooldown für einen Slot anzeigen (remaining_time in Sekunden)
func set_slot_cooldown(slot_index: int, remaining_time: float):
if slot_index < 0 or slot_index >= 9:
return
if remaining_time > 0:
slot_cooldown_overlays[slot_index].visible = true
slot_cooldown_labels[slot_index].visible = true
slot_cooldown_labels[slot_index].text = "%.1f" % remaining_time
else:
slot_cooldown_overlays[slot_index].visible = false
slot_cooldown_labels[slot_index].visible = false
# Level/XP UI erstellen
func _create_level_ui():
var control = $Control
# Level Label
level_label = Label.new()
level_label.name = "LevelLabel"
level_label.position = Vector2(20, 55)
level_label.add_theme_font_size_override("font_size", 14)
level_label.text = "Level 1"
control.add_child(level_label)
# XP Bar
xp_bar = ProgressBar.new()
xp_bar.name = "XPBar"
xp_bar.position = Vector2(80, 55)
xp_bar.size = Vector2(140, 18)
xp_bar.show_percentage = false
xp_bar.value = 0
# XP Bar Farbe (blau)
var xp_style = StyleBoxFlat.new()
xp_style.bg_color = Color(0.2, 0.4, 0.9, 1.0)
xp_bar.add_theme_stylebox_override("fill", xp_style)
control.add_child(xp_bar)
# Gold Label
gold_label = Label.new()
gold_label.name = "GoldLabel"
gold_label.position = Vector2(20, 78)
gold_label.add_theme_font_size_override("font_size", 14)
gold_label.add_theme_color_override("font_color", Color(1, 0.85, 0, 1))
gold_label.text = "0 Gold"
control.add_child(gold_label)
# Gold aktualisieren
func update_gold(amount: int):
if gold_label:
gold_label.text = str(amount) + " Gold"
# HP-Leiste und Text aktualisieren
func update_health(current_hp, max_hp):
health_bar.max_value = max_hp
health_bar.value = current_hp
health_label.text = str(current_hp) + " / " + str(max_hp)
# Level und XP aktualisieren
func update_level(level: int, current_xp: int, xp_to_next: int):
if level_label:
level_label.text = "Lv " + str(level)
if xp_bar:
xp_bar.max_value = xp_to_next
xp_bar.value = current_xp
# Aktions-Slot kurz golden hervorheben (0.1s)
func set_active_slot(index):
action_slots[active_slot].self_modulate = Color(1, 1, 1)
active_slot = index
action_slots[active_slot].self_modulate = Color(1, 0.8, 0)
await get_tree().create_timer(0.1).timeout
action_slots[active_slot].self_modulate = Color(1, 1, 1)