Warning: Undefined array key "HTTP_ACCEPT_LANGUAGE" in /var/www/vhosts/bilgigunlugum.net/httpdocs/index.php on line 43
SDL Game Programming

SDL3 Oyun Programlama sayfalarımız yayında...

Ana sayfa > Oyun programlama > SDL3 programming > Timer

Timer

In this section, we will examine a program that starts and stops a timer via a menu, and displays the elapsed time in hours, minutes, seconds, and milliseconds in the window title.

When the program runs, in addition to the basic operations, the following operations occur:

  1. At the beginning of the program, the following global variable is first defined:
    • bool timer_on: Timer activation variable
    • unsigned int time_start: Timer start time variable
    • unsigned int time_current: Active time variable
  2. The init_vars() function initializes global variables.
  3. load_media() function In, the menu image is loaded to the texture variable with the IMG_LoadTexture() function.
  4. In the process_event() function, when the mouse movement and click are performed,
    • The x and y coordinate values ​​of the mouse are assigned to the mouse_pos variable.
    • With the SDL_PointInRect() function, the clicked menu option is determined in the menu texture and the timer is started or stopped according to this option.
  5. In the draw_screen() function,
    • With the SDL_RenderTexture() function, it copies the menu texture to the main window.
    • With the SDL_GetTicks() function, it takes the active time and assigns it to the time_current variable.
    • The difference between the time_current and the time_start variable, which contains the timer start time, is taken and assigned to the milliseconds variable.
    • The time counter is set using milliseconds variable for hour, minute, second and millisecond values ​​are obtained.
    • Timer values ​​are shown in the main window title.

main.c file content will be as follows:


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

// Window width and height
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480

// Global variables
int is_running = false;        // Variable that controls the execution of the main loop of the program
SDL_Window *window = NULL;     // Main window variable
SDL_Texture *texture = NULL;   // Texture variable
SDL_Renderer *renderer = NULL; // Renderer variable

bool timer_on;                 // Timer activation variable
unsigned int time_start;       // Timer start time variable
unsigned int time_current;     // Current time variable

// Function prototypes
int init_window(void);     // Create window and renderer
void init_vars(void);      // Initialize values
void load_media(void);     // Load media
void process_event(void);  // Process events
void update_screen();      // Update values
void draw_screen(void);    // Draw screen
void destroy_window(void); // Destroy window

int main(int argc, char* argv[])
{
    // Create window and renderer
    is_running = init_window();

    // Initialize variables
    init_vars();

    // Load image
    load_media();

    // Main loop
    while (is_running) {
       process_event(); // Processing SDL events (Here keyboard inputs)
       update_screen(); // Updating variables
       draw_screen();   // Drawing objects on the window (Rendering)
    }

    // Destroy renderer and SDL window
    destroy_window();

    return 0;
}

// Create window and renderer
int init_window(void)
{
    // Initialize the SDL library.
    if(SDL_Init(SDL_INIT_VIDEO) == false) {
       SDL_Log("SDL init error: %s\n", SDL_GetError());
       return false;
    }

    // Create a window and a 2D rendering context for the window.
    if(!SDL_CreateWindowAndRenderer("SDL3 window", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
       return false;
    }
	
    return true;
}

// Initialization function that runs only once at the beginning of the program
void init_vars(void)
{
    timer_on = false;
    time_start = 0;
    time_current = 0;
}

// Load image
void load_media(void)
{
    // Load image to texture
	texture = IMG_LoadTexture(renderer, "menu_timer.png");

	if(texture == NULL) {
       SDL_Log("IMG_LoadTexture error: %s\n", SDL_GetError());
	}
}

// Function to control SDL events and process keyboard inputs
void process_event(void)
{
    SDL_Event event;

    // Creating a loop to process user inputs
    while (SDL_PollEvent(&event)) {
       switch (event.type) {
          case SDL_EVENT_MOUSE_BUTTON_DOWN:
          case SDL_EVENT_MOUSE_MOTION:
          {
               SDL_Point mouse_pos = { event.motion.x, event.motion.y };
               SDL_Rect rect_menu = { 20, 20, 120, 30 };
               bool mouse_in = 0;
               bool lb_state = event.type==SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button==SDL_BUTTON_LEFT;

               // Checking whether the mouse is inside the button
               if(SDL_PointInRect(&mouse_pos, &rect_menu)) {
                  mouse_in = true;
                  if(lb_state) {
                     timer_on = true;
                     time_start = SDL_GetTicks();
                  }
               }
               rect_menu.y = 60;
               if(SDL_PointInRect(&mouse_pos, &rect_menu)) {
                  mouse_in = true;
                  if(lb_state) timer_on = false;
               }

               if(mouse_in) SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER));
               else SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT));
          }
          break;

          case SDL_EVENT_QUIT: // Logout action by the user (x button at the top right of the window)
               is_running = false; // Terminates the execution of the program main loop.
               break;

          case SDL_EVENT_KEY_DOWN: // Key pressed.
               if(event.key.key==SDLK_ESCAPE) {
                 is_running = false;
               }
               break;
       }
    }
}

// Updates objects in the main window
void update_screen(void)
{

}

// Render function used to draw game objects in the main window
void draw_screen(void)
{
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Set the color used for drawing operations.
    SDL_RenderClear(renderer); // Clear the current rendering target with the drawing color.

    // Copy menu texture to main window
    SDL_FRect frect_dst = { 20, 20, 120, 70 };
	SDL_RenderTexture(renderer, texture, NULL, &frect_dst);

    // Loading all objects drawn one by one to the back buffer to the front buffer at once and loading them onto the screen
    // This process prevents each drawn object from being displayed on the screen one by one.
    SDL_RenderPresent(renderer); // Update on screen all operations performed since the previous call

    char cdizi[100];
    char time_format[20];
    time_current = SDL_GetTicks();

    if(timer_on) {
       int milliseconds = time_current-time_start;
       int seconds = milliseconds / 1000;
       milliseconds %= 1000;
       int minutes = seconds / 60;
       seconds %= 60;
       int hours = minutes / 60;
       minutes %= 60;

       sprintf(time_format, "%.2d:%.2d:%.2d:%.4d", hours, minutes, seconds, milliseconds);
    }
    else {
       strcpy(time_format, "00:00:00:0000");
    }

    sprintf(cdizi, "SDL3 window - Timer: %s", time_format);
    SDL_SetWindowTitle(window, cdizi);
}

// Destroy Renderer and SDL window, exit from SDL3
void destroy_window(void)
{
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}