How to add recharcing stamina bar after a while?

Question

Hi, I’m new to godot and I made a basic game that you can run and hit your enemy and I added a stamina bar. When the player hits to enemy, the stamina which is 50 at the beginning starts to get low. Then I added a basic code that recharges the stamina bar like this:
if stamina < 50:
stamina += 1 * delta

But then I realized that it doesn’t allows to player to get tired. So I want to add a code like when player isn’t attacking a 4 second timer starts to run out. After timeout, stamina starts to recharge so I added a code like this:
if stamina < 50:
$StaminaTimer.start()

func on_stamina_timer_timeout():
stamina += 1

But it didn’t work. If you help, thank you from now!
(and if it solves i’m gonna add a code that stamina only recharges when not attacking)

The problem with the code above is that at the end of the timer, stamina will be incremented by 1 and that’s it, until stamina is spent again, then the 4 sec timer end, then incremented by 1 again. Etc.

One way to tackle this would be to use a flag at the end of the timer that would increase the stamina in the _process() method.

#Something like
func on_stamina_timer_timeout():
    incStamina = true

func _process(delta):
    if incStamina:
        # This would be probably too fast, but you get the idea
        stamina += 1 * delta

func player_gets_hurt():
    incStamina = false
1 Like

I guess you called this in _process or physics_process (i.e. every frame) in which case calling the start() method on your StaminaTimer will reset the wait_time every frame to the default. Instead, only start the Timer if it isn’t already running:

if $StaminaTimer.is_stopped():
    $StaminaTimer.start()

However, now the player will only regenerate one stamina every 4 seconds (if that’s the wait_time of your timer). So what you could do instead is introducing a variable that indicates if the player should regenerate stamina or not:

var regenerate_stamina := false

func _physics_process(delta):
    if regenerate_stamina:
        stamina += 1 * delta
    elif $StaminaTimer.is_stopped():
        $StaminaTimer.start()

func on_StaminaTimer_timeout():
    regenerate_stamina = true

(Note that you have to reset regenerate_stamina to false, if you want to apply the delay again another time)

1 Like

Your solution should be right, I think like that too but when I try that codes it doesn’t works again.

You do realize that if we don’t see the code that doesn’t work, it’s next to impossible to tell you where it fails, right?

My code is the same as you wrote.
var regenerate_stamina := false

func _physics_process(delta):
if regenerate_stamina:
stamina += 1 * delta
elif $StaminaTimer.is_stopped():
$StaminaTimer.start()

func on_StaminaTimer_timeout():
regenerate_stamina = true

Please learn to use the CTRL-E (preformatted text) tag so the code you write is legible. It makes things much easier for everyone.

In the case above, you should see something happening. To do a quick and dirty debug, dump some print statements to see where things run and where it ends, values, etc.

Ex:

func _physics_process(delta):
    print("regen stam? ", regenerate_stamina)
    if regenerate_stamina:
        stamina += 1 * delta
        print("new stam val : ", stamina)
    elif $StaminaTimer.is_stopped():
        $StaminaTimer.start()

print is your friend.

2 Likes

Thanks, I tried it and it says regen stamina is always false. So I guess there is a problem with the timer.

Have you made sure the on_StaminaTimer_timeout callback is actually called (again: use prints!)? Did you connect it to your timer’s timeout signal?

2 Likes

Yes and problem has somehow solved but another problem begun. When I run the game, after a while it starts to increase the stamina even though I don’t use my stamina bar.

:point_up: Again: You have to reset regenerate_stamina to false again.

2 Likes

It’s also false.

Then you change the stamina somewhere else in your script as well. If regenerate_stamina is false, with my code stamina won’t change.