Godot Version
Godot 4.3.stable.steam
Question
TL;DR
I have been struggling around 8 months with my hurt logic to work properly, but never have I ever been able to do so. (I’m still very beginner at programming).
So if player enters hitbox, player takes damage → invulnerability timer starts. Now finally if player stays colliding with the hitbox, player takes continuous damage every time invulnerability timer runs out, but the problem I have been having is:
if player collides with hit box → player takes damage → invulnerability timer starts → player leaves hitbox and re-enters while the invulnerability timer is still running → player stays inside hitbox after invulnerability timer stops → player can keep colliding with the hitbox as long as player wishes until leaving and re-colliding again.
Code:
var is_hurt: bool = false
var is_dead: bool = false
@export var invulnerability_time : float = 2.0
var is_inside_hitbox: bool = false
@onready var is_invulnerable_time_enabled = invulnerability_time > 0
@onready var invulnerability_timer = Timer.new()
func _ready():
##my other codes##
if is_invulnerable_time_enabled:
add_child(invulnerability_timer)
invulnerability_timer.wait_time = invulnerability_time
invulnerability_timer.one_shot = true
invulnerability_timer.timeout.connect(_on_invulnerability_timeout)
##rest of my orther codes##
func start_invulnerability_timer():
if is_invulnerable_time_enabled:
invulnerability_timer.start()
func start_hurt_animation():
if not is_invulnerable_time_enabled and not is_dead and (not animated_sprite_2d.is_playing() or animated_sprite_2d.animation != "player_hurt"):
animated_sprite_2d.play("player_hurt")
func is_invulnerability_timer_running() -> bool:
return not invulnerability_timer.is_stopped()
func _on_invulnerability_timeout():
if is_inside_hitbox and !is_dead:
currentHealth -= 1
healthChanged.emit(currentHealth)
if currentHealth <= 0:
currentHealth = 0
is_dead = true
animated_sprite_2d.play("player_ded")
lifeLost.emit()
else:
if not is_flashing:
is_flashing = true
flash_times = 0
animated_sprite_2d.play("player_hurt")
is_hurt = true
start_hurt_animation()
start_invulnerability_timer()
func _on_hurt_box_area_entered(area):
if area.name == "hitBox":
if not is_invulnerability_timer_running():
if not is_inside_hitbox:
is_inside_hitbox = true
currentHealth -= 1
healthChanged.emit(currentHealth)
print("Current Health: ", currentHealth)
if currentHealth <= 0:
currentHealth = 0
is_dead = true
animated_sprite_2d.play("player_ded")
lifeLost.emit()
else:
if not is_flashing:
is_flashing = true
flash_times = 0
animated_sprite_2d.play("player_hurt")
is_hurt = true
start_hurt_animation()
start_invulnerability_timer()
func _on_hurt_box_area_exited(area):
if area.name == "hitBox":
is_inside_hitbox = false
If you got any further questions about the issue, let me know.
I am well aware that this is possibly spagetti like, so my apologies!
It has been re-written / altered like 50 times now.
(There are more related to the code like sprite flash and respawn function, but those definitely doesn’t affect the issue so I left them off).
Thank you for checking this post and any help would be greatly appreciated!