Add DamageNumberManager and DamageNumber for displaying damage feedback
This commit is contained in:
56
Autoloads/DamageNumberManager.cs
Normal file
56
Autoloads/DamageNumberManager.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using Mr.BrickAdventures.scripts.components;
|
||||||
|
using Mr.BrickAdventures.scripts.UI;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.Autoloads;
|
||||||
|
|
||||||
|
public partial class DamageNumberManager : Node
|
||||||
|
{
|
||||||
|
[Export] public PackedScene DamageNumberScene { get; set; }
|
||||||
|
|
||||||
|
private readonly List<Node> _managedNodes = [];
|
||||||
|
|
||||||
|
public void Register(Node node)
|
||||||
|
{
|
||||||
|
if (_managedNodes.Contains(node)) return;
|
||||||
|
|
||||||
|
var healthComponent = node.GetNodeOrNull<HealthComponent>("HealthComponent");
|
||||||
|
if (healthComponent == null)
|
||||||
|
{
|
||||||
|
GD.PrintErr($"Node '{node.Name}' tried to register with DamageNumberManager but has no HealthComponent.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
healthComponent.HealthChanged += (delta, total) => OnHealthChanged(healthComponent, delta);
|
||||||
|
node.TreeExiting += () => Unregister(node);
|
||||||
|
_managedNodes.Add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unregister(Node node)
|
||||||
|
{
|
||||||
|
var healthComponent = node.GetNodeOrNull<HealthComponent>("HealthComponent");
|
||||||
|
if (healthComponent != null)
|
||||||
|
{
|
||||||
|
healthComponent.HealthChanged -= (delta, _) => OnHealthChanged(healthComponent, delta);
|
||||||
|
}
|
||||||
|
_managedNodes.Remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHealthChanged(HealthComponent healthComponent, float delta)
|
||||||
|
{
|
||||||
|
if (delta >= 0) return;
|
||||||
|
|
||||||
|
if (DamageNumberScene == null)
|
||||||
|
{
|
||||||
|
GD.PrintErr("DamageNumberManager: DamageNumberScene is not set!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var damageNumber = DamageNumberScene.Instantiate<DamageNumber>();
|
||||||
|
GetTree().CurrentScene.AddChild(damageNumber);
|
||||||
|
|
||||||
|
var position = healthComponent.GlobalPosition;
|
||||||
|
damageNumber.ShowDamage(Mathf.Abs(delta), position);
|
||||||
|
}
|
||||||
|
}
|
1
Autoloads/DamageNumberManager.cs.uid
Normal file
1
Autoloads/DamageNumberManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://i06td076ej68
|
8
objects/damage_number_manager.tscn
Normal file
8
objects/damage_number_manager.tscn
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://dpibw6s3dcggr"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://i06td076ej68" path="res://Autoloads/DamageNumberManager.cs" id="1_me007"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://c7mp0o2goauyy" path="res://objects/ui/damage_number.tscn" id="2_ghslv"]
|
||||||
|
|
||||||
|
[node name="DamageNumberManager" type="Node"]
|
||||||
|
script = ExtResource("1_me007")
|
||||||
|
DamageNumberScene = ExtResource("2_ghslv")
|
@@ -216,10 +216,11 @@ Sprite = NodePath("../Graphics/Root/Right Eye")
|
|||||||
FlashDuration = 1.0
|
FlashDuration = 1.0
|
||||||
HealthComponent = NodePath("../HealthComponent")
|
HealthComponent = NodePath("../HealthComponent")
|
||||||
|
|
||||||
[node name="StompDamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area")]
|
[node name="StompDamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area", "Root")]
|
||||||
script = ExtResource("17_bl1gx")
|
script = ExtResource("17_bl1gx")
|
||||||
Damage = 4.0
|
Damage = 4.0
|
||||||
Area = NodePath("../StompDamageArea")
|
Area = NodePath("../StompDamageArea")
|
||||||
|
Root = NodePath("..")
|
||||||
|
|
||||||
[node name="SkillManager" type="Node" parent="."]
|
[node name="SkillManager" type="Node" parent="."]
|
||||||
script = ExtResource("18_6lsog")
|
script = ExtResource("18_6lsog")
|
||||||
|
15
objects/ui/damage_number.tscn
Normal file
15
objects/ui/damage_number.tscn
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://c7mp0o2goauyy"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://bbupymh6krrgx" path="res://scripts/UI/DamageNumber.cs" id="1_yv42p"]
|
||||||
|
|
||||||
|
[node name="DamageNumber" type="Label"]
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 8.0
|
||||||
|
theme_override_constants/outline_size = 1
|
||||||
|
theme_override_constants/shadow_outline_size = 3
|
||||||
|
theme_override_font_sizes/font_size = 8
|
||||||
|
text = "23"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
script = ExtResource("1_yv42p")
|
||||||
|
metadata/_custom_type_script = "uid://bbupymh6krrgx"
|
@@ -40,6 +40,7 @@ LimboConsole="*res://addons/limbo_console/limbo_console.gd"
|
|||||||
DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd"
|
DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd"
|
||||||
SteamManager="*res://Autoloads/SteamManager.cs"
|
SteamManager="*res://Autoloads/SteamManager.cs"
|
||||||
AchievementManager="*res://objects/achievement_manager.tscn"
|
AchievementManager="*res://objects/achievement_manager.tscn"
|
||||||
|
DamageNumberManager="*res://objects/damage_number_manager.tscn"
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
@@ -197,10 +197,6 @@ process_mode = 4
|
|||||||
[node name="HitParticles" parent="Brick Player" index="26"]
|
[node name="HitParticles" parent="Brick Player" index="26"]
|
||||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||||
|
|
||||||
[node name="ProgressiveDamageComponent" parent="Brick Player" index="31"]
|
|
||||||
MinJumpHeight = null
|
|
||||||
JumpReductionPercentage = null
|
|
||||||
|
|
||||||
[node name="Enemies" type="Node2D" parent="."]
|
[node name="Enemies" type="Node2D" parent="."]
|
||||||
|
|
||||||
[node name="Flying Enemy" parent="Enemies" instance=ExtResource("18_162yw")]
|
[node name="Flying Enemy" parent="Enemies" instance=ExtResource("18_162yw")]
|
||||||
|
41
scripts/UI/DamageNumber.cs
Normal file
41
scripts/UI/DamageNumber.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Mr.BrickAdventures.scripts.UI;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class DamageNumber : Label
|
||||||
|
{
|
||||||
|
[Export] public float Duration { get; set; } = 0.8f;
|
||||||
|
[Export] public float FallDistance { get; set; } = 40f;
|
||||||
|
[Export] public float HorizontalDrift { get; set; } = 15f;
|
||||||
|
|
||||||
|
public void ShowDamage(float damageAmount, Vector2 position)
|
||||||
|
{
|
||||||
|
Text = Mathf.Round(damageAmount * 100f).ToString(CultureInfo.InvariantCulture);
|
||||||
|
GlobalPosition = position;
|
||||||
|
|
||||||
|
var rng = new RandomNumberGenerator();
|
||||||
|
var horizontalOffset = rng.RandfRange(-HorizontalDrift, HorizontalDrift);
|
||||||
|
|
||||||
|
var startPosition = GlobalPosition;
|
||||||
|
var endPosition = GlobalPosition + new Vector2(horizontalOffset, FallDistance);
|
||||||
|
|
||||||
|
var startColor = Colors.White;
|
||||||
|
startColor.A = 1f;
|
||||||
|
Modulate = startColor;
|
||||||
|
|
||||||
|
var tween = CreateTween();
|
||||||
|
tween.SetParallel();
|
||||||
|
|
||||||
|
tween.TweenProperty(this, "global_position", endPosition, Duration)
|
||||||
|
.SetTrans(Tween.TransitionType.Quad)
|
||||||
|
.SetEase(Tween.EaseType.In);
|
||||||
|
|
||||||
|
tween.Chain().TweenProperty(this, "modulate:a", 0f, Duration * 0.5f)
|
||||||
|
.SetTrans(Tween.TransitionType.Sine)
|
||||||
|
.SetEase(Tween.EaseType.Out);
|
||||||
|
|
||||||
|
tween.TweenCallback(Callable.From(QueueFree));
|
||||||
|
}
|
||||||
|
}
|
1
scripts/UI/DamageNumber.cs.uid
Normal file
1
scripts/UI/DamageNumber.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bbupymh6krrgx
|
@@ -1,5 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Mr.BrickAdventures.Autoloads;
|
||||||
|
|
||||||
namespace Mr.BrickAdventures.scripts.components;
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
@@ -13,6 +14,14 @@ public partial class HealthComponent : Node2D
|
|||||||
[Signal] public delegate void HealthChangedEventHandler(float delta, float totalHealth);
|
[Signal] public delegate void HealthChangedEventHandler(float delta, float totalHealth);
|
||||||
[Signal] public delegate void DeathEventHandler();
|
[Signal] public delegate void DeathEventHandler();
|
||||||
|
|
||||||
|
private DamageNumberManager _damageNumberManager;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
_damageNumberManager = GetNode<DamageNumberManager>("/root/DamageNumberManager");
|
||||||
|
_damageNumberManager?.Register(Owner);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetHealth(float newValue)
|
public void SetHealth(float newValue)
|
||||||
{
|
{
|
||||||
_ = ApplyHealthChange(newValue);
|
_ = ApplyHealthChange(newValue);
|
||||||
|
Reference in New Issue
Block a user