Health bar system not really working

Godot Version

4.2.2

Question

For whatever reason, when HP is set to 13, it shows 6 bars (of HP), when it should show 6 bars and 1 half bar. It should only show 6 bars if HP is set to 12. When HP is set to 14, it shows 7 bars and 1 half bar when it should be showing 7 bars. At 15 it shows 7 bars and 1 half bar, which is correct.

entire code:

extends Node2D

@export var maxHP: int = 18
@export var HP: int = 15

var eB: Texture2D = preload("res://images/healthNone.png")
var hB: Texture2D = preload("res://images/healthHalf.png")
var fB: Texture2D = preload("res://images/healthFull.png")
var tempatlas

var regions = [
	Rect2(Vector2(238, 0), Vector2(18, 16)),
	Rect2(Vector2(224, 0), Vector2(32, 16)),
	Rect2(Vector2(210, 0), Vector2(46, 16)),
	Rect2(Vector2(196, 0), Vector2(60, 16)),
	Rect2(Vector2(182, 0), Vector2(74, 16)),
	Rect2(Vector2(168, 0), Vector2(88, 16)),
	Rect2(Vector2(154, 0), Vector2(102, 16)),
	Rect2(Vector2(140, 0), Vector2(116, 16)),
	Rect2(Vector2(126, 0), Vector2(130, 16)),
	Rect2(Vector2(112, 0), Vector2(144, 16))
]

# Called when the node enters the scene tree for the first time.
func _ready():
	updateHP()

func updateHP():
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = eB
	tempatlas.region = regions[int(truncate_string_at_character(str(maxHP/2), ".")) - 1]
	$EmptyBar.texture = tempatlas
	
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = hB
	tempatlas.region = regions[add_to_odd(int(truncate_string_at_character(str(HP/2), "."))) - 1]
	$HalfBar.texture = tempatlas
	
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = fB
	tempatlas.region = regions[int(truncate_string_at_character(str(HP/2), ".")) - 1]
	$FullBar.texture = tempatlas

func truncate_string_at_character(input_string: String, target_character: String) -> String:
	var index = input_string.find(target_character)
	if index >= 0:
		return input_string.left(index)
	else:
		return input_string

func add_to_odd(num: int) -> int:
	if num % 2 == 1:
		return num + 1
	else:
		return num

Something about updateHP() seems to be the problem.

For whatever reason, when HP is set to 13, it shows 6 bars (of HP), when it should show 6 bars and 1 half bar. It should only show 6 bars if HP is set to 12.

Since HP is an integer, dividing it by 2 will result in an integer. 13 / 2 is 6.5, but since HP can only store whole numbers, it becomes 6.

	var HP: int = 13
	print(HP / 2) # prints "6"

One workaround is to cast it to a float first, however floats have their own quirks.

	var HP: int = 13
	print(float(HP)/2) #prints "6.5"

You could also double the values of HP in your game to only increment it using even numbers, so that dividing by 2 will always result in a whole number. If you only display the HP to the player using these bars, and not the actual numeric value, the player would never know the difference.

3 Likes

ok i sorta get it but what exactly do i need to change to get this to work? (pretty new to godot)

I updated my comment above. You can cast HP to a float before doing division, as demonstrated. Or make HP itself a float type instead of int.

so should i just change everywhere i use HP and maxHP and convert them to floats?

You could probably get away with changing just the definitions

@export var maxHP: int = 18
@export var HP: int = 15
# to:
@export var maxHP: float = 18
@export var HP: float = 15

but…

It seems like you are doing a lot of strange conversions, from a int to a string to an int? And you seemingly intend to always remove deicmal points anyways so changing your variables to floats should result in the same equation, with more steps.

The regions array is a little confusing, could you share your none/half/full textures?

I think you want something like this? subtracting one from everything is a little scary, if you ever have zero health it will try to find a region out of bounds.

func updateHP():
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = eB
	tempatlas.region = regions[maxHP/2 - 1]
	$EmptyBar.texture = tempatlas
	
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = hB
	tempatlas.region = regions[(HP+1)/2 - 1] # rounds up
	$HalfBar.texture = tempatlas
	
	tempatlas = AtlasTexture.new()
	tempatlas.atlas = fB
	tempatlas.region = regions[HP/2 - 1]
	$FullBar.texture = tempatlas
1 Like