Programmer un screenshaker en C/SDL
 

      Pour ce petit tutoriel, nous allons voir comment faire trembler l'écran à l'aide d'une fonction : shakeScreen. C'est une fonction que j'ai créée pour le jeu Wiwi's Adventures 2.

Tutoriel présenté par : Jérémie F. Bellanger
Publication : 07 octobre 2010

 
    Dans un jeu vidéo, il peut être utile de faire trembler l'écran, notemment pour simuler des chocs violents ou les pas lourds d'un gros boss. Cette fonction a pour mérite d'être simple, rapide et adaptable à tout projet programmé en C avec la SDL.

    Ce que fait cette fonction : elle blitte rapidement (toutes les 16 ms, pour avoir 60 images/stories/seconde) l'image de l'écran à deux coordonnées différentes en alternance. On a ainsi l'impression que l'écran tremble.

    On peut régler sa durée en faisant varier la valeur de i et on peut aussi rajouter, si on le souhaite, plus de coordonnées de blittage différentes.

    Il faut noter cependant que cette fonction ne doit durer que quelques secondes pour être crédible, car elle bloque aussi le renouvellement de l'affichage (c'est-à-dire que les sprites ne s'animent plus). Elle est là pour simuler un choc rapide et soudain qui cloue tout le monde sur place ;)

    Voici la fonction, commentée :


Code C utilisant la SDL :
 
/* Permet de faire vibrer l'écran pendant quelques secondes */

void shakeScreen(void)
{
   
    /* On crée une surface temporaire et on y enregistre l'écran de jeu (screen) */
    SDL_Surface *temp = SDL_DisplayFormat(screen);
    SDL_Rect dest;
    int i;

    /* Dans une boucle, on va "shaker" l'écran en le blittant 1 fois sur deux à x et y = 4 et autrement à (0,0) */
    for (i = 0 ; i < 30 ; i++)
    {
        /* Selon que la division de i par deux est entière ou non, on blitte aux coordonnées différentes (0,0) ou (4,4) */
        if (i%2 == 0)
        {
            dest.x = 4;
            dest.y = 4;
        }
        else
        {
            dest.x = 0;
            dest.y = 0;
        }

        /* On remplit l'écran de noir pour éviter les surimpressions */
        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,           0, 0, 0));
        /* On blitte aux nouvelles coordonnées */
        SDL_BlitSurface(temp, NULL, screen, &dest);
        /* On affiche l'écran */
        SDL_Flip(screen);
        /* On fait une pause de 16ms pour se limiter à 60fps (images/stories/seconde) */
        SDL_Delay(16);

    }

    /* On reblitte l'écran à sa place d'origine */
    dest.x = 0;
    dest.y = 0;
    SDL_BlitSurface(temp, NULL, screen, &dest);

    /* Puis on supprime notre surface temporaire */
    SDL_FreeSurface(temp);

}

    Variante intéressante : Pampattitude m'a proposé une variante intéressante pour le tremblement d'écran avec un blittage aléatoire. La voici :


VARIANTE :
 
/* Permet de faire vibrer l'écran pendant quelques secondes */

void shakeScreen(void)
{
   
    /* On crée une surface temporaire et on y enregistre l'écran de jeu (screen) */
    SDL_Surface *temp = SDL_DisplayFormat(screen);
    SDL_Rect dest;
    int i;

    /* Dans une boucle, on va "shaker" l'écran en le blittant 1 fois sur deux à x et y = 4 et autrement à (0,0) */
    for (i = 0 ; i < 30 ; i++)
    {
        /* On blitte aléatoirement */
            dest.x = rand() % 12 - 6;
            dest.y = rand() % 12 - 6;
       
        /* On blitte aux nouvelles coordonnées */
        SDL_BlitSurface(temp, NULL, screen, &dest);
        /* On affiche l'écran */
        SDL_Flip(screen);
        /* On fait une pause de 16ms pour se limiter à 60fps (images/stories/seconde) */
        SDL_Delay(16);

    }

    /* On reblitte l'écran à sa place d'origine */
    dest.x = 0;
    dest.y = 0;
    SDL_BlitSurface(temp, NULL, screen, &dest);

    /* Puis on supprime notre surface temporaire */
    SDL_FreeSurface(temp);

}


    Libre à vous d'essayer les deux et d'en choisir une ou de l'adapter librement ;) Et n'hésitez pas à m'envoyer des exemples d'adaptations de cette fonction dans vos projets !




 

Connexion

CoalaWeb Traffic

Today106
Yesterday147
This week805
This month253
Total1734468

2/03/24