Hello SDL2
Noțiuni Introductive


Ce trebuie să știi pentru a învață SDL2?
l POO
l C++

Ce este SDL2?
SDL2 = API (Application Programmera€™s Interface)
* API - interfață destinată programării aplicațiilor

Ce face SDL2?
pentru a utiliza lucruri că: grafica, sunet, tastatură, joystick-uri etc.
aveți nevoie de un API

aici intervine SDL2, ia toate aceste caracteristici și le transformă astfel încât să poată interacționa cu C++

pentru a-l folosi trebuie să îl INSTALAȚI

SDL2 conține 3 tipuri de fișiere:
l fișierele header (Library.h)
l fișierele library (Library.lib)
l fiesierele binary (Library.dll)

EXPLICAȚII PAS CU PAS PENTRU A INSTALĂ SDL2:

1. Trebuie să descarci fișierele conținute de SDL2. Le vei găsi pe toate AICI


dezarhiveaza fișierul
acolo trebuie să fie un folder denumit SDL2-2.0.3
În folderul respectiv cele mai important este i686-w64-mingw32, care sontine librăria pentru 32biti

Copie conținutul folderului într-un fișier creat de ține
(în acest tutorial voi pune conținutul fișierului în C:\mingw_dev_lib)

2. Pornește code::blocks și fă un proiect nou


3. Du-te în proprietăți


4. Du-te în build options


5. Du-te în search directories -> compiler
Apăsa ADD, du-te în fișierul unde ai extras bibliotecă, du-te în folderul include și selectează folderul SDL2


6. Du-te în search directories -> linker
Apăsa ADD, du-te în fișierul unde ai extras bibliotecă și selectează folderul lib


7. du-te în linker settings
Aiici trebuie să mergi în linker settings și să copii în fereastră cu a€œother linker options” acest rând:
-lminqw32 -lSDL2main -lSDL2


8. Apăsa okay, du-te înapoi la project properties, în build targets și selectează la build type: console application


9. Când aplicația rulează trebuie să copii toate fișierele din folderul bin în:
folderul unde aplicația rulează
folderul proiectului

10. Succes la implementat

Rendering
Noțiuni Introductive
Rendering este procesul de generare a unei imagini de la un model (sau modele în ceea ce colectiv ar putea fi numit un fișier scenă) prin intermediul unor programe de calculator.

Rendering an image
Noțiuni Introductive
Procesul de rendering este foarte complex.

main.cpp
imagine.h
imagine.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>

#include "initializare.h"
#include "imagine.h"

using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;Eventul pe care îl folosim pentru a detecta activitățile utilizatorului

    init();
    while (1)
    {
        while (SDL_PollEvent(&e)!=0)Preia activitatea utilizatorului
        {
            if (e.type == SDL_QUIT)
                close();Daca tipul este QUIT(utilizatorul a apasat X) iese din aplicație
        }
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);Setez culoarea cu care se deseneaza, în cazul ăsta fiind culoarea alba
        SDL_RenderClear(renderer);Elibereaza toate texturile din renderer
        imagine.render(0, 0);Pune imaginea în renderer la poziția 0 0
        SDL_RenderPresent(renderer);Rendererul pune pe ecran ce a primit
    }
    return 0;
}

#ifndef C_IMAGINE
#define C_IMAGINE

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include "initializare.h"
using namespace std;

class textureClasa pe care o folosim ca să încarcăm o imagine și mai târziu sa o punem pe ecran
{
    public:
        texture();
        ~texture();
        void load_from_file (string);Funcția care primește calea catre poză și o citește

        void free();
        void render (int, int);Funcția care primește x și y și care pune poza pe ecran

        int get_w() {return w;};Functie inline care returnează lățimea(width)
        int get_h() {return h;};Functie inline care returnează înățimea(height)

    private:
        SDL_Texture* m_texture;Textura care conține imaginea
        int w, h;Înălțimea si lățimea
};

extern texture imagine;
#endif
#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
using namespace std;

texture imagine;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}

void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_file(string path)
{
    free();
    SDL_Texture* new_texture = NULL;
    SDL_Surface* loaded_surface = IMG_Load( path.c_str() );

    new_texture = SDL_CreateTextureFromSurface (renderer, loaded_surface);
    w = loaded_surface->w;
    h = loaded_surface->h;
    SDL_FreeSurface (loaded_surface);

    m_texture = new_texture;
    return;
}

void texture::render (int x, int y)
{
    SDL_Rect render_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &render_q);
}
#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "imagine.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "imagine.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    window=SDL_CreateWindow("Image", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF );

    imagine.load_from_file( "imagine.png" );
}

void close()
{
    imagine.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    exit(EXIT_SUCCESS);
}
Rendering text
Noțiuni Introductive

main.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

#include "initializare.h"
#include "text.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);
        text.render(0, 0);Funcția prin care se pune textul pe ecran
        SDL_RenderPresent(renderer);
    }
    return 0;
}
#ifndef C_TEXT
#define C_TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);Funcția care creeaza o textură dintr-un șir de caractere

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture text;
#endif
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture text;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 60 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);Crearea texturii din suprafața deja creată

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);Copierea texturii in renderer in poziția x, y.
    	În renderer_q se află poziția exactă
}
#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif
#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );

    text.load_from_text("hello. smile, be happy.");
}

void close()
{
    text.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}
Rendering geometry
Noțiuni Introductive

main.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>

#include "initializare.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0xFF, 0XFF, 0XFF, 0XFF);
        SDL_RenderClear(renderer);

        SDL_Rect patrat = { W/4, H/4, W/2, H/2 };
        SDL_SetRenderDrawColor( renderer, 0xB2, 0x66, 0xFF, 0xFF );
        SDL_RenderFillRect( renderer, &patrat );

        SDL_Rect contur = { W/6, H/6, W*2/3, H*2/3 };
        SDL_SetRenderDrawColor( renderer, 0x66, 0x00, 0xCC, 0xFF );
        SDL_RenderDrawRect( renderer, &contur );

        SDL_SetRenderDrawColor( renderer, 0x00, 0x00, 0xFF, 0xFF );
        SDL_RenderDrawLine( renderer, H/3, 0, H/3, W);

        SDL_SetRenderDrawColor( renderer, 0x66, 0x66, 0xFF, 0xFF );
        for (int i = 0; i < H; i += 10 )
            {
                SDL_RenderDrawPoint( renderer, H, i );
            }

        SDL_RenderPresent(renderer);
    }
    return 0;
}
#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );
}

void close()
{
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    exit(EXIT_SUCCESS);
}

Events
Noțiuni Introductive

Event driven programming
Un concept interesant

-decursul programului este bazat pe acțiunile utilizatorului
-în functie de eventuri (click-uri, taste apăsate, etc.)programul răspunde diferit
-conceptul este folosit des în aplicațiile grafice interactive

Cum este folosit?
-în bucla principala din cod sunt puse bucăți de cod care preiau evenimentul și în functie de tip și de dorința programatorului oferă un răspuns (vizual sau apeleaza o altă funcție)


Work in progress...

Key presses
Noțiuni Introductive

main.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

#include "initializare.h"
#include "text.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    texture now;

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);

        now=directie[0];
        if (e.type == SDL_KEYDOWN)
        {
            switch (e.key.keysym.sym)
            {
                case SDLK_UP:
                    now=directie[1];
                    break;
                case SDLK_RIGHT:
                    now=directie[2];
                    break;
                case SDLK_DOWN:
                    now=directie[3];
                    break;
                case SDLK_LEFT:
                    now=directie[4];
                    break;
                default:
                    now=directie[0];
                    break;
            }
        }

        now.render((W-now.get_w())/2, (H-now.get_h())/2);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

#ifndef C_TEXT
#define C_TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture directie[5];
#endif

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture directie[5];

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 72 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );

    directie[0].load_from_text("apasa pe sageti");
    directie[1].load_from_text("SUS");
    directie[2].load_from_text("DREAPTA");
    directie[3].load_from_text("JOS");
    directie[4].load_from_text("STANGA");
}

void close()
{
    int i;
    for (i=0; i<5; i++) directie[i].free();

    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}

Ket states
Noțiuni Introductive

main.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

#include "initializare.h"
#include "text.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    texture now;

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);

        const Uint8* key_states = SDL_GetKeyboardState(NULL);
        if (key_states[SDL_SCANCODE_UP]) now = directie[1];
            else
        if (key_states[SDL_SCANCODE_RIGHT]) now = directie[2];
            else
        if (key_states[SDL_SCANCODE_DOWN]) now = directie[3];
            else
        if (key_states[SDL_SCANCODE_LEFT]) now = directie[4];
            else
            now = directie[0];

        now.render((W-now.get_w())/2, (H-now.get_h())/2);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

#ifndef C_TEXT
#define C_TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture directie[5];
#endif

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture directie[5];

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 72 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );

    directie[0].load_from_text("apasa pe sageti");
    directie[1].load_from_text("SUS");
    directie[2].load_from_text("DREAPTA");
    directie[3].load_from_text("JOS");
    directie[4].load_from_text("STANGA");
}

void close()
{
    int i;
    for (i=0; i<5; i++) directie[i].free();

    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}

Mouse Events
Noțiuni Introductive

main.cpp
imagine.h
imagine.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>

#include "initializare.h"
#include "imagine.h"

using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    int x=200, y=200;
    init();
    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
            if (e.type == SDL_MOUSEBUTTONDOWN)
            {
                if (e.button.button == SDL_BUTTON_LEFT)
                    x-=20;
                else if (e.button.button == SDL_BUTTON_RIGHT)
                    x+=20;
            }
        }
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
        SDL_RenderClear(renderer);
        imagine.rendererder(x, y);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

#ifndef C_IMAGINE
#define C_IMAGINE

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_file (string);

        void free();
        void rendererder (int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Texture* m_texture;
        int w, h;
};

extern texture imagine;
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
using namespace std;

texture imagine;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}

void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_file(string path)
{
    free();
    SDL_Texture* new_texture = NULL;
    SDL_Surface* loaded_surface = IMG_Load( path.c_str() );

    new_texture = SDL_CreateTextureFromSurface (renderer, loaded_surface);
    w = loaded_surface->w;
    h = loaded_surface->h;
    SDL_FreeSurface (loaded_surface);

    m_texture = new_texture;
    return;
}

void texture::rendererder (int x, int y)
{
    SDL_Rect rendererder_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &rendererder_q); //, angle, center, flip );
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <SDL_image.h>
#include <cstdlib>
#include "imagine.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "imagine.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    window=SDL_CreateWindow("DOT", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF );

    imagine.load_from_file( "poza.png" );
}

void close()
{
    imagine.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    exit(EXIT_SUCCESS);
}

Window events
Noțiuni Introductive

În SDL2 este posibilă și mișcarea ferestrelor.
Asta înseamnă că, ultilizand SDL2, jocul nostru poate fi redimensionat de către utilizator după preferințele acestuia
Când jocul nostru are fereastră redimensionabilă mai sunt anumite evenimente adiționale pe care trebuie să le luăm în considerare
Pentru asta vom face o nouă clasă (care reprezintă o îmbunătățire) pentru SDL_Window. Aici vom avea:
Un constructor
Un destructor
O funcție care inițializează
O funcție care crează un renderer din fereastră
O funcție care se ocupă de EVENIMENTE
+ funcțiile get/set


Motion
Noțiuni Introductive
Rotation and flipping
Noțiuni Introductive

main.cpp
imagine.h
imagine.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>

#include "initializare.h"
#include "imagine.h"

using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    double grade = 0;
    SDL_RendererFlip flip = SDL_FLIP_NONE;

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
        SDL_RenderClear(renderer);

        if (e.type == SDL_KEYDOWN)
        {
            switch (e.key.keysym.sym)
            {
                case SDLK_LEFT:
                    grade-=1;
                    break;

                case SDLK_RIGHT:
                    grade+=1;
                    break;

                case SDLK_UP:
                    flip = SDL_FLIP_HORIZONTAL;
                    break;

                case SDLK_DOWN:
                    flip = SDL_FLIP_VERTICAL;
                    break;
            }
        }

        sageata.render((W-sageata.get_w())/2, (H-sageata.get_h())/2, grade, flip);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

#ifndef C_IMAGINE
#define C_IMAGINE

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_file (string);

        void free();
        void render(int, int, double, SDL_RendererFlip);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Texture* m_texture;
        int w, h;
};

extern texture sageata;
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
using namespace std;

texture sageata;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}

void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_file(string path)
{
    free();
    SDL_Texture* new_texture = NULL;
    SDL_Surface* loaded_surface = IMG_Load( path.c_str() );

    new_texture = SDL_CreateTextureFromSurface (renderer, loaded_surface);
    w = loaded_surface->w;
    h = loaded_surface->h;
    SDL_FreeSurface (loaded_surface);

    m_texture = new_texture;
    return;
}

void texture::render (int x, int y, double angle, SDL_RendererFlip flip)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopyEx(renderer, m_texture, NULL, &renderer_q, angle, NULL, flip );
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "imagine.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "imagine.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    window=SDL_CreateWindow("rotation and flipping", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF );

    sageata.load_from_file( "imagine.png" );
}

void close()
{
    sageata.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    exit(EXIT_SUCCESS);
}

Colision
Noțiuni Introductive

inter.h
inter.cpp


#ifndef INTER
#define INTER

bool intersectie(int, int, int, int, int, int);

#endif

#include "inter.h"

bool intersectie(int x1, int y1, int r1, int x2, int y2, int r2)
{
    int dx, dy;
    dx=x1-x2;
    dy=y1-y2;
    int d=dx*dx+dy*dy;//distanta la patrat dintre cele 2 centre ale cercurilor
    return d<(r1+r2)*(r1+r2);
}

Levels
Noțiuni Introductive

Tilling = modul în care putem face diferite nivele dintr-un joc cu ajutorul anumitor "piese"
O piesă = un element de grafică. Aceste "piese", puse împreună într-un anumit mod, trebuie să se unească astfel încât să formeze o imagine care să corespundă cu nivelul dorit.
Avantaje:
Salvarea memoriei
Salvarea timpului
Dezajantaje:
O structură fixă a nivelelor
Din aceste motive tilingul:
era foarte popular în trecut (atât pentru aplicațiile cu resurse reduse cât și pentru restul)
încă este foarte utilizat în zilele noastre


FPS
Noțiuni Introductive

Timer
Noțiuni Introductive

main.cpp
timer.h
timer.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include <sstream>
#include <stdio.h>

#include "initializare.h"
#include "text.h"
#include "timer.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    timer ceas;
    stringstream timp;

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);

        if (e.type == SDL_KEYDOWN)
        {
            if (e.key.keysym.sym == SDLK_UP)
            {
                if (ceas.is_started()) ceas.stop();
                    else ceas.start();
            }

            if (e.key.keysym.sym == SDLK_DOWN)
            {
                if (ceas.is_paused()) ceas.unpause();
                    else ceas.pause();
            }
        }

        timp.str("");
        timp<< "seconds since start "<< (ceas.get_ticks()/1000.f);
        time_text.load_from_text(timp.str().c_str());

        start_text.render(10, 100);
        pause_text.render(10, 200);
        time_text.render(10, 300);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

#ifndef TIMER_H
#define TIMER_H

class timer
{
    public:
        timer();
        void start();
        void stop();
        void pause();
        void unpause();

        int get_ticks();

        bool is_started();
        bool is_paused();

    private:
        int start_ticks, paused_ticks;
        bool started, paused;
};

#endif

#include "timer.h"
#include <SDL.h>

timer::timer()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::start()
{
    started = true;
    paused = false;

    start_ticks = SDL_GetTicks();
    paused_ticks = 0;
}

void timer::stop()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::pause()
{
    if (started && !paused)
    {
        paused = true;
        paused_ticks = SDL_GetTicks() - start_ticks;
        start_ticks = 0;
    }
}

void timer::unpause()
{
    if (started && paused)
    {
        paused = false;
        start_ticks = SDL_GetTicks() - paused_ticks;
        paused_ticks = 0;
    }
}

int timer::get_ticks()
{
    int time=0;
    if (started)
        if (paused) time = paused_ticks;
            else time = SDL_GetTicks() - start_ticks;
    return time;
}

bool timer::is_started()
{
    return started;
}

bool timer::is_paused()
{
    return paused && started;
}

#ifndef C_TEXT
#define C_TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture time_text, pause_text, start_text;
#endif

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture time_text, pause_text, start_text;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 36 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );

    start_text.load_from_text("apasa sageata de sus pentru START/STOP");
    pause_text.load_from_text("apasa sageata de jos pentru PAUSE/UNPAUSE");
}

void close()
{
    time_text.free();
    pause_text.free();
    start_text.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}

Timer Callbacks
Noțiuni Introductive
Pagină în lucru


FPS
Noțiuni Introductive

main.cpp
timer.h
timer.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include <sstream>
#include <stdio.h>

#include "initializare.h"
#include "text.h"
#include "timer.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    timer ceas;
    stringstream timp;

    int nr_frames = 0;
    ceas.start();

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);

        double medie_frames = nr_frames / (ceas.get_ticks() / 1000.f);
        if (medie_frames > 2000000)
            medie_frames = 0;

        timp.str("");
        timp<< "media de frameuri pe secunda este de "<< medie_frames;
        time_text.load_from_text(timp.str().c_str());

        time_text.render((W-600)/2, (H - time_text.get_h())/2);
        SDL_RenderPresent(renderer);

        ++nr_frames;
    }
    return 0;
}

#ifndef TIMER_H
#define TIMER_H

class timer
{
    public:
        timer();
        void start();
        void stop();
        void pause();
        void unpause();

        int get_ticks();

        bool is_started();
        bool is_paused();

    private:
        int start_ticks, paused_ticks;
        bool started, paused;
};

#endif

#include "timer.h"
#include <SDL.h>

timer::timer()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::start()
{
    started = true;
    paused = false;

    start_ticks = SDL_GetTicks();
    paused_ticks = 0;
}

void timer::stop()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::pause()
{
    if (started && !paused)
    {
        paused = true;
        paused_ticks = SDL_GetTicks() - start_ticks;
        start_ticks = 0;
    }
}

void timer::unpause()
{
    if (started && paused)
    {
        paused = false;
        start_ticks = SDL_GetTicks() - paused_ticks;
        paused_ticks = 0;
    }
}

int timer::get_ticks()
{
    int time=0;
    if (started)
        if (paused) time = paused_ticks;
            else time = SDL_GetTicks() - start_ticks;
    return time;
}

bool timer::is_started()
{
    return started;
}

bool timer::is_paused()
{
    return paused && started;
}

#ifndef C_TEXT
#define C_TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture time_text;
#endif

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture time_text;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 36 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);
}

#ifndef C_INITIALIZARE
#define C_INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );
}

void close()
{
    time_text.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}

FPS
Noțiuni Introductive

main.cpp
timer.h
timer.cpp
text.h
text.cpp
initializare.h
initializare.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include <sstream>
#include <stdio.h>

#include "initializare.h"
#include "text.h"
#include "timer.h"
using namespace std;

int main(int argc, char* args[])
{
    SDL_Event e;
    init();

    timer ceas;
    timer seteaza;
    stringstream timp;

    int nr_frames = 0;
    ceas.start();

    while (1)
    {
        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                close();
        }

        SDL_SetRenderDrawColor(renderer, 0x00, 0X00, 0X00, 0XFF);
        SDL_RenderClear(renderer);

        double medie_frames = nr_frames / (ceas.get_ticks() / 1000.f);
        if (medie_frames > 2000000)
            medie_frames = 0;

        timp.str("");
        timp<< "media de frameuri (setate) pe secunda este de "<< medie_frames;
        time_text.load_from_text(timp.str().c_str());

        time_text.render((W-730)/2, (H - time_text.get_h())/2);
        SDL_RenderPresent(renderer);

        ++nr_frames;

        int frame_ticks = seteaza.get_ticks();
        if (frame_ticks < TICK_PER_FRAME)
        {
            SDL_Delay(TICK_PER_FRAME - frame_ticks);
        }
    }
    return 0;
}

#ifndef TIMER_H
#define TIMER_H

class timer
{
    public:
        timer();
        void start();
        void stop();
        void pause();
        void unpause();

        int get_ticks();

        bool is_started();
        bool is_paused();

    private:
        int start_ticks, paused_ticks;
        bool started, paused;
};

#endif

#include "timer.h"
#include <SDL.h>

timer::timer()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::start()
{
    started = true;
    paused = false;

    start_ticks = SDL_GetTicks();
    paused_ticks = 0;
}

void timer::stop()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::pause()
{
    if (started && !paused)
    {
        paused = true;
        paused_ticks = SDL_GetTicks() - start_ticks;
        start_ticks = 0;
    }
}

void timer::unpause()
{
    if (started && paused)
    {
        paused = false;
        start_ticks = SDL_GetTicks() - paused_ticks;
        paused_ticks = 0;
    }
}

int timer::get_ticks()
{
    int time=0;
    if (started)
        if (paused) time = paused_ticks;
            else time = SDL_GetTicks() - start_ticks;
    return time;
}

bool timer::is_started()
{
    return started;
}

bool timer::is_paused()
{
    return paused && started;
}

#ifndef TEXT
#define TEXT

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_text(string);

        void free();
        void render(int, int);

        int get_w() {return w;};
        int get_h() {return h;};

    private:
        SDL_Surface* m_surface;
        SDL_Texture* m_texture;
        int w, h;
};

extern texture time_text;
#endif

#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <string>
#include "initializare.h"
#include "text.h"

using namespace std;

texture time_text;

texture::texture() {m_texture = NULL; w=0; h=0;}
texture::~texture() {free();}


void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::load_from_text(string path)
{
    free();
    SDL_Color color; color = { 255, 255, 255 };
    TTF_Font* font; font = TTF_OpenFont( "font.ttf", 36 );

    m_surface = TTF_RenderText_Solid(font, path.c_str(), color);
    m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);

    w = m_surface->w;
    h = m_surface->h;
    return;
}

void texture::render(int x, int y)
{
    SDL_Rect renderer_q = {x, y, w, h};
    SDL_RenderCopy(renderer, m_texture, NULL, &renderer_q);
}

#ifndef INITIALIZARE
#define INITIALIZARE

#include <SDL.h>
#include <cstdlib>
#include "text.h"

extern SDL_Renderer* renderer;
extern SDL_Window* window;
extern int W, H;

extern int FPS, TICK_PER_FRAME;

void init();
void close();
#endif

#include <SDL.h>
#include <SDL_image.h>
#include "initializare.h"
#include "text.h"

SDL_Renderer* renderer;
SDL_Window* window;
int W=800, H=600;

int FPS = 60;
int TICK_PER_FRAME = 1000 / FPS;

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();
    window=SDL_CreateWindow("text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    renderer=SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF );
}

void close()
{
    time_text.free();
    SDL_DestroyRenderer( renderer ); renderer = NULL;
    SDL_DestroyWindow( window ); window = NULL;
    IMG_Quit();
    SDL_Quit();
    TTF_Quit();
    exit(EXIT_SUCCESS);
}

Frame independent movement
Noțiuni Introductive

main.cpp
biluta.h
biluta.cpp
timer.h
timer.cpp
renderer.h
renderer.cpp


#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>

#include "biluta.h"
#include "renderer.h"
#include "timer.h"

using namespace std;

void init();
void close();

SDL_Window* win;
int W=800, H=600;

int frames_per_second = 60;
int tick_per_frame = 1000 / frames_per_second;

int main( int argc, char* args[] )
{
    bool quit = false;
    SDL_Event e;
    biluta dot;

    timer fps_timer, cap_timer;
    //int counted_frames = 0;

    init();

    int time_last, time_now;
    fps_timer.start();

    while (!quit)
    {
        cap_timer.start();

        while (SDL_PollEvent(&e)!=0)
        {
            if (e.type == SDL_QUIT)
                quit=true;
            dot.handle_event( e );
        }

        int frame_ticks = cap_timer.get_ticks();
        if (frame_ticks < tick_per_frame)
             SDL_Delay(tick_per_frame - frame_ticks);

        float dt=cap_timer.get_ticks();
        dot.move (dt/10);

        SDL_SetRenderDrawColor( ren, 0xFF, 0xFF, 0xFF, 0xFF );
        SDL_RenderClear(ren);
        dot.render();
        SDL_RenderPresent(ren);
    }

    close();
    return 0;
}

void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    win=SDL_CreateWindow("DOT", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, W, H, NULL);

    ren=SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF );

    dot_texture.load_from_file( "dot.bmp" );
}

void close()
{
    dot_texture.free();
    SDL_DestroyRenderer( ren ); ren = NULL;
    SDL_DestroyWindow( win ); win = NULL;
    IMG_Quit();
    SDL_Quit();
}

#ifndef BILUTA_H
#define BILUTA_H

#include <SDL.h>
#include <SDL_image.h>
#include <string>
using namespace std;

class texture
{
    public:
        texture();
        ~texture();
        void load_from_file (string);

        void free();
        void render(int, int);

        int get_w();
        int get_h();

    private:
        SDL_Texture* m_texture;
        int w, h;
};

extern texture dot_texture;

class biluta
{
    public:
        static const int dot_w = 20;
        static const int dot_h = 20;
        static const int dot_v = 10;

        biluta();

        void handle_event(SDL_Event&);
        void move(float);
        void render();

    private:
        int pos_x, pos_y;
        int vel_x, vel_y;
};

#endif

#include <SDL.h>
#include <SDL_image.h>
#include "renderer.h"
#include "biluta.h"
using namespace std;

texture::texture()
{
    m_texture = NULL; w=0; h=0;
}

texture::~texture()
{
    free();
}

void texture::load_from_file(string path)
{
    free();
    SDL_Texture* new_texture = NULL;
    SDL_Surface* loaded_surface = IMG_Load( path.c_str() );

    new_texture = SDL_CreateTextureFromSurface (ren, loaded_surface);
    w = loaded_surface->w;
    h = loaded_surface->h;
    SDL_FreeSurface (loaded_surface);

    m_texture = new_texture;
    return;
}

void texture::free()
{
    SDL_DestroyTexture (m_texture);
    m_texture = NULL; w = 0; h = 0;
}

void texture::render (int x, int y)
{
    SDL_Rect render_q = {x, y, w, h};
    SDL_RenderCopy (ren, m_texture, NULL, &render_q);
}
void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );


int texture::get_w()
{
    return w;
}

int texture::get_h()
{
    return h;
}

biluta::biluta()
{
    pos_x = 0; pos_y = 0;
    vel_x = 0; vel_y = 0;
}

void biluta::handle_event(SDL_Event& e)
{
    if( e.type == SDL_KEYDOWN && e.key.repeat == 0 )
    {
        switch( e.key.keysym.sym )
        {
            case SDLK_UP: vel_y -= dot_v; break;
            case SDLK_DOWN: vel_y += dot_v; break;
            case SDLK_LEFT: vel_x -= dot_v; break;
            case SDLK_RIGHT: vel_x += dot_v; break;
        }
    }
    else
    if( e.type == SDL_KEYUP && e.key.repeat == 0 )
    {
        switch( e.key.keysym.sym )
        {
            case SDLK_UP: vel_y += dot_v; break;
            case SDLK_DOWN: vel_y -= dot_v; break;
            case SDLK_LEFT: vel_x += dot_v; break;
            case SDLK_RIGHT: vel_x -= dot_v; break;
        }
    }
}

void biluta::move( float time_step )
{
    int W=800, H=600;

    pos_x += vel_x * time_step;

    if (pos_x < 0) pos_x = 0;
    else if (pos_x > W - dot_w) pos_x = W - dot_w;

    pos_y += vel_y * time_step;

    if (pos_y < 0) pos_y = 0;
    else if (pos_y > H - dot_h) pos_y = H - dot_h;
}

void biluta::render()
{
    dot_texture.render(pos_x, pos_y);
}

texture dot_texture;
#ifndef TIMER_H
#define TIMER_H

class timer
{
    public:
        timer();
        void start();
        void stop();
        void pause();
        void unpause();

        int get_ticks();

        bool is_start();
        bool is_paused();

    private:
        int start_ticks, paused_ticks;
        bool paused, started;
};

#endif

#include "timer.h"
#include <SDL.h>

timer::timer()
{
    start_ticks = 0;
    paused_ticks = 0;

    paused = false;
    started = false;
}

void timer::start()
{
    started = true;
    paused = false;

    start_ticks = SDL_GetTicks();
    paused_ticks = 0;
}

void timer::stop()
{
    started = false;
    paused = false;

    start_ticks = 0;
    paused_ticks = 0;
}

void timer::pause()
{
    if (started && !paused)
    {
        paused = true;
        paused_ticks = SDL_GetTicks() - start_ticks;
        paused_ticks = 0;
    }
}

int timer::get_ticks()
{
    int time = 0;
    if (started)
        if (paused)
        time = paused_ticks;
        else
        time = SDL_GetTicks() - start_ticks;

    return time;
}

bool timer::is_start()
{
    return started;
}

bool timer::is_paused()
{
    return paused && started;
}

#ifndef RENDERER_H
#define RENDERER_H
#include <SDL.h>
extern SDL_Renderer* ren;
#endif

#include "renderer.h"
#include <SDL.h>
SDL_Renderer* ren;

Test final
This demo illustrates the free Javascript quiz maker script from DHTMLGoodies.com