I'm making a game that is a bit like Fruit Ninja classic. Basically, when you fail to click a box three times, you lose. I'm currently working on the GUI, and in the top right corner I want a life counter of sorts, like the one in that game.

Here's an example in Minecraft:

There are probably a few good ways to do this and a lot of bad ways. It would be nice if I could just enter a number somewhere and then it would make some hearts greyed out. A pseudocode example: func lose_life(): get_node("heart_counter").hearts -= 1

I'm surprised no one has asked about this before. So if anyone has good ideas for how I could make this work, it would be great if you shared them! Thank you.

For a jam game I made, I just did the brute force approach and made three sprites and some simple code that takes a value and enables/disables the hearts as necessary based on the number passed.

Here is the relevant snippets of the code I used:

# Located in a function called _setup()
panel_player_1 = get_node("Top_Bar_Container/Panel_P1");
panel_player_1_health_1 = get_node("Top_Bar_Container/Panel_P1/Heart_01");
panel_player_1_health_2 = get_node("Top_Bar_Container/Panel_P1/Heart_02");
panel_player_1_health_3 = get_node("Top_Bar_Container/Panel_P1/Heart_03");
panel_player_1.visible = false;

# Located in a function called update_player_health_ui
if (player_health <= 0):
	panel_player_1_health_1.modulate = Color.black;
	panel_player_1_health_2.modulate = Color.black;
	panel_player_1_health_3.modulate = Color.black;
elif (player_health == 1):
	panel_player_1_health_1.modulate = Color.white;
	panel_player_1_health_2.modulate = Color.black;
	panel_player_1_health_3.modulate = Color.black;
elif (player_health == 2):
	panel_player_1_health_1.modulate = Color.white;
	panel_player_1_health_2.modulate = Color.white;
	panel_player_1_health_3.modulate = Color.black;
elif (player_health >= 3):
	panel_player_1_health_1.modulate = Color.white;
	panel_player_1_health_2.modulate = Color.white;
	panel_player_1_health_3.modulate = Color.white;

I wouldn't necessarily recommend writing a health counter like this if you have the time to write a better system, but because it was for a game jam I decided to use the simplest solution first. A better solution might be making each heart in the heart counter its own object, and then using something like a for loop to tell each heart to update based on the value passed.

2 years later

You can use a TextureProgress node with a texture that has as many tiled hearts as you'd like. Set min to 0 and max to the number of hearts. Change the step property to the increment in which hearts should be adjustable (half-hearts, full hearts, …) and adjust value as desired.

8 months later