Page 1 of 3

Making a Health Bar - Tutorial

PostPosted: Mon Aug 08, 2005 5:12 pm
by ondy1985
The idea
I found several threads here discussing health bars (or health meters, call it whatever you want) with no satysfying answers on how to do this, so here is my answer.
The aim is to create a bar that will reflect the players health, ammunition or whatever you want, and not have dozens of actors to do that. I'm going to introduce the way I used in my upcoming space shooting game.

1)
It may sound a bit strange, but we will use one text actor for this. First, we need a bitmap "font" that will make the health bar.
Like this one that I have created: Image

2)
Now we have to create the actor in GE. Let's name it "health_bar". Don't add any animations. Click on the Text button in Actor Properties. Now click the New Font button. We find the file with our "font" and set it's properties. The initial character will be 0 and the number of characters is 3. You can write some text into the actor (but remember to use only 0, 1 and 2 characters) to see if it works fine.

3)
Now we need the bar to reflect the player's health. Create "g_PlayerHealth" variable in 'Variables' and make it Global Integer. We will write som simple functions in 'Global Code' to easily change the g_PlayerHealth value and show it via the health bar at the same time.

Code: Select all
void UpdateHealthBar()
{
    int i;
    strcpy(health_bar.text,"");
    for (i=0; i<g_PlayerHealth; i++)
        {
            if (i<=5) strcat(health_bar.text, "0");
            if ((i>5)&&(i<=15)) strcat(health_bar.text, "1");
            if (i>15) strcat(health_bar.text, "2");
        }
}

void ChangeHealth(int modifier)
{
    g_PlayerHealth += modifier;
    if (g_PlayerHealth > 25) g_PlayerHealth = 25;
    if (g_PlayerHealth < 0) g_PlayerHealth = 0;
    UpdateHealthBar();
}

void SetHealth(int value)
{
    g_PlayerHealth = value;
    if (g_PlayerHealth > 25) g_PlayerHealth = 25;
    if (g_PlayerHealth < 0) g_PlayerHealth = 0;
    UpdateHealthBar();
}


We will now have a closer look on this three functions;
SetHealth function sets the player health to the value passed as it's parameter (int value). If the value is higher than maximum allowed (25 in my case), players health is set to the maximum. If it is lower that allowed minimum, it is set to the minimum (0 in my case). Then the UpdateHealthBar function is called.

ChangeHealth function works the same way the SetHealth function works, but instead of setting the g_PlayerHealth variable to have the value of the passed parameter (int modifier), it just adds the modifier to the current g_PlayerHealth value. Be the modifier -1, it substracts 1 point of health, be it 2, it adds 1 to the health value, but will never cross behind the minimum and maximum allowed values. Then UpdateHealthBar function is called.

UpdateHealthBar is the most important part, as it makes the health bar show the value of our g_PlayerHealth variable. You can see, there is a simple FOR cycle running g_PlayerHealth-times (so if we have g_PlayerHealth = 3, the loop will run 3 times). Just before the cycle, we erase everything in the text property of our "health_bar" actor. Than in each cycle, we write new character to the string so in the end, so be the g_PlayerHealth variable set to 3, we would have 3 characters in 'health_bar.text' string. As you can see, I use 3 different characters, so the bar will be red on one end, yellow in the middle and green on the other end, so it looks cool.

4)
We now have everything set up. In the game, we can just call ChangeHealth(modifier) or SetHealth(value) function and the health bar will react. Now, when the g_PlayerHealth variable has the value of 25, the bar looks like this:Image

Last words
Although my english is poor I hope you have understood the basics of creating a health bar. If not, just post here and I will try to explain it better.

I don't say that this is the best way how to do that, it's just the best I came up with.

PostPosted: Mon Aug 08, 2005 6:52 pm
by ondy1985
Here you can see it in-game (lower left corner of the screen):
Image

PostPosted: Mon Aug 08, 2005 9:26 pm
by willg101
Thanks for the advice!

( :shock: nice graphics!!)

PostPosted: Tue Aug 09, 2005 9:52 pm
by Just4Fun
ondy1985:

Interesting solution. I appreciate your generousity in sharing it with all of us... :)

PostPosted: Wed Aug 10, 2005 4:30 pm
by ondy1985
willg101:
Thanks. I'm proud of the graphics because I'm programmer, not drawer. But I did only the background and hud graphics. All ships' graphic in the game have been made by my friend Farmer_TED. You can see just one ship on the screen, but others look even better. I dont like the sharp edges of the ships though. Gotta do something with that :).

Just4fun:
Thank you, though I'm not sure about the emoticon you used at the end of the sentence. It makes the sentence look a little bit sarcastic... ;)

I would appreciate if some could use this type of health bar in his/her game and tell me how much it affects the game performance on PocketPC. Does it make the game run slower? I'm trying to find out the best solution to do health bars and not affect the game playability. Thank you for any feedback on this.

PostPosted: Wed Aug 10, 2005 4:53 pm
by makslane
I think there is no performance issues with this solution.

PostPosted: Fri Aug 12, 2005 12:13 am
by Just4Fun
It makes the sentence look a little bit sarcastic...

Hmm, that is the first time anyone has ever told me that they thought that a the little Smile guy was sarcastic. Maybe a picture isn't worth a thousand words after all! Smiley was just my way of saying I was happy about your contribution. I guess I will have to rethink my smiles...

PostPosted: Fri Aug 12, 2005 7:55 am
by jazz_e_bob
Just4Fun wrote:
It makes the sentence look a little bit sarcastic...

Hmm, that is the first time anyone has ever told me that they thought that a the little Smile guy was sarcastic. Maybe a picture isn't worth a thousand words after all! Smiley was just my way of saying I was happy about your contribution. I guess I will have to rethink my smiles...


:)

PostPosted: Fri Aug 12, 2005 4:38 pm
by ondy1985
Just4Fun wrote:Hmm, that is the first time anyone has ever told me that they thought that a the little Smile guy was sarcastic. Maybe a picture isn't worth a thousand words after all! Smiley was just my way of saying I was happy about your contribution. I guess I will have to rethink my smiles...

Forget about it. I just didn't know whether the Smile meant "I'm happy" or "The last sentence was a joke".
:)

makslane wrote:I think there is no performance issues with this solution.

I guess it's much faster than using 25 separated actors.

PostPosted: Fri Aug 12, 2005 7:07 pm
by willg101
LOL :lol:

I think this is getting a little too confusing for me!

PostPosted: Fri Aug 12, 2005 8:24 pm
by jazz_e_bob
ondy1985

G'day mate,

This forum is generally free from sarcasm/flaming etc.

You can pretty well assume that a smile is a smile here.

I only smiled because J4F is possibly the nicest person on this board and would NEVER make a backhanded remark.

Good on ya mate. You are a creative programmer who will do well with this product.

:) 8)

PostPosted: Fri Aug 12, 2005 8:27 pm
by jazz_e_bob
To get back on topic..

Health bar is good.

Perhaps a little too complicated for my small brain. :wink:

Give this one a look.

http://www.artsystems.com.au/game%20editor/quickMeter.zip

Regards,

jazz

PostPosted: Sun Aug 21, 2005 11:41 pm
by BeyondtheTech
Here's two things I did with ondy1985's concept, which, by the way, is very welcome and appreciated.

1. The 25 strcat commands may be replaced with just two commands. Having a full meter string and only grabbing the first 'n' characters is much more simplified and less of a performance hit.

2. If you decide to do this routine in the Draw Actor (for an automatic update), you can only update when a change has occured.

Code: Select all
Global:
strcpy(fullmeter,"0000000011111111222222222");

Routine:
if (weaponsmeter_old!=weaponsmeter_current)
{
    strcpy(text,"");
    strncat(text,fullmeter,weaponsmeter_current);
    weaponsmeter_old=weaponsmeter_current;
}

PostPosted: Sun Aug 21, 2005 11:44 pm
by willg101
jazz_e_bob wrote:I only smiled because J4F is possibly the nicest person on this board and would NEVER make a backhanded remark.


Jazz: You, J4F, and Makslane are all the probably the nicest people here!

(not to say they're the only ones! :wink: )

PostPosted: Mon Aug 22, 2005 4:19 pm
by ondy1985
BeyondtheTech wrote:
Code: Select all
Global:
strcpy(fullmeter,"0000000011111111222222222");

Routine:
if (weaponsmeter_old!=weaponsmeter_current)
{
    strcpy(text,"");
    strncat(text,fullmeter,weaponsmeter_current);
    weaponsmeter_old=weaponsmeter_current;
}


That's a very smart code there! I wonder why I didn't do it like that...