Scrolling Background

Pada kebanyakan game, kita menemukan bahwa yang bergerak sebenarnya bukanlah karakter game-nya, tapi latar belakangnya. Karena background-nya bergerak, kita melihat karakter game seolah-olah bergerak berlawanan arah dengan gerakan background. Latar belakang yang bergerak sambung menyambung dan terus menerus ke satu arah disebut dengan scrolling background.

Dalam pembuatan game, kita bisa menggunakan satu gambar atau lebih yang digerakkan ke satu arah. Gambar yang kecil bisa ditampilkan berulang-ulang sebagai gambar yang saling sambung-menyambung sehingga menjadi satu bagian dari latar belakang.

Karakter utama cukup di letakkan di kiri bawah atau di posisi manapun sesuai kehendak kita. Untuk membuat karakter utama seperti bergerak, selain dengan menggerakkan background-nya, kita juga perlu memberikan gerakan pada kakinya saat tombol ditekan. Sebelum membuat yang karakternya bisa digerakkan, sekarang kita akan membuat scrolling background tanpa karakter di atasnya.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define playar 640
#define tlayar 480

SDL_Renderer *trender=NULL;

SDL_Texture *muat_gambar(SDL_Rect *dgambar, const char *s){
SDL_Texture *teksture=NULL;
    SDL_Surface *tmp=IMG_Load(s);
    if(tmp){
        dgambar->w=tmp->w;
        dgambar->h=tmp->h;

        SDL_SetColorKey(tmp, SDL_TRUE, SDL_MapRGB(tmp->format, 0x00, 0xFF, 0xFF));
        teksture=SDL_CreateTextureFromSurface(trender, tmp);
        if(teksture)printf("gagal membuat teksture %s", s);
        else SDL_FreeSurface(tmp);
    }else printf("gagal memuat");
    return teksture;
}

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;
    int xlatar=0;
    int batas=0;
    int x=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, playar, tlayar, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            trender = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Texture *bmp=NULL;
            SDL_Texture *latar=NULL;
            SDL_Rect dgambar;
            unsigned int berikutnya, platar, tlatar;

            latar=muat_gambar(&dgambar, "background.png");
            platar=dgambar.w;
            tlatar=dgambar.h;
            batas=platar;
  
            berikutnya=SDL_GetTicks()+70;
            if(latar!=NULL){
                SDL_Rect rct;
      
                while(evt.type!=SDL_QUIT){
                    while(SDL_PollEvent(&evt)){
                    }

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

                    rct.x=xlatar;
                    rct.y=0;
                    rct.w=platar;
                    rct.h=tlayar;
                    SDL_RenderSetViewport(trender, &rct);
      
                    x=0;
                    while(rct.x < 2*playar){
                        SDL_RenderSetViewport(trender, &rct);
                        SDL_RenderCopy(trender, latar, NULL, NULL);
                        rct.x=x-xlatar;
                        x+=platar;
                    }
      
                    SDL_RenderPresent(trender);
      
                    if(SDL_GetTicks()>=berikutnya){
                        berikutnya=SDL_GetTicks()+70;
                        xlatar+=4;
                        if(xlatar>=batas){
                            xlatar=0;
                        }
                    }
                }
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}
Gambar yang digunakan untuk background sebaiknya tingginya sesuai dengan tinggi permukaan window yang akan digambar. Dalam kode program di atas, tingginya adalah 480 pixel sesuai nilai dari parameter SDL_CreateWindow.

Menambahkan Karakter
Selanjutnya, kita akan menambahkan karakter yang diam di tempat. Saya tidak akan memberikan contoh cara menggerakkannya di sini. Kalau kalian ingin melihat cara menggerakkannya, tunggu tulisan saya berikutnya.
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define jpotongan 3
#define playar 640
#define tlayar 480

SDL_Renderer *trender=NULL;

SDL_Texture *muat_gambar(SDL_Rect *dgambar, const char *s){
SDL_Texture *teksture=NULL;
    SDL_Surface *tmp=IMG_Load(s);
    if(tmp){
        dgambar->w=tmp->w;
        dgambar->h=tmp->h;

        SDL_SetColorKey(tmp, SDL_TRUE, SDL_MapRGB(tmp->format, 0x00, 0xFF, 0xFF));
        teksture=SDL_CreateTextureFromSurface(trender, tmp);
    if(teksture)printf("gagal membuat teksture %s", s);
        else SDL_FreeSurface(tmp);
    }else printf("gagal memuat");
    return teksture;
}

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;
    int xlatar=0;
    int batas=0;
    int pos=0;
    int x=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, playar, tlayar, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            trender = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Texture *bmp=NULL;
            SDL_Texture *latar=NULL;
            SDL_Rect dgambar;
            unsigned int berikutnya, pkarakter, tkarakter, platar, tlatar;

            bmp=muat_gambar(&dgambar, "animasi.png");
            pkarakter=dgambar.w/jpotongan;
            tkarakter=dgambar.h;

            latar=muat_gambar(&dgambar, "background.png");
            platar=dgambar.w;
            tlatar=dgambar.h;
            batas=platar;
        
            berikutnya=SDL_GetTicks()+70;
            if(bmp!=NULL && latar!=NULL){
                SDL_Rect rct;
            
                while(evt.type!=SDL_QUIT){
                    while(SDL_PollEvent(&evt)){
                    }

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

                    rct.x=xlatar;
                    rct.y=0;
                    rct.w=platar;
                    rct.h=tlayar;
                    SDL_RenderSetViewport(trender, &rct);
            
                    x=0;
                    while(rct.x < 2*playar){
                        SDL_RenderSetViewport(trender, &rct);
                        SDL_RenderCopy(trender, latar, NULL, NULL);
                        rct.x=x-xlatar;
                        x+=platar;
                    }
            
                    rct.x=0;
                    rct.y=tlayar-tkarakter;
                    rct.w=pkarakter;
                    rct.h=tkarakter;

                    SDL_RenderSetViewport(trender, &rct);

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

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}
Dalam kode program di atas, saya menggunakan SDL_RenderCopy sebanyak dua kali. SDL_RenderCopy yang pertama digunakan untuk menggambar background-nya dengan perulangan for. Kemudian, SDL_RenderCopy digunakan untuk menggambar karakternya di atas background. Selain itu, saya juga menggunakan viewport untuk mengatur batas bagian yang bisa digambar di permukaan window.