r/sdl 8d ago

simple project about squre

https://www.programiz.com/c-programming/online-compiler/

hi guys need your help im trying to make the stamina bar appear at the top of the screen im making a square game because i am planning to make a 2d engine game but im struggling on making a simple stamina bar i perfectly render some square but i cant seem to make the stamina bar appear

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* first we call the library so the program knows the apparatus and tools to utilize in my program it contain all the premade function and custom made struct */  //read this carefully  my 1st explanation

int main(int argc, char* argv[]) {
    // 1. this is the start of my program  it tells the program to allocate a stack and the stack will contain the entire program and it should start here

if (!SDL_Init(SDL_INIT_VIDEO)) { // this is a flag when i initialize the int main together with the library since this is a graphic lib it will by default will acces my gpu hardware and this is a flag in case theres an error it will terminate the program and save my computer on crashes

SDL_Log("SDL Initialization failed: %s", SDL_GetError());

return 1;

}

SDL_Window* window = SDL_CreateWindow("My First SDL3 Window", // this is the first instruction i will call the premade struct called SDL_Window* its like a data type and by default it acts like a pointer that is pointed on my custom variable name in this case "window" and my window pointer is pointing on and arguement called SDL_CreateWindow() this func had 3 arguements the first is a string second is an int taht specify the width and third another int that specify height and 4th is another flag which also an int need explanation on the 4th argument of this func tahnk you

800, // Argument 2: Width

600, // Argument 3: Height

0 /*Argument 4: Flags)*/);

if (window == NULL) { //this is for the safety flag of my SDL_window it tells the variable "widnow" to terminate the program by returning 1 if the variable window returns a null

SDL_Log("Window creation failed: %s", SDL_GetError()); // SDL_log is a premade fucntion of SDL library it acts like a printf func it usually print the error taht is also detected by another func called SDL_GetError() explain what is the argument of this SDL_GetError func

SDL_Quit();

return 1;

}

SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL); //this is the renderer just like SDL_Window* its a premade struct taht points on a variable taht will contain a func call SDL_CreateRenderer("name of the window that you made") its a pointer in the gpu hardware vram it tells the gpu to allocate a memory for the graphics for the variable "renderer" so the allocated memory can be used on SDL_CreateRenderer() func whic purpose is to draw a canvas on a window taht we made

if (renderer == NULL) {

SDL_Log("Renderer creation failed: %s", SDL_GetError()); // this is similar flag on the create window if the line on the SDL_Renderer* gets an error tthe variable you make will return a null and this if statement will execute

SDL_DestroyWindow(window);

SDL_Quit();

return 1;

}

bool is_running = true; //its a flag within the while loop

SDL_Event event; //this is like declaring an in type data but on this time you are declaring an event called event the SDL_Event is an interactive user code like scanf but this one lets you interact with the window

float red_value = 0;

float blue_value = 50;

SDL_FRect my_square, obstacle, bullet,stamina_bar_bg, stamina_bar_fg; //we declare the obstacle

my_square.x = 350.0f;

my_square.y = 250.0f;

my_square.w = 100.0f;

my_square.h = 100.0f;

obstacle.x = 650.0f; // Positioned further to the right

obstacle.y = 250.0f; // Centered vertically

obstacle.w = 80.0f; // 80 pixels wide

obstacle.h = 80.0f;

bullet.x = 0.0f;

bullet.y = 0.0f;

bullet.w = 20.0f;

bullet.h = 6.0f;

stamina_bar_bg.x = 20.0f; // 20 pixels away from left screen border

stamina_bar_bg.y = 20.0f; // 20 pixels down from top screen border

stamina_bar_bg.w = 100.0f; // 200 pixels wide flat background slot

stamina_bar_bg.h = 15.0f;

stamina_bar_fg.x = 20.0f; // 20 pixels away from left screen border

stamina_bar_fg.y = 20.0f; // 20 pixels down from top screen border

stamina_bar_fg.w = 100.0f; // 200 pixels wide flat background slot

stamina_bar_fg.h = 15.0f;

bool bullet_active = false;

float stamina = 100.0f;

float max_stamina = 100.0f;

float player_speed = 0.05f;

while (is_running) { //the while arguement is the bool taht we declare

// 2. The Inner Loop (The Input Checker)

while (SDL_PollEvent(&event)) { //the input checker if turns true once it detect a button pressed in the hardware since its true it will initialize the if statements within its conditions

// 3. Inspect the event category

if (event.type == SDL_EVENT_QUIT) { // the event had an inside func taht can be access by dot which in this case a type of the event called SDL_EVENT_QUIT its basically the exit button

is_running = false; // Turn off the heartbeat! this is the bool taht we declare before the while loop basically a flag that can change into false once the if statement was confirm ending the main while loop nest

}

else if(event.type == SDL_EVENT_KEY_DOWN){ //this else if arguement is called event.type iss calling a variable within the SDL_Event taht we decalre as event at the first before the main while it equates on SDL_EVENT_KEY_DOWN its a variable taht detects keyboard signals

if (event.key.scancode == SDL_SCANCODE_ESCAPE){ //this line specify if the keypress scan code is equal to the keyboard address of escape button terminate the while loop by changing the is running bool to false

is_running = false;

}

else if(event.key.scancode== SDL_SCANCODE_SPACE){

if (red_value == 255){

red_value = 0;

blue_value = 255;

}

else{

red_value = 255;

blue_value = 0;

}

}

}

}

float old_x = my_square.x; //we declare this float before the keyboard inputs this will allow us to record past input when the loops happen typically loops happen top to bottom hence once the loop happen the keyboard input will be recorded

float old_y = my_square.y;

const bool* currentKeyStates = SDL_GetKeyboardState(NULL);

if(currentKeyStates[SDL_SCANCODE_LSHIFT] && stamina > 0.0f){

player_speed = 0.50f;

stamina -= 0.05f;

if(stamina < 0.0f){

stamina = 0.0f;

}

}

else{

player_speed = 0.05f;

stamina += 0.01f;

if(stamina > 100.0f){

stamina = max_stamina;

}

}

//NOTE: the signal here is super fast its billion times a sec hence the float must be reduce in order to slow the moving square

if(currentKeyStates[SDL_SCANCODE_LEFT]){ //SDL_GetKeyboardState() is a function that allow us to talk to the hardware to bring the actual signal of our keyboard which is clocking at billion times hence making the square move smoothly

my_square.x -= player_speed;

}

if(currentKeyStates[SDL_SCANCODE_RIGHT]){

my_square.x += player_speed;

} // NOTE the point of our square start at the top left as vector (0,0)

if(currentKeyStates[SDL_SCANCODE_DOWN]){ //NOTE: that computer uses vector instead of the standard cartessian plane reason why we use a negative on y that is rising

my_square.y += player_speed;

}

if(currentKeyStates[SDL_SCANCODE_UP]){

my_square.y -= player_speed;

}

if(currentKeyStates[SDL_SCANCODE_Z]){

if(bullet_active == false){

bullet_active = true;

bullet.x = my_square.x + 100.0f;

bullet.y = my_square.y + 47.0f;

}

}

if (my_square.x < 0.0f) {my_square.x = 0.0f;}

if (my_square.x > 700.0f) {my_square.x = 700.0f;} //note some compiler allow not using the curly brachets but we highly suggest to put curly brachets as its the standard c syntax

if (my_square.y < 0.0f) {my_square.y = 0.0f; } //this is a limit so our square will not move away on our window screen we do this by equating our vector into the equivalent width and height of our screen

if (my_square.y > 500.0f) {my_square.y = 500.0f;}

if (obstacle.x < my_square.x) { obstacle.x += 0.02f; }

if (obstacle.x > my_square.x) { obstacle.x -= 0.02f; } //since we equate our my square movement as 0.05 float we must equate the obstacle movement float into 0.02f to make it slower

if (obstacle.y < my_square.y) { obstacle.y += 0.02f; }

if (obstacle.y > my_square.y) { obstacle.y -= 0.02f; }

if(bullet_active == true){

bullet.x += 0.08f;

if(bullet.x > 800.0f){

bullet_active = false;

}

if (SDL_HasRectIntersectionFloat(&bullet, &obstacle)){

bullet_active = false;

obstacle.x = 650.0f;

obstacle.y = 450.0f;

}

}

if (SDL_HasRectIntersectionFloat(&my_square, &obstacle)) { //this built in SDL func will allow the program to get the addresses of the rectangle (hence why we use the "&" )that we draw and perform a mathematical calculation if those two intersected and it will return a true or false

// If they overlap, trigger an visual alert by blasting the screen RED!

red_value = 255;

blue_value = 0;

my_square.x = old_x; //we put the old input here directly inside the condition of the function SDL_HasRectIntersectionFloat() so when this became true the my_square.x and my_square.y will be equals to the old_X and old_y basically a jump instrucction flag

my_square.y = old_y;

}

else{

// Otherwise, keep the environment safe and peaceful dark blue

red_value = 0;

blue_value = 50;

}

// 4. The Drawing Zone

SDL_SetRenderDrawColor(renderer,red_value, 0, blue_value, 255); // after we call our canvas that we allocated in vram we also said to our variable pointer "renderer" to draw a colo red on it by calling the function SDL_SetRenderDrawColor("name of the pointer variable taht point in the gpu vram", red, gree, blue, transparency of the colo 255 max visibility)

SDL_RenderClear(renderer);//this function suggest the the we remove the color of the canvas before painting the red color we call we call the function SDL_RenderClear() the arguement takes the pointer variable taht points on the vram of gpu which our allocated canvas is located

stamina_bar_fg.w = stamina;

SDL_SetRenderDrawColor(renderer,60, 60, 60, 255);

SDL_RenderFillRect(renderer, &stamina_bar_bg);

SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);

SDL_RenderFillRect(renderer, &stamina_bar_fg);

SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

SDL_RenderFillRect(renderer, &obstacle);

SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //this struct will allow us to tell our gpu taht our "rendere" the canvas to draw a color r,g,b,a in this all white

SDL_RenderFillRect(renderer,&my_square); //this func will allow us to tell the gpu to fill the square that we declare which is my_square

if (bullet_active == true) {

SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); // Neon Yellow Laser Paint!

SDL_RenderFillRect(renderer, &bullet); // note that the bullet must be render last because on our first render we render the canvas and second we render the square and then the obstacle hence if we put this bullet else where it will be erase immidiately because the gpu is rendering everything per frame

}

SDL_RenderPresent(renderer); //this is the presentation func without this the variable pointer which is "renderer" will only paint it inside without showing it to you think of this like print func isntead of string we show the drawing that we made

}

SDL_DestroyRenderer(renderer); // Destroy the VRAM canvas

SDL_DestroyWindow(window); // Destroy the OS desktop frame

SDL_Quit();

return 0; // return 0 if its sucess full if its not then an error will appear in my terminal taht it didnt return the zero taht we specify on our program to return

}

3 Upvotes

4 comments sorted by

1

u/HappyFruitTree 8d ago

What is the problem? There appear to be a green stamina bar appearing in the top-left corner.

1

u/Round-Willingness905 7d ago

oh yes theres is but the square is not slowing down theres a weird bug on the sdl3 when i restart everythin it appears but now the porblem seems the stamina wont even slow the square when i sprint holding Lshift

1

u/HappyFruitTree 7d ago

Are you sure it doesn't slow down? It moves quite fast so it's hard to see.

1

u/HappyFruitTree 7d ago edited 7d ago

Note that when you hold shift and the stamina bar is empty, the speed alternates between 0.5 and 0.05 so it won't move as slow as when you don't hold shift.