Timer dan SDL_GetTick

Kita bisa menggunakan SDL_GetTick untuk mendapatkan "berapa lama waktu yang sudah berlalu" sejak program dijalankan. Dengan SDL_GetTick kita bisa membuat perhitungan framerate untuk animasi menggunakan dalam loop dari program yang menggunakan SDL. Contoh kode program berikut ini menampilkan gambar yang berubah-ubah berdasarkan gambar di spritesheet tiap 70 milidetik.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define jpotongan 3
int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;
    int pos=0;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0 && IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG)){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            SDL_Renderer *trender = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

            SDL_Surface *tmp=IMG_Load("animasi.png");

            if(tmp){
                unsigned int berikutnya=SDL_GetTicks()+70;
                int panjang=tmp->w/jpotongan;
                int tinggi=tmp->h;

                SDL_SetColorKey(tmp, SDL_TRUE, SDL_MapRGB(tmp->format, 0x00, 0xFF, 0xFF));
                SDL_Texture *bmp=SDL_CreateTextureFromSurface(trender, tmp);
                SDL_FreeSurface(tmp);

                if(bmp){
                    SDL_Rect rct;
                    while(evt.type!=SDL_QUIT){
                        while(SDL_PollEvent(&evt)){
                        }

                        SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
                        SDL_RenderClear(trender);

                        rct.x=0;
                        rct.y=0;
                        rct.w=panjang;
                        rct.h=tinggi;

                        SDL_RenderSetViewport(trender, &rct);

                        rct.x=panjang*pos;
                        SDL_RenderCopy(trender, bmp, &rct, NULL);
                        SDL_RenderPresent(trender);
                        if(SDL_GetTicks()>=berikutnya){
                            berikutnya=SDL_GetTicks()+70;
                            pos++;
                            if(pos>=jpotongan){
                                pos=0;
                            }
                        }
                    }
                }
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}

Timer dengan Callback
Untuk mengatur timer, selain menggunakan SDL_GetTicks, kita bisa menggunakan SDL_AddTimer dan callback. Untuk menggunakan function SDL_AddTimer, kalian perlu menggunakan konstanta SDL_INIT_TIMER pada function SDL_Init.

Callback adalah function yang dipicu oleh thread atau event tertentu. Callback dari SDL_AddTimer memiliki dua parameter, yang pertama adalah intervalnya, dan yang kedua adalah pointer yang bisa kita manfaatkan untuk "memberikan" alamat variabel tertentu dari function SDL_AddTimer kepada callback. Jika kita ingin menghentikan timer, kita bisa menggunakan SDL_RemoveTimer.
  • SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void* param)
  • SDL_RemoveTimer(SDL_TimerID id)
Id dari SDL_RemoveTimer didapatkan dari variabel bertipe SDL_TimerID. Variabel tersebut harus menyimpan kembalian dari SDL_AddTimer yang akan dihentikan pemanggilan callbacknya. Daripada ribet dengan teori yang panjang, mendingan langsung lihat, coba dan analisa sendiri contoh kode programnya.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define jpotongan 3

int pos=0;
int panjang, tinggi;
SDL_Renderer *trender;
SDL_Texture *bmp;
SDL_Rect rct;

Uint32 cback(Uint32 interval, void *param){
    SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
    SDL_RenderClear(trender);

    rct.x=0;
    rct.y=0;
    rct.w=panjang;
    rct.h=tinggi;

    SDL_RenderSetViewport(trender, &rct);

    rct.x=panjang*pos;
    SDL_RenderCopy(trender, bmp, &rct, NULL);
    SDL_RenderPresent(trender);
    pos++;
    if(pos>=jpotongan){
        pos=0;
    }
    return interval;
}

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;

    if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 && IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG)){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            trender= SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Surface *tmp=IMG_Load("animasi.png");

            if(tmp){
                panjang=tmp->w/jpotongan;
                tinggi=tmp->h;

                SDL_SetColorKey(tmp, SDL_TRUE, SDL_MapRGB(tmp->format, 0x00, 0xFF, 0xFF));
                bmp=SDL_CreateTextureFromSurface(trender, tmp);
                SDL_FreeSurface(tmp);

                if(bmp){
                    SDL_AddTimer(100, cback, 0);
                    while(evt.type!=SDL_QUIT){
                        while(SDL_PollEvent(&evt)){
                        }
                    }
                }
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}
Hasil kode program di atas hampir sama dengan kode program sebelumnya kecuali waktunya. Saat menggunakan SDL_AddTimer, callback akan dipanggil berulang-ulang dengan selisih waktu yang sama. Pemanggilan callback akan dihentikan saat function SDL_RemoveTimer digunakan untuk menghentikannya. Dibandingkan dengan menggunakan SDL_GetTick, ini mungkin akan terlihat lebih mudah. Walaupun begitu, kedua cara ini punya kelebihannya masing-masing.