GameMaker [SOLVED] Health Bar not showing correct HP

S

Sarena

Guest
I set up a health bar to go along with my player's hp (which is 4), but for some reason the health bar image itself is acting as if my player only has 3 hp.

I attached an image to showcase the issue.

Here is my objGUI's Create Event:
Code:
// Set Global Variable
global.playerhp = 4;
And the Draw GUI Event:
Code:
// Draw Sprite
draw_sprite(sprHPBackground, 0, view_xview[0] + 30, view_yview[0] + 50);

// Draw Sprite Transformed
draw_sprite_ext(sprHPBar, 0, view_xview[0] + 30, view_yview[0] + 50, global.playerhp / 4, 1, 0, $FFFFFFFF & $ffffff, ($FFFFFFFF >> 24) / $ff);

// Draw Sprite
draw_sprite(sprHPBorder, 0, view_xview[0] + 30, view_yview[0] + 50);

// If Variable
if(global.playerhp <= 0)
{
    // Destroy Instance
    instance_destroy();
}
 

Attachments

CloseRange

Member
how certain are you that it is the gui and not the collision code?
have you tried adding draw_text(0, 0, global.playerhp); just to make sure the hp is actually what you think it is?

your code looks fine at first glance. If there is nothing wrong with the hp try changing it to / 5 instead of / 4 seeing what happens.
 
T

Thunder Lion

Guest
Can I offer another solution?
Draw the backdrop as you did.

But have health work like this instead:
Create Event:
globalvar playermaxhp, playerhp;
playermaxhp=4
playerhp=playermaxhp
health=(playerhp/playermaxhp)*100

Step Event:
health=(playerhp/playermaxhp)*100

Then draw the health bar using the draw health bar function. It will do exactly the same thing but it will scale appropriately.
 
S

Sarena

Guest
how certain are you that it is the gui and not the collision code?
have you tried adding draw_text(0, 0, global.playerhp); just to make sure the hp is actually what you think it is?

your code looks fine at first glance. If there is nothing wrong with the hp try changing it to / 5 instead of / 4 seeing what happens.
I double-checked and it is indeed the GUI code. I also tested drawing text, and it draws the correct number. When I change it to /5 instead of /4, it starts out with the HP looking like it is at 3 instead of the full 4 and still looks like it is at 0 when there is still 1 HP left.

Can I offer another solution?
Draw the backdrop as you did.

But have health work like this instead:
Create Event:
globalvar playermaxhp, playerhp;
playermaxhp=4
playerhp=playermaxhp
health=(playerhp/playermaxhp)*100

Step Event:
health=(playerhp/playermaxhp)*100

Then draw the health bar using the draw health bar function. It will do exactly the same thing but it will scale appropriately.
I'm not entirely sure how the draw health bar function works exactly, so I may have inputted something incorrectly, but even with trying these suggestions, I have similar result. The only difference is that the health bar is drawn very tiny in the top left corner, and it does not go down at all when the player is damaged.

Here's what my events look like now:

Create Event:
Code:
// Set Global Variable
global.playermaxhp = 4;

// Set Global Variable
global.playerhp = global.playermaxhp;

// Assign Variable
health = (global.playerhp/global.playermaxhp) *100;
Step Event:
Code:
// Assign Variable
health = (global.playerhp/global.playermaxhp) *100;
Draw GUI Event:
Code:
// Draw Value
draw_text(100, 100, string(global.playerhp) + "");

// Draw Sprite
draw_sprite(sprHPBackground, 0, view_xview[0] + 30, view_yview[0] + 50);

// Draw Healthbar
draw_healthbar(4, 4, 0, 0, 4, $FF0606D1 & $FFFFFF, $FF00FF15 & $FFFFFF, $FF0606D1 & $FFFFFF, 0, (($FF0606D1>>24) != 0), (($00FFFFFF>>24) != 0));

// Draw Sprite
draw_sprite(sprHPBorder, 0, view_xview[0] + 30, view_yview[0] + 50);

// If Variable
if(global.playerhp <= 0)
{
    // Destroy Instance
    instance_destroy();
}
 
Change any code saying this:
Code:
health = (global.playerhp/global.playermaxhp) *100;
To this:
Code:
health = floor((100 / global.playermaxhp) * global.playerhp);
You do this because healthbars use a value between 0 and 100, not 0 and 4, and the code you're using will not scale that correctly from what I can see. (I might be wrong about this bit though, I've just told you the way I do it.)

You floor the health because you always want health to be an integer, and not have a decimal point. This means 0.75 will be made 0, or 5.32 will be made 5; it always rounds the number down.

Also, you're using the healthbar function incorrectly; it should be used like this:
Code:
draw_healthbar(2, 2, 258, 10, health, c_black, c_red, c_lime, 90, true, true);
This will draw a health bar 2 from the top left of the screen with a height of 8 and a width of 256, using the variable 'health' to say how filled it is. The last two arguments control weather a background and border are drawn.

Reference the manual for more information: Link

Also a little side note:
You don't need to use view_xview[0] in the Draw GUI event, since it is always aligned with the screen.
 
Last edited:
S

Sarena

Guest
Thank you so much, thestolenbattenberg! This works correctly now :D

As an addition now, is there an easy way to transfer this over so that it can use my HPbar image rather than the default drawn solid colors?
I've been playing around with a few different changes, but haven't seemed to figure out a good way to transfer it over.

Thanks!
 
S

Sarena

Guest
Look into draw_sprite_part() in the manual. That's probably what you're looking for. =)
This was very helpful and helped me come to a different conclusion, thank you!

I ended up making multiple frames within the sprHPBar with different sizes of the health bar and was able to check the global.playerhp variable's number to show the specific sprite.

Thank you to everyone here who helped me come to this final conclusion!
 
I'm glad you got your problem solved, but is that actually what you wanted to do? You can just draw a percentage of your healthbar sprite using draw_sprite_part(), without having to make separate frames or anything. :x
 
S

Sarena

Guest
It ended up working better with the separate frames so that I could change them to specific colors over time. I do see the benefits of the draw_sprite_part() though, so maybe I'll make good use of it in the future, thanks! :)
 
Top