Health and Damage system not working

Godot 4

I need help with my project. My game is a top-down 2d game. I have an enemy ai that chases the player around a little box and I want the enemy to damage the player by 1 hitpoint every time it touches the player (the player has 10 hitpoints), but whenever the enemy touches the player the health does not go down in any way and the enemy just pushes the player. How do I make the player take damage? This is the code for the player:

extends CharacterBody2D
var speed = 200

func _physics_process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed("ui_left"):
		velocity.x -= speed
	if Input.is_action_pressed("ui_right"):
		velocity.x += speed
	if Input.is_action_pressed("ui_up"):
		velocity.y -= speed
	if Input.is_action_pressed("ui_down"):
		velocity.y += speed

	self.velocity = velocity.normalized() * speed
	move_and_slide()
	
	

var max_health = 10
var current_health = 10

var health_label

func _ready():
	# Initialize health_label by getting the reference to the PlayerHealthLabel node
	health_label = get_node("PlayerHealthLabel")

func _process(delta):
	# Update the health label text
	health_label.update_health(current_health, max_health)

func take_damage(damage):
	current_health -= damage

Here’s the code for the label:

extends Label

func update_health(current_health, max_health):
	self.text = "HP: " + str(max_health) + " / " + str(current_health)

Here’s the code for the enemy:

extends CharacterBody2D

var speed = 150
var player_chase = false
var player = null

func _physics_process(_delta):
	if player_chase:
		var direction = player.position - position
		direction = direction.normalized()  

		
	

		# Move towards the player
		position += direction * speed * _delta

func _on_area_2d_body_entered(body):
	player = body
	player_chase = true

func _on_area_2d_body_exited(_body):
	player = null
	player_chase = false


var damage_amount = 1

func _on_Enemy_area_entered(area):
	if area.is_in_group("player"):
		# If colliding with the player, apply damage
		area.take_damage(damage_amount)

Capture

The left one is the enemy and the right one is the player. The circle collision around the enemy is a collisionshape2d and is supposed to detect the player when it enters the circle and chase it. The square collision around it is to prevent it from clipping into the wall. The label only shows when I play the scene.

Calling area.take_damage(damage_amount) within the code for the enemy? I’m pretty sure the enemy code doesn’t have acess to that function since you defined it in the player code.

What you need to do is create a global GameManager script and define the function to deduct the health there.

Autoload it and then, you can call GameManager.take_damage(damage_amount)

You want to connect to the enemy’s hit box body entered. the area_entered signal only works when a area enters it, but the player is a CharacterBody2D

This is incorrect. The area_entered and body_entered signals provide references to the area or body that entered the area. You should be able to call any method or access any property from that reference. Resorting to handling something like player health from a singleton shouldn’t be necessary, and is kind of an unclean solution depending on the project.

Your Player is a CharacterBody2D, but you’re using the area_entered signal on your enemy code. This will not fire since CharacterBody2D is not an area, but a body. You should instead connect a method to the enemy’s body_entered signal, and handle dealing damage to the Player there.

1 Like

I believe updating coin and health should be done using global GameManager script. Since there might be many levels in the game, and many things that can deduct health such as traps, enemys or falling off the world.

Do you recon he should be creating and updating health everytime for this in each script file? Instead of just having it defined globally once and then calling it when needed?

The area of body entered signal can access functions that isn’t defined in the same file where they are being used too? Please help my beginner self understand :sweat_smile:

I managed to get it working. Thank you guys