diff --git a/project.godot b/project.godot index 41772e4..0f485e3 100644 --- a/project.godot +++ b/project.godot @@ -25,6 +25,10 @@ window/size/viewport_width=1920 window/size/viewport_height=1080 window/stretch/mode="canvas_items" +[gui] + +theme/custom_font="uid://kfh6ooeul77g" + [input] move_up={ diff --git a/scenes/components/health_component.gd b/scenes/components/health_component.gd new file mode 100644 index 0000000..a76a32c --- /dev/null +++ b/scenes/components/health_component.gd @@ -0,0 +1,42 @@ +extends Node +class_name HealthComponent + +signal on_unit_hit +signal on_unit_died +signal on_health_changed(current: float, max: float) + +var max_health := 1.0 +var current_health := 1.0 + +func setup(stats: UnitStats) -> void: + max_health = stats.health + current_health = max_health + on_health_changed.emit(current_health, max_health) + +func take_damage(value: float) -> void: + if current_health <=0: + return + + current_health -= value + current_health = max(0, current_health) + + on_unit_hit.emit() + on_health_changed.emit(current_health, max_health) + + if current_health <= 0: + current_health = 0 + on_unit_died.emit() + die() + +func heal(amount: float) -> void: + if current_health <= 0: + return + + current_health += amount + current_health = min(max_health, current_health) + on_health_changed.emit(current_health, max_health) + + +func die() -> void: + owner.queue_free() + diff --git a/scenes/components/health_component.gd.uid b/scenes/components/health_component.gd.uid new file mode 100644 index 0000000..89d4815 --- /dev/null +++ b/scenes/components/health_component.gd.uid @@ -0,0 +1 @@ +uid://c2hqb7ixwow4h diff --git a/scenes/components/health_component.tscn b/scenes/components/health_component.tscn new file mode 100644 index 0000000..4e1b880 --- /dev/null +++ b/scenes/components/health_component.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://2ew7i6g3p0v8"] + +[ext_resource type="Script" uid="uid://c2hqb7ixwow4h" path="res://scenes/components/health_component.gd" id="1_2wcl1"] + +[node name="HealthComponent" type="Node" unique_id=455886217] +script = ExtResource("1_2wcl1") diff --git a/scenes/ui/health_bar/health_bar.gd b/scenes/ui/health_bar/health_bar.gd new file mode 100644 index 0000000..c550310 --- /dev/null +++ b/scenes/ui/health_bar/health_bar.gd @@ -0,0 +1,36 @@ +extends Control +class_name HealthBar + +@export var back_color: Color +@export var fill_color: Color + +@onready var progress_bar: ProgressBar = $ProgressBar +@onready var health_amount: Label = $HealthAmount + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + var back_style := progress_bar.get_theme_stylebox("background").duplicate() + back_style.bg_color = back_color + + var fill_style := progress_bar.get_theme_stylebox("fill").duplicate() + fill_style.bg_color = fill_color + + progress_bar.add_theme_stylebox_override("background", back_style) + progress_bar.add_theme_stylebox_override("fill", fill_style) + +func update_bar(value: float, health: float) -> void: + progress_bar.value = value + health_amount.text = str(health) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + + +func _on_health_component_on_health_changed(current: float, max: float) -> void: + var value = current / max + update_bar(value, current) + + diff --git a/scenes/ui/health_bar/health_bar.gd.uid b/scenes/ui/health_bar/health_bar.gd.uid new file mode 100644 index 0000000..ae10418 --- /dev/null +++ b/scenes/ui/health_bar/health_bar.gd.uid @@ -0,0 +1 @@ +uid://b3hyy3co71rtf diff --git a/scenes/ui/health_bar/health_bar.tscn b/scenes/ui/health_bar/health_bar.tscn new file mode 100644 index 0000000..d6b6dac --- /dev/null +++ b/scenes/ui/health_bar/health_bar.tscn @@ -0,0 +1,53 @@ +[gd_scene format=3 uid="uid://ifmw1e7gycc8"] + +[ext_resource type="Script" uid="uid://b3hyy3co71rtf" path="res://scenes/ui/health_bar/health_bar.gd" id="1_ruhgv"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ilash"] +bg_color = Color(0.13725491, 0.019607844, 0.02745098, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ruhgv"] +bg_color = Color(1, 0.2901961, 0.45490196, 1) +border_width_left = 3 +border_width_top = 3 +border_width_right = 3 +border_width_bottom = 3 +border_color = Color(0.13725491, 0.019607844, 0.02745098, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[node name="HealthBar" type="Control" unique_id=1540037291] +custom_minimum_size = Vector2(96, 20) +layout_mode = 3 +anchors_preset = 0 +offset_right = 96.0 +offset_bottom = 20.0 +script = ExtResource("1_ruhgv") + +[node name="ProgressBar" type="ProgressBar" parent="." unique_id=1237029629] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/background = SubResource("StyleBoxFlat_ilash") +theme_override_styles/fill = SubResource("StyleBoxFlat_ruhgv") +max_value = 1.0 +value = 0.5 +show_percentage = false + +[node name="HealthAmount" type="Label" parent="." unique_id=1539272143] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +text = "10" +horizontal_alignment = 1 diff --git a/scenes/unit/enemy/enemy_chaser_slow.tscn b/scenes/unit/enemy/enemy_chaser_slow.tscn index 1679911..e1c7ae5 100644 --- a/scenes/unit/enemy/enemy_chaser_slow.tscn +++ b/scenes/unit/enemy/enemy_chaser_slow.tscn @@ -45,3 +45,9 @@ collision_mask = 32 position = Vector2(0, -30) shape = SubResource("CircleShape2D_421q1") debug_color = Color(0.95670325, 0.056883797, 0.5071302, 0.41960785) + +[node name="HealthBar" parent="." index="7" unique_id=1540037291] +offset_top = -95.0 +offset_bottom = -75.0 +back_color = Color(0.015686275, 0.05490196, 0.16862746, 1) +fill_color = Color(0.37254903, 0.5372549, 0.75686276, 1) diff --git a/scenes/unit/players/player.gd b/scenes/unit/players/player.gd index c0b8a94..f1c4b40 100644 --- a/scenes/unit/players/player.gd +++ b/scenes/unit/players/player.gd @@ -16,6 +16,7 @@ var dash_available := true # Called when the node enters the scene tree for the first time. func _ready() -> void: + super._ready() dash_timer.wait_time = dash_duration dash_cooldown_timer.wait_time = dash_cooldown diff --git a/scenes/unit/players/player_well_rounded.tscn b/scenes/unit/players/player_well_rounded.tscn index f854644..b49b90b 100644 --- a/scenes/unit/players/player_well_rounded.tscn +++ b/scenes/unit/players/player_well_rounded.tscn @@ -63,5 +63,9 @@ z_index = 1 position = Vector2(0, -32) shape = SubResource("CircleShape2D_ht2l1") +[node name="HealthBar" parent="." index="8" unique_id=1540037291] +back_color = Color(0.13725491, 0.019607844, 0.02745098, 1) +fill_color = Color(1, 0.2901961, 0.45490196, 1) + [connection signal="timeout" from="DashTimer" to="." method="_on_dash_timer_timeout"] [connection signal="timeout" from="TrailTimer" to="Visuals/Trail" method="_on_trail_timer_timeout"] diff --git a/scenes/unit/unit.gd b/scenes/unit/unit.gd index f006866..c3284d6 100644 --- a/scenes/unit/unit.gd +++ b/scenes/unit/unit.gd @@ -6,3 +6,16 @@ class_name Unit @onready var visuals: Node2D = %Visuals @onready var sprite: Sprite2D = %Sprite @onready var anim_player: AnimationPlayer = $AnimationPlayer +@onready var health_component: HealthComponent = $HealthComponent + +func _ready() -> void: + print(stats) + health_component.setup(stats) + + +func _on_hurtbox_component_on_damaged(hitbox: HitboxComponent) -> void: + if health_component.current_health <=0: + return + + health_component.take_damage(hitbox.damage) + print("%s: %d" % [name, health_component.current_health] ) diff --git a/scenes/unit/unit.tscn b/scenes/unit/unit.tscn index 2f671a7..90734e9 100644 --- a/scenes/unit/unit.tscn +++ b/scenes/unit/unit.tscn @@ -3,6 +3,8 @@ [ext_resource type="Texture2D" uid="uid://devt2xbk78rej" path="res://assets/sprites/shadow.png" id="1_fvc8g"] [ext_resource type="Script" uid="uid://cwf3afjy6t6rg" path="res://scenes/unit/unit.gd" id="1_vh40f"] [ext_resource type="PackedScene" uid="uid://bkyyic3okyjxx" path="res://scenes/components/hurtbox_component.tscn" id="3_vh40f"] +[ext_resource type="PackedScene" uid="uid://2ew7i6g3p0v8" path="res://scenes/components/health_component.tscn" id="4_bhlit"] +[ext_resource type="PackedScene" uid="uid://ifmw1e7gycc8" path="res://scenes/ui/health_bar/health_bar.tscn" id="5_vgvef"] [sub_resource type="Animation" id="Animation_bhlit"] length = 0.001 @@ -247,3 +249,14 @@ position = Vector2(0, -61) libraries/ = SubResource("AnimationLibrary_w7udy") [node name="HurtboxComponent" parent="." unique_id=1155790880 instance=ExtResource("3_vh40f")] + +[node name="HealthComponent" parent="." unique_id=455886217 instance=ExtResource("4_bhlit")] + +[node name="HealthBar" parent="." unique_id=1540037291 instance=ExtResource("5_vgvef")] +offset_left = -46.0 +offset_top = -90.0 +offset_right = 50.0 +offset_bottom = -70.0 + +[connection signal="on_damaged" from="HurtboxComponent" to="." method="_on_hurtbox_component_on_damaged"] +[connection signal="on_health_changed" from="HealthComponent" to="HealthBar" method="_on_health_component_on_health_changed"]