Damage System and health system

i am trying to make a damage and health system where as of right now atleast if the player (characterbody2d) touches the enemy (area2d) they lose one heart out of three at the moment. But i am unable to figure out why when the charachter hits the enemy it does nothing. Ideally I want to be able to remove the heart and replace it with a half a heart sprite instead.

var hearts_list : Array[TextureRect]
var health = 3

func _ready() → void:
var hearts_parent = $CanvasLayer/HBoxContainer
for child in hearts_parent.get_children():
hearts_list.append(child)
print(hearts_list)

func take_damage():
if health > 0:
health -= 1
$damage.play(“damage”)
update_heart_display()

func update_heart_display():
for i in range(hearts_list.size()):
hearts_list[i].visible = i < health

Where are you calling the take_damage function?


Make sure to format your code pastes

Im not exactly sure where to call it, I oringally thought that I should call in inside of the enemy. The idea was that when the charachter hits the enemy the take damage function is called and the player loses a heart. But im not sure how to call a function that is inside of a different script nor if i should or not.

Calling inside the enemy is usually what I do, makes sense as “the enemy make the player take_damage”.

As your enemy is an Area2D you can connect the body_entered signal onto the enemy’s script. Then you can check if the colliding body is a player, preferably using the player’s class_name if you set one.

func _on_body_entered(body: Node2D) -> void:
    if body is Player:
        body.take_damage()

I put that in but i am not completey sure if it is working how I want it to. Im not sure if the way I am doing it is inncorect but it is not removing a heart from the top left of my game where there are three containers located when the charachter touches the enemy sprite. I did put the take damage function in the enemy though.

var hearts_list : Array[TextureRect]
var health = 3

func _ready() -> void:
   var hearts_parent = $CanvasLayer/HBoxContainer
   for child in hearts_parent.get_children():
   	hearts_list.append(child)
   	print(hearts_list)
   
func take_damage():
   if health > 0:
   	health -= 1
   	$damage.play("damage")
   	update_heart_display()
   	
func update_heart_display():
   for i in range(hearts_list.size()):
   	hearts_list[i].visible = i < health

The player code looks fine, good technique for making the hearts invisible. Make sure the enemy’s function is connected to the signal. Add a print or breakpoint to see if the collision is going through to the function.

It can touch now, although im getting an error i am unsure about what is causing it?

Your error states that $damage is null, are you sure there is a child of the player scene named “damage”?

I completely forgot i had removed it. it is all working now thank you so much!