Damage Logic Issue

Godot Version

4.6

Damage Logic Issue

Hello, I am new to programming in general and I have a little problem with my HP loss logic. Initially the player's hurtbox was active all the time, which led to it to not detect spikes if the player stood on them while invincible and then the invincibility period ran out. I solved it by making the hurtbox disabled for the amount of time invincibility was on, but now I have another problem. If the p,ayer detects two damage boxes at the same time, it will take both damage hits inmediately, so I need to make sure that the player only recieves one hit at a time. How could I do that?

What does your code look like? If invincibility is a Timer you could only take damage if it .is_stopped(), then start it.

no yeah, fortunatedly the damage works as intended. You don’t suffer damage if you’re invincible, and once your hurtbox reenables, if any enemy hitbox is inside your hurtbox then you take damage. My issue here is that if there are two bodies overlapping the player’s hitbox, the damage function will be called twice and you’ll take both hits.

I understand, but script functions are never called at the exact same time so there must be a way to detect that invincibility has started before processing the other collision. Pasting your code would help to find such a variable or function.

okay

func _on_area_2d_body_entered(body: Node2D) → void:
#hplose
if _muerto:
return
if _vida > 1 and _hitinv == false and _golpeado == false:
hurtbox.set_deferred(“disabled”, true)
AudioController.play_damage()
velocity.y = _verknockback
_golpeado = true
_dash = false
_vida -= 1
_actualizarhp()
sprite2D.material = material_blanco
await get_tree().create_timer(0.05).timeout
sprite2D.material = null
_hitinv = true
await get_tree().create_timer(0.5).timeout
_golpeado = false
_parpadeo()
await get_tree().create_timer(3).timeout
_hitinv = false
hurtbox.set_deferred(“disabled”, false)
elif _vida > 0 and _hitinv == true:
pass
else:
_muerto = true
AudioController.play_death()
padrecorazones.queue_free()
sprite2D.scale.x = 1
velocity.y = -500
collision_mask = false
sprite2D.material = material_blanco
await get_tree().create_timer(0.05).timeout
sprite2D.material = null
await get_tree().create_timer(4).timeout
personaje_muerto.emit()

You do set _hitinv = true after an await, so they will only be invincible after the frame (or three) has finished, if you place this line before the await it should resolve only one collision at a time.

It may be better to use a Timer node or AnimationPlayer instead of many create_timers. await is tricky and usually causes many issues better resolved by connecting signals.


Make sure to paste code in a code block for proper formatting

thanks, that was the issue

also thanks for the tip, I’ll try to use it