Glusoft

Make a health bar with SDL3

In this tutorial, we will make a health bar with SDL3 and SDL3_image.

A simple health bar

Introduction of making a health bar with SDL

You will need to have SDL3_image installed and working properly, if not you can follow this tutorial: Display an image

For the include you simply need SDL3, SDL3_image and iostream :

#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <iostream>

After that you can initialise the SDL3 context with the PNG format, inside a main function:

// Initialize SDL and SDL_image
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) {
    std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << "\n";
    return 1;
}

// Create a window
SDL_Window* window = SDL_CreateWindow("Health bar", 400, 300, 0);
if (!window) {
    std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << "\n";
    SDL_Quit();
    return 1;
}

// Create a renderer
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
if (!renderer) {
    std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << "\n";
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 1;
}

Loading the texture

The next step is to load the image for making the health bar and create a texture from a surface.


You can download the empty health bar image :
Health Bar

You can also download ressources for the health bar on other tutorials, here are some health bar from Brackeys


Here is the code to load to create the texture and load the image, the SDL_Surface reside in the CPU memory (ram) but to render the texture we need to have a SDL_Texture which reside in the GPU memory (vram) :

// Load the health bar image
SDL_Surface* healthbar_sur = IMG_Load("img/healthbar.png");
if (!healthbar_sur) {
    std::cerr << "Failed to load image! IMG_Error: " << SDL_GetError() << "\n";
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 1;
}

SDL_Texture* healthbar_tex = SDL_CreateTextureFromSurface(renderer, healthbar_sur);
SDL_DestroySurface(healthbar_sur); // Free surface after creating texture
if (!healthbar_tex) {
    std::cerr << "Failed to create texture! SDL_Error: " << SDL_GetError() << "\n";
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 1;
}

SDL_FRect rect{100, 100, 200, 22};

int x = 0; // x position of the mouse

We also want to store the x position of the mouse because we want to add some interaction to the health bar.
We will use the mouse position to fill the health bar accordingly.

The event loop

The event loop allow the player to quit the app and record the x position of the mouse. The mouse position is bound between 196 and 392, if we exceed the positions we reset the variable to the nearest value. The event SDL_MOUSEMOTION occurs when the player move his mouse cursor.

bool running = true;
while (running) {
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_EVENT_QUIT) {
            running = false;
        }
        if (e.type == SDL_EVENT_MOUSE_MOTION) {
            x = e.motion.x;
            
            if (x < 196)
                x = 196;
            
            if (x > 392)
                x = 392;
        }
    }

The rendering

We need to render everything the texture and the red rectangle which size depend on the x mouse position. The function SDL_SetRenderDrawColor set the default color used in the renderer. SDL_RenderClear clear the renderer with the default color. SDL_RenderFillRect creates a rectangle with the default color.

SDL_FRect rect2{102, 102, (float) std::max(0, (x - 196)), 18};
    
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);

SDL_RenderTexture(renderer, healthbar_tex, NULL, &rect);

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect2);

SDL_RenderPresent(renderer);

Cleanup

Time to do some cleanup when the main loop is exited, we delete the texture of the health bar, the renderer and the window. Then we quit SDL3.

SDL_DestroyTexture(healthbar_tex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();

Full source code to make a health bar with SDL3

You can download the full project here: