Skip to content

Commit 726464a

Browse files
Slocalyolivierperez
andauthoredMar 5, 2025
feat(player): implement player's health and healthbar (#41)
* feat(player): add player healthbar * feat(player): re-add shader & and animations after rebase * feat(player): @export of AnimationPlayer * feat(player): extract HealthBar to its own scene * feat(player): add player healthbar * fix death anim --------- Co-authored-by: Olivier PEREZ <[email protected]>
1 parent 477cbd9 commit 726464a

File tree

7 files changed

+131
-18
lines changed

7 files changed

+131
-18
lines changed
 

‎objects/actors/mob/Mob.gd

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
class_name Mob
22
extends Actor
33

4-
54
var targeted_players: Array[Player]

‎objects/actors/player/Player.gd

+17-6
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ class_name Player
22
extends Actor
33

44
@export var chestModifierSpeed: float = 0.7
5+
@export var life = 100
56

67
@onready var attackTimer = $AttackTimer
8+
@onready var healthbar: HealthBar = $HealthBar
9+
@onready var animation_player: AnimationPlayer = $AnimationPlayer
710

811
@export var weapon: Weapon
912
var hasChest = false
1013

1114
func _ready() -> void:
1215
if StoreManager.player_weapon != null:
1316
weapon = StoreManager.player_weapon
17+
healthbar.init(life)
1418
attackTimer.wait_time = weapon.attack_speed
1519

1620
func _input(event):
@@ -22,7 +26,15 @@ func _input(event):
2226
attack()
2327

2428
func apply_attack(force: int) -> void:
25-
prints("Attacked with force", force)
29+
if life <= 0:
30+
return
31+
32+
life -= force
33+
animation_player.play("Hit")
34+
healthbar.value = life
35+
36+
if (life <= 0):
37+
animation_player.play("Death")
2638

2739
func get_speed():
2840
if hasChest: return _speed * chestModifierSpeed
@@ -38,7 +50,7 @@ func attack():
3850
var direction = global_position.direction_to(mouseCoords)
3951

4052
var attack_scene = weapon.attackTo(direction)
41-
53+
4254
if weapon.attack_type == Weapon.ATTACK_TYPES.projectile:
4355
attack_scene.global_position = global_position
4456
get_tree().current_scene.add_child(attack_scene)
@@ -53,7 +65,6 @@ func _on_collecting(element):
5365
if element is Boat:
5466
if hasChest:
5567
element.can_enter = true
56-
$AnimationPlayer.play("fade_away")
57-
58-
if element.can_enter: $AnimationPlayer.play("fade_away")
59-
68+
animation_player.play("FadeAway")
69+
70+
if element.can_enter: animation_player.play("FadeAway")

‎objects/actors/player/Player.tscn

+76-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
[gd_scene load_steps=77 format=3 uid="uid://bsfyypyhwfbs5"]
1+
[gd_scene load_steps=80 format=3 uid="uid://bsfyypyhwfbs5"]
22

33
[ext_resource type="PackedScene" uid="uid://du0c1yciw8ul6" path="res://objects/actors/Actor.tscn" id="1_wrkhm"]
44
[ext_resource type="Script" path="res://objects/actors/player/Player.gd" id="2_bhjnv"]
5+
[ext_resource type="Resource" uid="uid://r3i80a6v2w0y" path="res://resources/weapons/gun/Gun.tres" id="3_irbyu"]
56
[ext_resource type="Texture2D" uid="uid://dw5vuo3agm77m" path="res://objects/actors/player/template.png" id="3_q5uec"]
6-
[ext_resource type="Resource" uid="uid://ca4y5d7kksi0h" path="res://resources/weapons/sword/Sword.tres" id="3_uqweb"]
77
[ext_resource type="PackedScene" uid="uid://cxlkjx4h6gv5h" path="res://components/collector/Collector.tscn" id="5_q1uwo"]
8+
[ext_resource type="PackedScene" uid="uid://c5w6dv2r65qsd" path="res://objects/hud/HealthBar.tscn" id="7_svy1a"]
89

910
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_p4sxr"]
1011
properties/0/path = NodePath(".:position")
@@ -508,19 +509,33 @@ radius = 32.0
508509
[sub_resource type="CircleShape2D" id="CircleShape2D_xu8dn"]
509510
radius = 80.0
510511

511-
[sub_resource type="Animation" id="Animation_tc2ku"]
512-
length = 0.001
512+
[sub_resource type="Animation" id="Animation_0v3ge"]
513+
resource_name = "Death"
513514
tracks/0/type = "value"
514515
tracks/0/imported = false
515516
tracks/0/enabled = true
516517
tracks/0/path = NodePath(".:modulate")
517518
tracks/0/interp = 1
518519
tracks/0/loop_wrap = true
519520
tracks/0/keys = {
520-
"times": PackedFloat32Array(0),
521-
"transitions": PackedFloat32Array(1),
521+
"times": PackedFloat32Array(0, 0.75),
522+
"transitions": PackedFloat32Array(1, 1),
522523
"update": 0,
523-
"values": [Color(1, 1, 1, 1)]
524+
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)]
525+
}
526+
tracks/1/type = "method"
527+
tracks/1/imported = false
528+
tracks/1/enabled = true
529+
tracks/1/path = NodePath(".")
530+
tracks/1/interp = 1
531+
tracks/1/loop_wrap = true
532+
tracks/1/keys = {
533+
"times": PackedFloat32Array(0.75),
534+
"transitions": PackedFloat32Array(1),
535+
"values": [{
536+
"args": [],
537+
"method": &"queue_free"
538+
}]
524539
}
525540

526541
[sub_resource type="Animation" id="Animation_l1t87"]
@@ -552,17 +567,62 @@ tracks/1/keys = {
552567
}]
553568
}
554569

570+
[sub_resource type="Animation" id="Animation_fx0oj"]
571+
resource_name = "Hit"
572+
length = 0.4
573+
tracks/0/type = "value"
574+
tracks/0/imported = false
575+
tracks/0/enabled = true
576+
tracks/0/path = NodePath("AnimatedSprite:modulate")
577+
tracks/0/interp = 1
578+
tracks/0/loop_wrap = true
579+
tracks/0/keys = {
580+
"times": PackedFloat32Array(0, 0.2, 0.4),
581+
"transitions": PackedFloat32Array(1, 1, 1),
582+
"update": 0,
583+
"values": [Color(1, 1, 1, 1), Color(0.912963, 0.144798, 0.20362, 1), Color(1, 1, 1, 1)]
584+
}
585+
586+
[sub_resource type="Animation" id="Animation_tc2ku"]
587+
length = 0.001
588+
tracks/0/type = "value"
589+
tracks/0/imported = false
590+
tracks/0/enabled = true
591+
tracks/0/path = NodePath(".:modulate")
592+
tracks/0/interp = 1
593+
tracks/0/loop_wrap = true
594+
tracks/0/keys = {
595+
"times": PackedFloat32Array(0),
596+
"transitions": PackedFloat32Array(1),
597+
"update": 0,
598+
"values": [Color(1, 1, 1, 1)]
599+
}
600+
tracks/1/type = "bezier"
601+
tracks/1/imported = false
602+
tracks/1/enabled = true
603+
tracks/1/path = NodePath(".:material:shader_parameter/flash_value")
604+
tracks/1/interp = 1
605+
tracks/1/loop_wrap = true
606+
tracks/1/keys = {
607+
"handle_modes": PackedInt32Array(0),
608+
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
609+
"times": PackedFloat32Array(0)
610+
}
611+
555612
[sub_resource type="AnimationLibrary" id="AnimationLibrary_mt86f"]
556613
_data = {
557-
"RESET": SubResource("Animation_tc2ku"),
558-
"fade_away": SubResource("Animation_l1t87")
614+
"Death": SubResource("Animation_0v3ge"),
615+
"FadeAway": SubResource("Animation_l1t87"),
616+
"Hit": SubResource("Animation_fx0oj"),
617+
"RESET": SubResource("Animation_tc2ku")
559618
}
560619

561620
[node name="Player" instance=ExtResource("1_wrkhm")]
562621
collision_mask = 7
563622
script = ExtResource("2_bhjnv")
564623
chestModifierSpeed = 0.7
565-
weapon = ExtResource("3_uqweb")
624+
life = 100
625+
weapon = ExtResource("3_irbyu")
566626

567627
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." index="0"]
568628
replication_config = SubResource("SceneReplicationConfig_p4sxr")
@@ -590,4 +650,10 @@ libraries = {
590650
"": SubResource("AnimationLibrary_mt86f")
591651
}
592652

653+
[node name="HealthBar" parent="." index="6" instance=ExtResource("7_svy1a")]
654+
offset_left = -27.0
655+
offset_top = -34.0
656+
offset_right = 84.0
657+
offset_bottom = -23.0
658+
593659
[connection signal="on_collecting" from="Collector" to="." method="_on_collecting"]

‎objects/hud/HealthBar.gd

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class_name HealthBar
2+
extends ProgressBar
3+
4+
var RED_COLOR = "e7001f"
5+
var ORANGE_COLOR = "edae14"
6+
var GREEN_COLOR = "3ac428"
7+
8+
func _process(delta):
9+
if value <= max_value / 10:
10+
modulate = RED_COLOR
11+
elif value <= max_value / 3:
12+
modulate = ORANGE_COLOR
13+
else:
14+
modulate = GREEN_COLOR
15+
16+
func init(maxHealth: int) -> void:
17+
max_value = maxHealth
18+
value = maxHealth
19+

‎objects/hud/HealthBar.tscn

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[gd_scene load_steps=2 format=3 uid="uid://c5w6dv2r65qsd"]
2+
3+
[ext_resource type="Script" path="res://objects/hud/HealthBar.gd" id="1_kbje0"]
4+
5+
[node name="HealthBar" type="ProgressBar"]
6+
modulate = Color(0.227451, 0.768627, 0.156863, 1)
7+
z_index = 10
8+
offset_left = -68.0
9+
offset_top = -60.0
10+
offset_right = 206.0
11+
offset_bottom = -33.0
12+
scale = Vector2(0.5, 0.5)
13+
mouse_filter = 2
14+
step = 1.0
15+
show_percentage = false
16+
script = ExtResource("1_kbje0")

‎project.godot

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ config/icon="res://icon.svg"
2020
ProgressionService="*res://services/save/ProgressionService.gd"
2121
UiAudio="*res://components/uicontrols/UIAudio.gd"
2222
SceneTransition="*res://services/transition/SceneTransition.tscn"
23-
MultiplayerManager="*res://services/multiplayer/MultiplayerManager.gd"
2423
StoreManager="*res://services/managers/store/StoreManager.gd"
24+
MultiplayerManager="*res://services/multiplayer/MultiplayerManager.gd"
2525

2626
[debug]
2727

‎scenes/levels/debug/DebugLevel.tscn

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ script = ExtResource("1_ggoyj")
1818

1919
[node name="Player" parent="." instance=ExtResource("1_t7e46")]
2020
weapon = ExtResource("2_sywcb")
21+
chestModifierSpeed = 0.7
22+
maxHealth = 100
2123

2224
[node name="Camera2D" type="Camera2D" parent="Player"]
2325
position_smoothing_enabled = true

0 commit comments

Comments
 (0)
Please sign in to comment.