How do you make a Secret of Mana style Power Bar?

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

I’m trying to make a power bar for an ARPG where when the player attacks, the power bar jumps down to zero, and immediately starts recharging back to 100 percent. When the power bar recharges, the values interpolate so that instead of jumping immediately from zero to one-hundred percent you briefly see several in-between values appear in a flash.

If the power bar recharges all the way to one-hundred percent, the player’s attack will be at its strongest, or the player can do a special attack. If the power bar recharges only partially and the player attacks, the player’s attack will be weaker than it would be if the power bar were fully charged, and the player’s attack strength will depend on how much the power bar has recharged.

Here’s a link to a vid showing what I’m looking for:

Pay special attention to how the number in the power bar changes as it recharges (the power bars are at the bottom of the screen.)

Long story short, I’ve tried different setups and I can’t figure out how to recreate this feature. Can you help me figure out how to do this?

:bust_in_silhouette: Reply From: MarshaLee

Hello dude, so i did some fast code, im not really good at programing, so i dont know is this the correct way but, it works(i guess), i hope this could help you.

var count = false
var wait = false

onready var bar = $TextureProgress
onready var cooldown = $Cooldown

var rng =

var Maximum = 100 #max mana
var actual = 0 #Current mana

func _ready():

func _process(delta):
	var add_number = rng.randi_range(4,5)
	if wait == false: #If its not in couldown
		if count == true: # Wait 0.2 sec to add again
			if actual < Maximum:
				actual = actual + add_number
			if actual > Maximum:
				actual = 100
			count = false
			print (actual)

func _input(event):
	if wait == false:
		if event.is_action_pressed("attack"): #Spacebar
			actual = 0
			wait = true
			print ("cooldown...")

func _on_Timer_timeout():
	#Sinal with a TIMER that autostars every 0.2 sec
	count = true

func _on_Cooldown_timeout():
	#Cooldown timer
	wait = false

This is what it shows

:bust_in_silhouette: Reply From: Fgico

It might not be the most efficient way but you could try using a label and change it’s text in the _process() function,
something like this:

onready var powerBarLabel = get_node("path/to/label")

var playerAtk : int = 1
var powerBarValue : float = 1
var powerBarChargeRatio : int = 1

func _process(delta):
#clamp assures us the value stays between 1 and 0
var powerBarValue = clamp(0, 1, powerBarValue += delta * powerBarChargeRatio)

if( Input.is_action_just_pressed( "attack")):
	var attack = generateAttack()
	#scale attack damage and reset powerBar to 0
	attack.damage = powerBarValue * playerAtk 
	powerBarValue = 0

#update the label
powerBarLabel.text = str(powerBarValue * 100) + "%"

sorry for the formatting, I’m new to this forum

:bust_in_silhouette: Reply From: RoniPerson

For the GUI part you could use a TextureProgress node to show a charging bar
In the script create a var

var punch_timer = 0

in the process set the value of the TextureProgress to the var and add delta to it

func _process(delta):
  punch_timer += delta

  # use a reference to the texture progress node, idk how you structure your gui
  texture_progress.value = punch_timer

when punching you can use the value of the var to apply bonuses to the punch.
In this case the damge is boosted by the percent of the reached meter
And reset the var to zero when punching.

func punch():
  var real_dmg = base_damage * (1+clamp(punch_timer, 0, max_value) /max_value )

  # your punching logic here

  punch_timer = 0