Dans ce tutoriels vous allez apprendre a détecter une collision entre de surface en SDL

pour coder proprement cela ce fera dans la fonction isCollide qui prendra comme paramètre deux structure de type SDL_Rect et renvois 1 si il ya eu collision ou 0 si il y’en a pas

int isCollide(SDL_Rect obj1, SDL_Rect obj2)
{
    return
    (
        obj1.x          >= obj2.x && obj1.x         <= obj2.x+obj2.w &&
        obj1.y          >= obj2.y && obj1.y         <= obj2.y+obj2.h ||

        obj1.x+obj1.w   >= obj2.x && obj1.x+obj1.w  <= obj2.x+obj2.w &&
        obj1.y          >= obj2.y && obj1.y         <= obj2.y+obj2.h ||

        obj1.x          >= obj2.x && obj1.x         <= obj2.x+obj2.w &&
        obj1.y+obj1.h   >= obj2.y && obj1.y+obj1.h  <= obj2.y+obj2.h ||

        obj1.x+obj1.w   >= obj2.x && obj1.x+obj1.w  <= obj2.x+obj2.w &&
        obj1.y+obj1.h   >= obj2.y && obj1.y+obj1.h  <= obj2.y+obj2.h ||

        obj2.x          >= obj1.x && obj2.x         <= obj1.x+obj1.w &&
        obj2.y          >= obj1.y && obj2.y         <= obj1.y+obj1.h ||

        obj2.x+obj2.w   >= obj1.x && obj2.x+obj2.w  <= obj1.x+obj1.w &&
        obj2.y          >= obj1.y && obj2.y         <= obj1.y+obj1.h ||

        obj2.x          >= obj1.x && obj2.x         <= obj1.x+obj1.w &&
        obj2.y+obj2.h   >= obj1.y && obj2.y+obj2.h  <= obj1.y+obj1.h ||

        obj2.x+obj2.w   >= obj1.x && obj2.x+obj2.w  <= obj1.x+obj1.w &&
        obj2.y+obj2.h   >= obj1.y && obj2.y+obj2.h  <= obj1.y+obj1.h
    );
}

Petite explication:
pour détecter une collision entre deux surface carrée en test en premier temps en test si un des point de la premier surface ce trouve a l’intérieur de la deuxième surface ensuit c’est l’inverse en test si un des point de la deuxièmes surface ce trouve a l’intérieur de la premier surface

Exemple:
pour cela supposions que ‘P’ soit le point a test si il est a l’intérieur d’une surface appeler ‘S’ en fait comme ce-si

if(P.x >= S.x && P.x <= S.x+S.w && P.y >= S.y && P.y <= S.y+S.h)
cout << "Collision !" << endl;

else
cout << "Pas de collision" << endl;

Exemple de programme complet:

#include <stdlib.h>
#include <stdio.h>

#include <sdl.h>
#include <sdl_framerate.h>

#define MOVE_POWER 5

int isCollide(SDL_Rect obj1, SDL_Rect obj2)
{
    return
    (
        obj1.x          >= obj2.x && obj1.x         <= obj2.x+obj2.w &&
        obj1.y          >= obj2.y && obj1.y         <= obj2.y+obj2.h ||

        obj1.x+obj1.w   >= obj2.x && obj1.x+obj1.w  <= obj2.x+obj2.w &&
        obj1.y          >= obj2.y && obj1.y         <= obj2.y+obj2.h ||

        obj1.x          >= obj2.x && obj1.x         <= obj2.x+obj2.w &&
        obj1.y+obj1.h   >= obj2.y && obj1.y+obj1.h  <= obj2.y+obj2.h ||

        obj1.x+obj1.w   >= obj2.x && obj1.x+obj1.w  <= obj2.x+obj2.w &&
        obj1.y+obj1.h   >= obj2.y && obj1.y+obj1.h  <= obj2.y+obj2.h ||

        obj2.x          >= obj1.x && obj2.x         <= obj1.x+obj1.w &&
        obj2.y          >= obj1.y && obj2.y         <= obj1.y+obj1.h ||

        obj2.x+obj2.w   >= obj1.x && obj2.x+obj2.w  <= obj1.x+obj1.w &&
        obj2.y          >= obj1.y && obj2.y         <= obj1.y+obj1.h ||

        obj2.x          >= obj1.x && obj2.x         <= obj1.x+obj1.w &&
        obj2.y+obj2.h   >= obj1.y && obj2.y+obj2.h  <= obj1.y+obj1.h ||

        obj2.x+obj2.w   >= obj1.x && obj2.x+obj2.w  <= obj1.x+obj1.w &&
        obj2.y+obj2.h   >= obj1.y && obj2.y+obj2.h  <= obj1.y+obj1.h
    );
}

int main(int argc, char** argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("Tutoriels Collision",0);
    SDL_Surface* screen = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
    SDL_Event event;
    int exit = 0;

    SDL_Surface* ball = SDL_CreateRGBSurface(SDL_HWSURFACE,32,32,32,0,0,0,0);
    SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,0,255,255,255));

    SDL_Surface* cube1 = SDL_CreateRGBSurface(SDL_HWSURFACE,64,64,32,0,0,0,0);
    SDL_FillRect(cube1,0,SDL_MapRGBA(cube1->format,0,255,255,255));

    SDL_Surface* cube2 = SDL_CreateRGBSurface(SDL_HWSURFACE,128,128,32,0,0,0,0);
    SDL_FillRect(cube2,0,SDL_MapRGBA(cube2->format,0,255,255,255));

    SDL_Rect ballpos = {10,10};
    SDL_Rect cube1pos = {100,100};
    SDL_Rect cube2pos = {300,300};

    FPSmanager fps;
    SDL_initFramerate(&fps);
    SDL_setFramerate(&fps,60);

    while(!exit)
    {
        SDL_PollEvent(&event);

        if(event.type == SDL_QUIT)
        exit = 1;

        /// Si appuye sur la touceh Espace
        if(event.type == SDL_KEYDOWN)
        {
            if(event.key.keysym.sym == SDLK_UP)
            ballpos.y -= MOVE_POWER;

            if(event.key.keysym.sym == SDLK_DOWN)
            ballpos.y += MOVE_POWER;

            if(event.key.keysym.sym == SDLK_LEFT)
            ballpos.x -= MOVE_POWER;

            if(event.key.keysym.sym == SDLK_RIGHT)
            ballpos.x += MOVE_POWER;
        }

        /// Si collision (balle rouge)
        if(isCollide(ballpos,cube1pos) || isCollide(ballpos,cube2pos))
        SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,255,0,0,255));

        /// Sinon (balle blue)
        else
        SDL_FillRect(ball,0,SDL_MapRGBA(ball->format,0,255,255,255));

       // Ajustement pour que la ball ne depasse pas l'ecran
        if(ballpos.y+ballpos.h > screen->h) ballpos.y = screen->h-ballpos.h;
        if(ballpos.x+ballpos.w > screen->w) ballpos.x = screen->w-ballpos.w;
        if(ballpos.x < 0) ballpos.x = 0;
        if(ballpos.y < 0) ballpos.y = 0;

        SDL_FillRect(screen,0,0);

        SDL_BlitSurface(cube1,0,screen,&cube1pos);
        SDL_BlitSurface(cube2,0,screen,&cube2pos);
        SDL_BlitSurface(ball,0,screen,&ballpos);

        SDL_framerateDelay(&fps);
        SDL_Flip(screen);
    }

    SDL_FreeSurface(ball);
    SDL_FreeSurface(cube1);
    SDL_FreeSurface(cube2);
    SDL_Quit();

    return 0;
}

Image: http://download.tuxfamily.org/b4n92uidsite/sdl-collide/collide.png

Voila cette technique montre comment détecter une collision entre deux surface car pour info ce test s’appelle la détection du Boundign Box de l’image il existe aussi la détection du Boundign Sphere de l’image celle si utilise les vecteur et le rayon d’une sphere pour détecter la collision et s’applique mieux aux forme rond.

Télécharger l’archive content le projet et l’exécutable