using System; using Astra; [ComponentId("docs.heart-hud")] public sealed class HeartHud : Behavior { [PropertyId("player")] public ObjectReference Player; private GuiAccess hud = null!; private PlayerHealth health = null!; private readonly GuiElement[] hearts = new GuiElement[PlayerHealth.Capacity]; private GuiElement status; private int lastHealth = -1; public override void Start() { var player = Resolve(Player) ?? throw new InvalidOperationException("Atribua Jogador ao campo Player do HeartHud."); health = player.GetBehavior() ?? throw new InvalidOperationException("Jogador precisa de PlayerHealth."); hud = Gui.ForCanvas(Object); for (int i = 0; i < hearts.Length; ++i) { hearts[i] = hud.Find($"Heart{i + 1}"); if (hearts[i].Kind != GuiKind.Image) throw new InvalidOperationException($"Heart{i + 1} precisa ser Image."); } status = hud.Find("Status"); hud.Find("Damage"); hud.Find("Heal"); Refresh(); } public override void Update(float deltaTime) { // Este script é o consumidor da fila deste Canvas. while (hud.Poll(out var message)) { if (message.Kind != GuiEventKind.Click) continue; if (message.Element.Name == "Damage") health.TakeDamage(1); else if (message.Element.Name == "Heal") health.Heal(1); } if (lastHealth != health.Current) Refresh(); } private void Refresh() { lastHealth = health.Current; for (int i = 0; i < hearts.Length; ++i) hearts[i].Visible = i < lastHealth; status.Text = $"Vida: {lastHealth}/{PlayerHealth.Capacity}" + (health.IsDead ? " | Sem vida" : ""); } }