In this tutorial, we will make a health bar with SDL and SDL2_image.
You will need to have SDL2_image installed and working properly, if not you can follow this tutorial: Display an image with SDL_image
For the include you simply need SDL2, SDL2_image and iostream :
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <iostream>
After that you can initialise the SDL2 context with the PNG format, inside a main function:
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow( "Health bar", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN );
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
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) :
SDL_Surface* healthbar_sur = IMG_Load("img/healthbar.png");
SDL_Texture* healthbar_tex = SDL_CreateTextureFromSurface(renderer, healthbar_sur);
SDL_Rect 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.
while (true) {
SDL_Event e;
if (SDL_WaitEvent(&e)) {
if (e.type == SDL_QUIT) {
break;
}
if(e.type == SDL_MOUSEMOTION) {
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_Rect rect2{102, 102, (x-196), 18};
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(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 SDL2_image and SDL.
SDL_DestroyTexture(healthbar_tex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <iostream>
int main( int argc, char* args[] )
{
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
IMG_Init(IMG_INIT_PNG);
SDL_Window* window = SDL_CreateWindow( "Health bar", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN );
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Surface* healthbar_sur = IMG_Load("img/healthbar.png");
SDL_Texture* healthbar_tex = SDL_CreateTextureFromSurface(renderer, healthbar_sur);
SDL_Rect rect{100, 100, 200, 22};
int x = 0; // x position of the mouse
while (true) {
SDL_Event e;
if (SDL_WaitEvent(&e)) {
if (e.type == SDL_QUIT) {
break;
}
if(e.type == SDL_MOUSEMOTION) {
x = e.motion.x;
if(x < 196)
x = 196;
if(x > 392)
x = 392;
}
}
SDL_Rect rect2{102, 102, (x-196), 18};
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, healthbar_tex, NULL, &rect);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect2);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(healthbar_tex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 0;
}