Partage
  • Partager sur Facebook
  • Partager sur Twitter

Comment faire un scrolling [SDL]

je cherche une explication simple

    3 avril 2010 à 20:38:29

    Bonjour à tous,
    J'ai un projet de jeu et je voudrai faire un scrolling en sdl mais je ne trouve aucun tutoriel clair et assez simple(je ne comprends pas le tuto de tile mapping ainsi que celui très connu de loka.developpez.com)
    Est ce que vous pourriez m'expliquer le procédé de manière à ce que je puisse l'adapter à mon code.
    Merci d'avance
    Eldunari
    • Partager sur Facebook
    • Partager sur Twitter
      3 avril 2010 à 21:09:23

      Salut, c'est assez simple dans l'idée, ton écran et tes persos se déplacent sur une immense carte virtuelle, et lors de l'affichage tu affiches les parties de la carte correspond à l'emplacement de ton écran.

      En gros si tu as une carte qui fait 2048x480px, et que ton écran fait 640x480, les coordonnées de ton joueur ne seront plus celle à l'écran, mais celle sur la grande carte (qui pourront donc varier à peu près entre 0 et 2048 pour les x par exemple), et ton écran aura ses coordonnées sur la carte qui varieront entre 0 et 2048-640 pour les x.

      Lors de l'affichage, tu trouves une relation entre la position de l'écran et celle de ton perso sur la map (vive les dessins papiers :) ).

      Puis pour avoir l'effet scroll, tu modifies les coordonnées de l'écran sur la map en fonction de celle de ton perso (ca dépend de comment tu veux que l'écran bouge par rapport au perso).
      • Partager sur Facebook
      • Partager sur Twitter
        3 avril 2010 à 23:34:42

        Merci pour ta réponse. J'ai a présent compris le principe mais je me demande comment définir la surface de l'image de fond comme une map sur laquelle l'écran se déplace(je ne travaille pas sur une map, mon perso est sur une sorte de plateforme avec une image d'arrière plan derrière). Comment faire en sorte que mon écran se déplace "sur" cette image d'arrière plan et cette plateforme , en suivant mon personnage?
        • Partager sur Facebook
        • Partager sur Twitter
          3 avril 2010 à 23:40:51

          Tu as une image géante en fond ? Si c'est le cas c'est simple, tu utilises le 2ème paramètre de SDL_BlitSurface en lui envoyant un SDL_Rect contant les coordonnées de ton écran sur ton image géante et sa taille.
          Si tu n'utilises pas une image géante, c'est que j'ai pas compris ce que tu as dis :p
          Pour la plate forme tu la blit de façon normal tu dois juste corriger les coordonnées du blit par rapport à l'écran.
          • Partager sur Facebook
          • Partager sur Twitter
            4 avril 2010 à 10:18:39

            Je crois que j'ai compris a présent. J'ai juste une dernière question: sur quoi vais-je coller mon image d'arrière plan, si mon écran est collé dessus.
            et aussi , tu m'as dis de coller mon écran avec la deuxième fonction de SDL BlitSurface, mais dois je mettre la taille ou la position de l'écran? (les deux? si oui comment?).
            Et oui, il y a bien une image géante une plateforme et le personnage (voici une capture d'écran:
            Image utilisateur
            , le jeu est un peu vide car je ne travaille pour l'instant que la mobilité du personnage)
            • Partager sur Facebook
            • Partager sur Twitter
              4 avril 2010 à 10:29:41

              En fait tu ne colles pas ton image d'arrière plan, tu la charges juste en mémoire.
              Ensuite grâce au 2ème argumente de SDL_BlitSurface (c'est un SDL_Rect), tu vas pouvoir dire "affiches moi tel partie de l'image".
              En gros si tu envoies en 2ème argument tel que :
              SDL_Rect p_screen;
              p_screen.x = 30;
              p_screen.y = 60;
              p_screen.h = 480;
              p_screen.w = 640
              
              SDL_BlitSurface(image_geante, p_screen, screen, NULL);
              


              Il va te blitter une partie de l'image, se trouvant aux coordonnées (30,60) et faisant 480px par 640, sur ton écran à la position (0,0) (si tu envoies NULL en dernier argument, il blit en position (0,0)).
              • Partager sur Facebook
              • Partager sur Twitter
                4 avril 2010 à 10:33:56

                D'accord, j'essaie tout de suite (je ne savais pas qu'un sdl_Rect contenait aussi la hauteur et la largeur).

                EDIT: j'ai essayé mais je n'y arrive pas.J'ai recommencé mon projet pour simplifier mon code mais jamais l'ecran ne se positionne de manière a ce que le personnage soit au milieu; je vais te montrer mon main.c (les autres ne devraient pas servir), le voici:
                #include "bouger.h"
                #include "defines.h"
                #include "pause.h"
                
                int main(int argc, char *argv[])
                {
                    SDL_Surface *ecran = NULL, *lara = NULL, *fond = NULL;
                    SDL_Event eventbouger, eventpause;
                    SDL_Rect ecranp, larap, fondp;
                    int continuer = 1;
                
                    fondp.x = 0;
                    fondp.y = 0;
                    fondp.w = 5000;
                    fondp.h = 599;
                
                    larap.x = 500;
                    larap.y = 599 - 394 - 66;
                
                    ecranp.w = 800;
                    ecranp.h = 599;
                    ecranp.x = larap.x - 400;
                    ecranp.y = 0;
                    if(ecranp.x < 0) {ecranp.x == 0;}
                
                
                    enum tournee larat;
                    larat = FACE;
                
                    SDL_Init(SDL_INIT_VIDEO);
                
                    ecran = SDL_SetVideoMode(ecranp.w, ecranp.h, 32, SDL_HWSURFACE | SDL_DOUBLEBUF );
                    SDL_WM_SetCaption(TITRE(), NULL);
                
                    fond = SDL_LoadBMP("images/autres/fond1.bmp");
                    lara = SDL_LoadBMP("images/autres/laraface.bmp");
                    SDL_SetColorKey(lara, SDL_SRCCOLORKEY, SDL_MapRGB(lara->format, 0, 0, 255));
                    SDL_BlitSurface(fond, &ecranp, ecran, &fondp);
                    SDL_BlitSurface(lara, NULL, ecran, &larap);
                
                    SDL_Flip(ecran);
                
                    bouger(lara, fond, ecran, larap, eventbouger, ecranp);// tout ce qui touche a la mobilité
                
                    SDL_BlitSurface(fond, &ecranp, ecran, &fondp);
                    SDL_BlitSurface(lara, NULL, ecran, &larap);
                
                    SDL_Flip(ecran);
                
                    pause(continuer, eventpause); // le programme se met en pause
                
                    return EXIT_SUCCESS;
                }
                
                • Partager sur Facebook
                • Partager sur Twitter
                  5 avril 2010 à 19:56:27

                  S'il vous plait quelqu'un n'aurait pas une solution?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    1 juillet 2010 à 16:29:54

                    Salut Eldunari,
                    je ne sais pas si tu as trouvé la solution à ton problème. Toutefois, on passant par là, j'ai vu que tu cherchais à faire scroller le décors avec la SDL.
                    Ben, voici que justement j'ai proposé un mini - tuto sur le sujet aux administrateurs du site, espérant qu'ils l'approuveront.
                    J'imagine que tu n'as pas de temps à perdre puisque tu crées déjà ton jeu; donc, inutile de te demander d'attendre que mon tuto soit mis en ligne. J'ai donc te montrer en gros comment tu peux parvenir à ton but.

                    Comme tu le sais certainement, la SDL utilise des variables SDL_Rect pour déclarer les coordonnées d'une SDL_Surface, c.-à-d. :

                    les axes X et Y de la fenêtre où sera affichée la sprite, ainsi que la hauteur W et la largeur H (la dimension) de la sprite (image 2D ou SDL_Surface).

                    Si donc tu déclare comme ceci :

                    SDL_Rect coordonnees={0,0, 46, 46};
                    


                    cela signifie que lorsque tu appeleras la fonction SDL_BlitSurface en lui envoyant &coordonnees, la SDL_Surface sera "blittée" dans la fenêtre SDL aux coordonnées (0,0) encadrée par un rectangle invisible (46,46) utile pour la création des collision. Et maintenant, grâce à l'incrementation de coordonnees.x et/ou de coordonnees.y tu pourras simuler un déplacement 2D dans la fenêtre. Tout ça tu le sais.
                    Mais le problème est que la SDL n'autorise pas aux SDL_Surface blittées de sortir du cadre dans lequel elles se trouvent. Cela signifie que : si ta fenêtre mésure 640x480, tu ne pourras jamais directement positionner une SDL_Surface, par exemple, à coordonnees.x=-10 ou coordonnees.x=700 ou coordonnees.y=-10 ou coordonnees.y=500. La vérité est qu'en un fragment de segonde, la surface se trouve bien dans le hors - cadre. Mais elle est "rappelée" dans le cadre automatiquement. Ce qui complique au début ceux qui veulent programmer un jeu 2D avec SDL pour la première fois.
                    Ce que tu dois faire c'est de forcer l'affichage à l'extérieur du cadre. Cela est impératif. Puisque, comme te l'as dit Holt, la surface de ton décors devra être immense (plus grande que ta fenêtre) et tu devras t'arranger pour n'afficher que la partie du décors où l'action se passe.

                    Imagine toi un grand rectangle vert au centre du quel se trouve un autre rectangle mais beaucoup plus petit.

                    Ceci est sensé représenter à l'intérier du grand triangle, la fenêtre SDL et le grand rectangle, la SDL_Surface de ton décors. C'est donc logique de positionner ton décors en une valeur négative. Or cela, La SDL ne le supporte pas. Tu dois donc "tricher".

                    Comment s'y prendre ?

                    commence par déclarer deux variable Uint32, comme ceci :

                    Sint32 x=0, y=0;
                    


                    Ensuite, dans ta boucle (avant l'affichage de ton décors) affecte les valeurs de ces variables aux axes de ton décors, comme ceci :


                    for( ; ; )// Boucle infinie. Attention !!!
                    {
                      coordonnees.x=x; coordonnees.y=y; //Tu les affecte ici avant de blitter
                    
                      SDL_BlitSurfarce( sprite, NULL, ecran, &coordonnees);
                    
                      SDL_Flip( ecran);
                    
                    }
                    


                    Maintenant, si tu changes les valeurs des variables Sint32 grâce au clavier, par exemple, ta SDL_Surface pourra aller partout sur l'axe X et/ sur l'axe Y.

                    Avec ce principe, tu peux afficher n'importe où une SDL_Surface (dans le cadre(la fenêtre SDL ou dans le Hors - cadre).
                    Tu pourrai faire comme tu veux, par exemple :

                    #include <stdio.h>
                    #include <SDL.h>
                    
                    int main( int argc, char**argv)
                    {
                       SDL_Init(SDL_INIT_VIDEO);
                       SDL_Surface*ecran=SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE |
                                                                      SDL_DOUBLEBUF);   
                       
                       SDL_Surface*sprite=SDL_LoadBMP("tonDecors.bmp");//ton décors, par ex: 1280x960
                       Uint32 x=-100, y=-100; //les variables UINT32
                       SDL_Rect decors={x,y, sprite->w, sprite->h};
                       
                       SDL_Surface*personnage=SDL_LoadBMP("lara.bmp");//ton personnage
                       SDL_Rect perso={ecran.x/2, ecran.y/2, personnage.w, personnage.h};
                        
                       SDL_Event evenement;
                        
                       for( ; evenement!=SDL_QUIT; SDL_PollEvent(&evenement)){
                        //Tu dois gérer les événements ici avec switch
                        switch( event.type){
                       case SDL_KEYDOWN : 
                        switch(event.key.keysym.sym){
                        case SDLK_LEFT :  --x; break;
                        case SDLK_RIGHT : ++x; break;
                        case SDLK_UP : --y; break;
                        case SDLK_DOWN : ++y; break;
                        }
                        ;
                      break;
                       }
                       //tu affectes les nvlles valeurs de x et y ici
                        decors.x=x; decors.y=y;
                       //tu blittes ici
                        SDL_BlitSurface( sprite, NULL, ecran, &decors);
                        SDL_BlitSurface( personnage, NULL, ecran, &decors);
                    
                        SDL_Flip(ecran);
                       }
                       
                       SDL_FreeSurface( sprite);
                       SDL_FreeSurface( personnage);
                        return 0; 
                    }
                    


                    Si tu exécutes ce code, tu devrais obtenir une fenêtre SDL affichant une scène où l'on voit ton perso dans un décors qui défile lorsque tu appuies sur les touches HAUT, BAS, GAUHE et DROITE. Ceci est un aperçu, pour te donner l'idée de comment faire du scrolling avec SDL.

                    Bon, je pense que le reste tu pourras t'en sortir, vu que tu programmes tout seul un jeu vidéo !

                    J'espère que ça va t'aider un peu. Il ne reste plus qu'à dire :
                    Mbala sima ebongo oya "Reviens la prochaine fois" (en disant ça à ton problème de "scrolling"

                    PS: Dans mon exemple, j'utilise des images BMP. Faut pas, c'est trop lourd ça. Je pense que tu utlise les formats compréssées (PNG, JPG, ...). C'est mieux.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Mbala'sima ebong'oya
                      2 juillet 2010 à 17:01:33

                      tu as dû remarquer la petite erreur que j'ai glissé dans la la ligne du code où on blitte le personnage. En effet, j'ai écris :

                      //tu blittes ici
                          SDL_BlitSurface( sprite, NULL, ecran, &decors);
                          SDL_BlitSurface( personnage, NULL, ecran, &decors);
                      


                      remplace &decors par &perso.

                      a+
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Mbala'sima ebong'oya
                        30 mars 2015 à 1:30:29

                        errata
                        #include <stdio.h>
                        
                        #include <SDL/SDL.h>
                        
                        int main( int argc, char**argv)
                        
                        {
                        
                           SDL_Init(SDL_INIT_VIDEO);
                        
                           SDL_Surface*ecran=SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE |
                        
                                                                          SDL_DOUBLEBUF);
                        
                           SDL_Surface*sprite=SDL_LoadBMP("tonDecors.bmp");//ton décors, par ex: 1280x960
                        
                           Uint32 x=-100, y=-100; //les variables UINT32
                        
                            //les coordonnées de ton décors sur l'écran, le perso sera affiché au centre de l'écran
                        
                           SDL_Rect decors={x,y, sprite->w, sprite->h};
                        
                           SDL_Surface*personnage=SDL_LoadBMP("lara.bmp");//ton personnage
                        
                            //les coordonnées de ton perso sur l'écran, le perso sera affiché au centre de l'écran
                        
                           SDL_Rect perso={ ecran->w/2 - personnage->w/2, ecran->h/2 - personnage->w/2, personnage->w, personnage->h};
                        
                           for( SDL_Event evenement; evenement.type!=SDL_QUIT&& evenement.key.keysym.sym!=SDLK_ESCAPE; SDL_PollEvent(&evenement)){
                        
                            //remplissage de l'écran d'une couleur ici noir avant d'afficher les images
                        
                            SDL_FillRect(ecran, NULL, SDL_MapRGB( ecran->format, 0,0,0));
                        
                            //Tu dois gérer les événements ici avec switch pour déplacer le background
                        
                            switch( evenement.type){
                        
                           case SDL_KEYDOWN :
                        
                            switch(evenement.key.keysym.sym){
                        
                            case SDLK_LEFT :  --x; break;
                        
                            case SDLK_RIGHT : ++x; break;
                        
                            case SDLK_UP : --y; break;
                        
                            case SDLK_DOWN : ++y; break;
                        
                            }
                        
                            ;
                        
                          break;
                        
                           }
                        
                           //tu affectes les nouvelles valeurs de x et y ici pour forcer le background a "scroller" dans toutes les directions
                        
                            decors.x=x; decors.y=y;
                        
                           //tu blittes ici
                        
                            SDL_BlitSurface( sprite, NULL, ecran, &decors);
                        
                            SDL_BlitSurface( personnage, NULL, ecran, &perso);
                        
                            SDL_Flip(ecran);
                        
                           }
                        
                           SDL_FreeSurface( sprite);
                        
                           SDL_FreeSurface( personnage);
                        
                            return 0;
                        
                        }
                        
                        Et pour les erreurs:
                        
                        main.c: In function ‘main’:
                        
                        main.c:21:23: error: request for member ‘x’ in something not a structure or union
                        
                          SDL_Rect perso={ecran.x/2, ecran.y/2, personnage->w,  personnage->h};
                        
                                               ^
                        
                        main.c:21:34: error: request for member ‘y’ in something not a structure or union
                        


                        • Partager sur Facebook
                        • Partager sur Twitter
                        Mbala'sima ebong'oya
                          18 février 2017 à 17:21:01

                          merci pour le tuto
                          • Partager sur Facebook
                          • Partager sur Twitter
                          l'Humilité précède la Gloire............C'est ça qui est la verité

                          Comment faire un scrolling [SDL]

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown