[GameMaker Tutorial] Drawing custom health bars with sprite parts

on September 5, 2017 - 1352 Views

GameMakerBlog Tutorials

Drawing Health Bars

Health bars (or HP Bars) are almost mandatory in any game, and even if it is not a traditional health bar these techniques will hold true for any bar that has positive or negative progress including Time based bars like those seen in Adventure Capitalist, Loading bars to let players know something is happening and what percent that something is on, Mana or Stamina bars and of course everyone’s favorite: Experience bars. GameMaker Studio 2 has a built-in function for drawing health bars for you called:  draw_healthbar which works incredibly well and is easy to implement but what about a fancy progress bar or health bar? Well, for that you need to draw it yourself; worry not though, as I will show you how and then you can apply this to not just bars but for other images as well. What do I mean? Read on to find out.

Always eat free when you can

The built-in GameMaker Studio 2 draw_healthbar function is very nice, easy and simple to use, the signature is:

draw_healthbar(x1, y1, x2, y2, amount, backcol, mincol, maxcol, direction, showback, showborder);

So what do we have here really? Well from right to left:

  • If you read my tutorial on What is a Room? then the first four parameters look familiar as they form the classic square
    • X1,Y1 is the start point for the top of the square
    • X2,Y2 is the end point for the bottom of the square
      • This square will form the space for the health bar
    • amount is how much of the bar should be filled
      • If this is an HP bar, it should be filled with the current percentage of how much health the player has left
    • backcol is the background color of the square itself
      • This color will show when the health bar is not full, filling in the missing health bar part
    • mincol is the color that the end of the health bar will be when hp or progress percent reaches 0
    • maxcol is the color at the beginning of the health bar when hp or progress percent reaches 100
      • Important note: As the progress goes up or down the health bar colors will change automatically with the middle of the health bar being a mix of the two colors chosen for mincol and maxcol
        • If mincol = red and maxcol = blue then middle of the health bar will be purple
    • direction is which way the health bar depletes
      • 0 = left = the health bar is full at the right side and depletes to 0 going towards the left
      • 1 = right = the health bar is full at the left side and depletes to 0 going towards the right
      • 2 = top = the health bar is full at the bottom and depletes to 0 going towards the top
        • Like opening your blinds on a window, the entire bar slowly depletes upwards
      • 3 = bottom = the health bar is full on the top and depletes to 0 going towards the bottom
        • Like a pop up road barrier that is fully up and then slowly goes back into the ground
    • showback is a Boolean that when true shows the background set by backcol and if false it shows no background
    • showborder is a Boolean that when true shows a 1px border and shows no border when false

Now an example of a health bar is:

draw_healthbar(x-20, y, 250, 50, (playerCurrentHP/playerMaxHP) * 100, c_black, c_red, c_lime, 0, true, true);

As you can now agree, using the built-in GameMaker Health Bar is easy but what if you want a fancy health bar for your main player character? There are no clean ways to spruce up the draw_healthbar function but sometimes a hero needs special attention and you just have to go all out for that health bar. This leads us into sprite parts.

A sprite part is still a sprite

Talking about sprite parts for the first time can seem slightly confusing: is it a physical modification of the original sprite?, is it a whole new resource?, do I have to go into the image editor and start cutting pieces up? The answer luckily is no to all questions; a sprite part in this sense is the part of the sprite that you end up drawing. Let’s take a look at the function:

draw_sprite_part(sprite, subimg, left, top, width, height, x, y);

This function is not too complex on the surface but underneath the simple signature, you will find the hidden power. Stepping through the parameters really quickly we find:

  • sprite = The sprite resource you want to invoke this method on (ex. sprHealthBar)
  • subimg = The frame of the sprite that we want to invoke this method on (0 for frame 1, 2 for frame 3 etc….)
  • left = X1 or the top left point of the sprite that you want to start drawing from
  • top = Y1 or the top left point of the sprite that you want to start drawing from
  • width = How much of the sprite to render in regards to width starting from the values of left,top
  • height = How much of the sprite to render in regards to height starting from the values of left,top
  • x = the x position in the room to start drawing the sprite part starting from the top left corner of the sprite
  • y = the y position in the room to start drawing the sprite part starting from the top left corner of the sprite

One example is this custom health bar code:

var spriteWidth = sprite_get_width(sprHealthBar);
var spriteHeight = sprite_get_height(sprHealthBar);
var hpPercent = objPlayer.playerCurrentHP/objPlayer.playerMaxHP;
draw_sprite_part(sprHealthBar, 0, 0, 0, spriteWidth*hpPercent, spriteHeight, x, y+5);

Now that example is pretty straight forward but there are some function calls and things that might seem unfamiliar, so let’s jump through them.

  • sprHealthBar is, of course, my custom health bar sprite, in full width and length – unmodified
  • 0 frame because there is only 1 frame, 0 for left and 0 for top since we want to start drawing at the beginning of the sprite
  • The tricky part is next, we need to calculate how much of the health bar we should be drawing and to do this we need the total width and height of the sprite and how much HP the player currently has
    • To get the base sprite width and height you use the following functions
    • In order to get the current percent of player health left you need to take current player health and divide by max health
      • *NOTE* GameMaker has a built-in global variable called: health and it is important to remember that it is GLOBAL
        • It is not recommended that you use the variable “health” in most cases as it is easy to get the scoping wrong
          • Use the proper scope for your variables to save on potential bugs later on
      • Example:
        • If the player has a max HP of 200 and currently only has 100 then 100/200 = .50
        • If our sprite has 200px width then (200 * .50) = (200 / 2) = 100 or exactly 50% of the health bar width will be drawn
  • The X and Y comes from the object that is “containing” and drawing the sprite, now it really doesn’t contain the sprite since we draw it ourselves on the screen and the object’s sprite is set to “No Sprite” but it does act as an anchor and it makes it easier to see where in the room it will be drawn.
    • Since the sprite is drawn, you could do this in any objects draw event

I think now is a good time to see a demo of how this all works, so here is an HTML5 made in GameMaker Studio 2 live demo you can use. Hold Left Click to decrease the Hitpoints, Hold Right Click to increase the Hitpoints.

Anything can be broken into parts

In the HTML5 example above you will notice there is an image that follows almost the same kind of expand and contract as the health bars but acts slightly different. The logic behind using sprite parts works on any sprite and you can do some pretty amazing tricks once you understand how to apply it in different situations. To make it work like I did on the lovely avatar picture you only need to change a few things:

var spriteWidth = sprite_get_width(sprAvatar);
var spriteHeight = sprite_get_height(sprAvatar);
var avatarPercent = objPlayer.playerCurrentHP/objPlayer.playerMaxHP;
draw_sprite_part(sprAvatar, 0, 0, 0, spriteWidth*avatarPercent, spriteHeight*avatarPercent, x, y+5);

Just about everything is the same, except we are using the sprite resource called sprAvatar and also applying the player hp percentage (renamed to avatarPercent to denote the percent of the avatar we want to show) to the height parameter. It all works the same in the end, instead of just expanding or contracting along the width, we also do the height as well. You can make some very cool fade out or fade in type effects easily by using sprite part drawing and because we are all working on a time crunch the easier you can get an end result, the better.

Leave any questions or comments below.

Good Luck in all things,
Hikati Games
Hikati Games LLC Logo

Recent Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

UA-103187421-1