Designing a Health System in Game Maker

In the next couple of  tutorials,  I thought I would focus on something very practical, reusable, and something most people struggle with when they first start developing in Game Maker: Designing a complete health system. We will cover the creation of several different custom health bars and what you need to think about when applying the health system.

To start, we are going to recreate the built-in health bar function where we will accept all the same arguments and return the same results. This will allow us to understand all the elements and constraints a basic health system requires and then we will use that information to expand into other systems. Let’s go!

Designing a Health System

The Construction of a Function

I can’t tell you how many times I have heard students tell me that they have never built a function before and I am sure some of you will say that as well. However, when I ask whether they have ever created a script in Game Maker, the usually answer in the affirmative. That’s when I point out that, in Game Maker, a script IS a function. It is probably very simple and likely should be broken into several smaller chunks, but a function nonetheless. Therefore, you are totally ready to start building larger functions.

So what is a function and what are the elements that make one? A function is simply a collection of tasks or actions that you would want to reuse. In Game Maker, the name you give a script is how you call  the function, you can declare up to 16 arguments in the script which will be a part of the body of code you want to execute. (Note: the Execute Script drag and drop action only accepts up to 5 arguments).

You might wonder why you would want to build a function. Well, to start, it is much easier to write one line of code that will end up doing multiple lines of code, than rewriting those chunks of code over and over. It also makes it easier to read and debug. Trust me, when it comes to debugging your code, you want to make your code as easy to read as possible.

The Arguments

Before we try and create our own health system, we first should understand what the arguments of the original, default health bar are used for. The draw_healthbar() function requires 11 different arguments. The first four relate to the X/Y coordinates, with the first two being the position in space and the second two representing the width and height. The fifth argument is the amount of health and is a percentage between 0 -100 (this is important for us to know). We are then asked for 3 colour values; one for the background color, the minimum (or in danger) colour, and the maximum (or full health) colour. The ninth argument determines the direct the health bar will move and there are four options: 0 will drain to the right, 1 drains to the left, 2 drains upwards, ,and 3 drains downwards. The final two arguments are boolean values for whether to display an element or not, in this case the elements are the background and the outline.

There is also some other factors that we need to know about which may not be be so obvious. The outline element in the default health bar is ALWAYS black and you can NEVER have more than 100% health visible.  It’s these little details that often cause plenty of issues later on.

So let’s get this into our script, which I am going to call scr_Draw_Healthbar.

x1 = argument0;
y1 = argument1;
x2 = argument2;
y2 = argument3;
amount = argument4 / 100;
bgCol = argument5;
minCol = argument6;
maxCol = argument7;
dirBar = argument8;
showBack = argument9;
showBord = argument10;

As you can see here, we are capturing all of the arguments in easy to read variables.  Hopefully you noticed that argument4 is being divided by 100. We needed to do this so that we guarantee that we are getting a percentage.

Three Layers of a Health Bar

The health bar we are creating has three distinct layers: Background, Health, and Outline. The function allows us to draw all three, but the Background and Outline are both optional and can be turned off. The reason I am bringing this up is that it will dictate the order we need to write the code. We will be drawing three rectangles, one on top of the other, so we don’t want to draw our background in front of everything, do we?

Drawing the background

Since the background is optional, we will need to see if the user sets the showBack argument to true or not. If they do, then we will draw the rectangle to whatever color the bgCol was set to, otherwise we will skip this all together.  That’s it!

//Draw Background
if showBack == true
{
    draw_set_color(bgCol);
    draw_rectangle(x1, y1, x2, y2, false);
}

Health

The health bar itself is a bit more complex. First we need to see if we have more than 100% health. If we do, then we draw the health at its full size and maximum colour. If we have less than (or equal) full health, we can draw the rectangle with a percentage based colour. We do this with the merge_color function, which takes two colors and blends them between a value of 0-1.

Then we get into the complicated part. The default health bar allows us to have the health drain in four different directions: Right, Left, Up, Down. Here we use some if statements to see what has been selected and draw the according rectangle. As you can see, it takes a bit of math to get it to draw properly. The basic premise of each equation is where does the upper left corner go and how big is the rectangle. You should notice that we do not always use the x1 and y1 as the upper left corner, even though the user thinks that we are.

// Draw Health
if amount > 1
{
    draw_set_color(maxCol);
    draw_rectangle(x1, y1, x2, y2, false);
}
else if amount  0
{
    draw_set_color(merge_color(minCol,maxCol,amount));

    if (dirBar == 0)
    {
        draw_rectangle(x1, y1, x1 + ((x2-x1)*amount), y2, false);
    }
    else if (dirBar == 1)
    {
        draw_rectangle(x2, y1, x2 - ((x2-x1)*amount), y2, false);
    }
    else if (dirBar == 2)
    {
        draw_rectangle(x1, y1, x2, y1 + ((y2-y1)*amount), false);
    }
    else if (dirBar == 3)
    {
        draw_rectangle(x1, y2, x2, y2 - ((y2-y1)*amount), false);
    }
}

Outlined Frame

Finally, we add the optional outline border. In this case, it is the same as the background layer, except we force the colour to be black in all cases.

//Draw Box outline
if showBord == true
{
    draw_set_color(c_black);
    draw_rectangle(x1, y1, x2, y2, true);
}

Implementation

Great! Now we have a fully working health bar, but we don’t have the system to implement it into. We will keep this simple and just have an object that displays the health bar and we will lose health when we press the space bar. I find that it is best to test it in this manner to ensure it works.

We need three scripts for this to work. We need to initialize the variable ( myHealth = 100; )  in the Create Event, decrease health ( myHealth -= 10; ) in a Key Press Event, and we will call our function ( scr_DrawHealthBar(x,y,x+100,y+30,myHealth,c_black,c_red,c_green,1,true,true); ) in the Draw Event. Once you have done that you can run the game and you should see a functioning health bar. Try throwing another object in there with all the same settings, except use the default health bar function. They should be identical.

Download the completed file

Next time, we will look at modifying this code to create some different types of health bars and systems.

12 thoughts on “Designing a Health System in Game Maker

  1. Great Stuff! I just wish I could just grasp this code language like second nature.

  2. Hey Jeffry, Is there anything specific that you are having trouble with or that I can explain better for you?

  3. This won’t conflict with the player character’s animation cycle but actually function as a separate counter, yes?

  4. The answer depends on how you plan on implementing it. If you have this used in the Draw Event of a character, you would still need to to ensure the animated sprites are drawn as well. It is a separate counter, so every instance in your game can have their own health bar. I hope that answers your question 🙂

  5. Looks pretty cool. But this is pretty basic stuff. I’m looking for a way to create unique health values for individual instances as they enter the room (this is for targets in a tower defense-style game). Do you have any idea how I would do that?

  6. In the follow-up tutorial it covers an RPG style health bar which allows for differing health values as you would find in a tower defence game. The main trick to this is instead of dividing the health by 100, you divide it by a maxHealth value. Health is always based on a percentage, so 50% of 100 is the same as 50% of 23564 😉

    Did that help?

  7. ((health variable / maximum health variable) *100) can be entered for argument 5. It will ensure that “max health” counts as whatever the maximum health value is. Useful when it isn’t 100, like having a character with 70 or 200 health; the health bar will read as full when their health variable equals the maximum health variable.

  8. Very good point. When I wrote this I was attempting to emulate the built-in draw_healthbar functionality, which doesn’t have that option, but it would be incredibly useful.

Leave a Reply