0 votes

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
in Engine by (180 points)

1 Answer

+1 vote
Best answer

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
by (1,401 points)
selected by

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

you're welcome. Glad it works.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories