How to improve the use of progress bar

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Idleman

There is a power recharge system in my game.There are 8 shots, once fired, a power bar will start recharging automatically to reload the fired bullets. I use a texture progress bar in indicate a time period, once time up, the shots are recharged.

The code I came up with works when shots are not fired frequently, but if many single shots are fired in a short period of time, the outcome is not very ideal. Some time the bar will freeze for a while and suddenly a few shots will be recharged instantly instead of one by one. I think this has something to do with the time out, but not sure how to optimise it. I am new to Godot, and hoping if some experienced coder could provide some advise to get a better result, thank you.

extends TextureProgress

func _ready():
  PlayerStats.connect("power_count_changed", self, "set_power_bar")

func set_power_bar(value):
  if value < 8:
	power_charge()

func power_charge():
  value = 0
  for i in 10:
    yield(get_tree().create_timer(0.5), "timeout")
    value += 10
  value = min(value, 100)
  PlayerStats.power_count += 1
  value = 0
:bust_in_silhouette: Reply From: deaton64

Hi,
I think the reason you are getting the issue, is because every time the ammo value (which I assume is the value variable) is less than 8 you are calling the power_charge() function . You need to wait for the power bar to refill, before you call the function again.

I’ve managed to reproduce what you were doing by adding a label to the progress bar, so I could see the ammo count. I used a variable called _ammo as it made more sense to me.
I moved the ammo check to the _process() function and added a flag to check if the bar is charging. I’ve dropped the timer value, so I can see it charging.
I think if you call set_power_bar it should set the _ammo value and use the power charge function.

The code has the mouse button test in it and an update to the label, which you can remove. This should work, let me know if it doesn’t. You may have to change the _ammo variable to work with the rest of your project.

extends TextureProgress

var _ammo = 8
var _charging = false


func _ready():
	_update_shots()


func _process(_delta: float) -> void:
	if _ammo < 8 and !_charging:
		power_charge()
		_charging = true


func _input(event):
	# check for mouse button
	if event is InputEventMouseButton and event.pressed:
		if _ammo > 0:
			_ammo -= 1
			_update_shots()


func _update_shots() -> void:
	$Label.text = "Shots left = " + str(_ammo)


func set_power_bar(value):
	_ammo = value


func power_charge():
	value = 0
	for i in 10:
		yield(get_tree().create_timer(0.1), "timeout")
		value += 10
	value = min(value, 100)
    # PlayerStats.power_count += 1
	_ammo += 1
	_update_shots()
	value = 0
	_charging = false

Thank you so much giving advise and taking time to write the code. I have implement it into my project, it works.

Idleman | 2020-07-08 12:25

you’re welcome. Glad it works.

deaton64 | 2020-07-08 13:49