In this tutorial, we will make a health bar with SDL3 and SDL3_image.
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;
}
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 :
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 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;
}
}
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);
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();
You can download the full project here: