Créons un jeu de plateformes de A à Z !



Tutoriel présenté par : Jérémie F. Bellanger
Dernière mise à jour : 08 novembre 2010
Difficulté :  



6. Gérer le scrolling de la map


    Vous avez toujours rêvé de scroller sans jamais savoir comment faire  ? Eh bien, c'est votre jour de chance !

    On va en effet rajouter un scrolling à notre map, que nous dirigerons au clavier (pour l'instant), et ça va être rapide et super facile ! Si, si, faites-moi confiance !



Résultat à la fin de ce chapitre : on scrolle la map au clavier  !



    Alors tout d'abord, vous allez télécharger une nouvelle map, à enregistrer dans le dossier du projet (Aron) dans le sous-dossier map à la place de l'ancienne. Celle-ci est déjà préconçue pour vous permettre de scroller (un peu) :

map1.txt

    Voilà une bonne chose de faite, nous pouvons donc maintenant modifier notre code !
    Première chose à faire, nous allons rajouter la fonction update() dans la boucle de notre main pour traiter les inputs du clavier et permettre à la map de scroller.

Nom du fichier : main.c


    #include "main.h"

    int main( int argc, char *argv[ ] )
   {
    unsigned int frameLimit = SDL_GetTicks() + 16;
    int go;

    /* Initialisation de la SDL dans une fonction séparée (voir après) */
        init("Aron");

   /* Appelle la fonction cleanup à la fin du programme */
         atexit(cleanup);

    go = 1;


    /* Boucle infinie, principale, du jeu */

    while (go == 1)
    {

        /* On vérifie l'état des entrées (clavier puis plus tard joystick) */
        getInput();

        /* On met à jour le jeu */
        update();

        /* On affiche tout */
        draw();

        /* Gestion des 60 fps ( 60 images pas seconde : soit 1s ->1000ms/60 = 16.6 -> 16
        On doit donc attendre 16 ms entre chaque image (frame) */

        delay(frameLimit);
        frameLimit = SDL_GetTicks() + 16;

    }

    /* Exit */
    exit(0);

    }

      


    Et nous rajouterons donc le prototype de cette fonction dans main.h (vous devriez commencer à avoir l'habitude maintenant ) :

Nom du fichier : main.h


  extern void update(void);



    On va maintenant implémenter cette fonction dans le fichier input.c en-dessous de getInput() :

Nom du fichier : input.c


 void update(void)
{

     if (input.left == 1)
    {
        map.startX -= TILE_SIZE;

        if (map.startX < 0)
        {
            map.startX = 0;
        }
    }

    else if (input.right == 1)
    {
        map.startX += TILE_SIZE;

        if (map.startX + SCREEN_WIDTH >= map.maxX)
        {
            map.startX = map.maxX - SCREEN_WIDTH;
        }
    }

    if (input.up == 1)
    {
        map.startY -= TILE_SIZE;

        if (map.startY < 0)
        {
            map.startY = 0;
        }
    }

    else if (input.down == 1)
    {
        map.startY += TILE_SIZE;

        if (map.startY + SCREEN_HEIGHT >= map.maxY)
        {
            map.startY = map.maxY - SCREEN_HEIGHT;
        }
    }

}


 

 

    Comme vous pouvez le voir, cette fonction est on ne peut plus simple.
    On teste s'il y a un appui sur les touches fléchées haut, bas, gauche, droite du clavier (à l'aide des variables input mises à jour par la fonction getInput() ) et en fonction de ça on scrolle de la valeur de TILE_SIZE, c'est-à-dire de 32 pixels. Vous pouvez faire varier cette valeur pour un scrolling plus ou moins rapide .
    Par sécurité, on vérifie aussi, si on ne sort pas de la map, en calant le scrolling à sa valeur max si les coordonnées de la carte (map.startX et map.startY) les atteignent ou les dépassent.

    Et n'oublions pas d'ajouter dans input.h :


  extern Map map;
 

    Il ne reste maintenant plus qu'à mettre à jour notre fonction drawMap() :

Nom du fichier : map.c


  void drawMap(void)
 {
    int x, y, mapX, x1, x2, mapY, y1, y2, xsource, ysource, a;

   /* On initialise mapX à la 1ère colonne qu'on doit blitter.
    Celle-ci correspond au x de la map (en pixels) divisés par la taille d'une tile (32)
    pour obtenir la bonne colonne de notre map
    Exemple : si x du début de la map = 1026, on fait 1026 / 32
    et on sait qu'on doit commencer par afficher la 32eme colonne de tiles de notre map */
    mapX = map.startX / TILE_SIZE;

    /* Coordonnées de départ pour l'affichage de la map : permet
    de déterminer à quels coordonnées blitter la 1ère colonne de tiles au pixel près
    (par exemple, si la 1ère colonne n'est visible qu'en partie, on devra commencer à blitter
    hors écran, donc avoir des coordonnées négatives - d'où le -1). */
    x1 = (map.startX % TILE_SIZE) * -1;

    /* Calcul des coordonnées de la fin de la map : jusqu'où doit-on blitter ?
    Logiquement, on doit aller à x1 (départ) + SCREEN_WIDTH (la largeur de l'écran).
    Mais si on a commencé à blitter en dehors de l'écran la première colonne, il
    va falloir rajouter une autre colonne de tiles sinon on va avoir des pixels
    blancs. C'est ce que fait : x1 == 0 ? 0 : TILE_SIZE qu'on pourrait traduire par:
    if(x1 != 0)
        x2 = x1 + SCREEN_WIDTH + TILE_SIZE , mais forcément, c'est plus long ;)*/
    x2 = x1 + SCREEN_WIDTH + (x1 == 0 ? 0 : TILE_SIZE);

    /* On fait exactement pareil pour calculer y */
    mapY = map.startY / TILE_SIZE;
    y1 = (map.startY % TILE_SIZE) * -1;
    y2 = y1 + SCREEN_HEIGHT + (y1 == 0 ? 0 : TILE_SIZE);

   
    /* Dessine la carte en commençant par startX et startY */

    /* On dessine ligne par ligne en commençant par y1 (0) jusqu'à y2 (480)
    A chaque fois, on rajoute TILE_SIZE (donc 32), car on descend d'une ligne
    de tile (qui fait 32 pixels de hauteur) */

    for (y = y1; y < y2; y += TILE_SIZE)
    {
        /* A chaque début de ligne, on réinitialise mapX qui contient la colonne
        (0 au début puisqu'on ne scrolle pas) */

        mapX = map.startX / TILE_SIZE;

        /* A chaque colonne de tile, on dessine la bonne tile en allant
        de x = 0 à x = 640 */

        for (x = x1; x < x2; x += TILE_SIZE)
        {

            /* Suivant le numéro de notre tile, on découpe le tileset */

            a = map.tile[mapY][mapX];

            /* Calcul pour obtenir son y (pour un tileset de 10 tiles
            par ligne, d'où le 10 */

            ysource = a / 10 * TILE_SIZE;

            /* Et son x */

            xsource = a % 10 * TILE_SIZE;

            /* Fonction qui blitte la bonne tile au bon endroit */

            drawTile(map.tileSet, x, y, xsource, ysource);

            mapX++;
        }

        mapY++;
    }
  }
 


    Ici, on efface les calculs simplifiés de l'affichage de la map et on les remplace par les calculs en commentaires.

    Les explications sont fournies directement ligne par ligne ci-dessus.
    Pour faire court, on calcule par quelles colonne et ligne de tiles on doit commencer l'affichage, selon les valeurs de map.startX et map.startY (qui augmentent/diminuent selon les inputs) et ensuite on calcule où commencer à blitter la première colonne et la première ligne (parfois hors-écran selon le scrolling). Enfin, on calcule où arrêter l'affichage de la map : si la 1ère ligne/colonne a été blittée hors écran, il va en effet falloir blitter une ligne/colonne de plus.

    Vous pouvez vous amuser à changer ces calculs pour mieux comprendre comment cela fonctionne (ça peut paraître un peu difficile au début, c'est normal ). Supprimez, par exemple :
(x1 == 0 ? 0 : TILE_SIZE) pour voir son importance !

 
    Eh voilà notre scrolling est terminé (quoi ? déjà  !!!), on est maintenant prêt à compiler... BUILD... RUN et tadaaaaam !
Appuyez sur les touches fléchées du clavier, et ça scrolle  !!!



    Et maintenant, prochaine étape : un level editor  !!






     

 

This site uses cookies to enable you to log in. We do not store or sell any personal data. By continuing to use this website, you agree to their use. Thanks!