Partage
  • Partager sur Facebook
  • Partager sur Twitter

Scrolling, tiles, lecture et enregistrement de lvl

    21 avril 2006 à 21:26:35

    Bonjour,

    apres le tp sur mario sodokan, j'ai noté les point que j'avais retenu et ceux pour lequels j'avais besoin d'un autre exemple pour mieu comprendre (disons que le tp était trés guidé, je vais maintenant essayé un truc 100% personnel ou presque)

    j'ai pensé dont revoir les tiles, et la lecture/enregistrement des lvl
    et aussi le scrolling, je suis curieu de savoir comment sa marche

    donc j'ai pensé a un jeux assez courant utilisant un scrolling vertical

    le principe c'est une route qui "descent" et qui retrecit au fur et a mesure
    http://img526.imageshack.us/img526/9417/exemple2om.jpg
    j'espere que vous reconnaitrez le style de jeu lol
    donc j'ai pensé commencé en fesant 3 tiles :

    -herbe (en dehors de la route)
    -bord de la route (ce qu'il ne faut pas touché)
    -entre les bord de la route, la route (la où est la voiture)

    mais je connais pas le scrolling, et si la route diminu, les tiles vont etre reduit, non?

    qel serai la maniere la plus simple de faire ce jeu en apprenant au moins le scrolling svp?

    merci

    ++

    edit : pendant que j'y suis, est ce que vous pouriez m'expliqué comment faire un saut comme dans mario ou les jeux de jongle (quand on clic sur la balle elle rebondi)
    • Partager sur Facebook
    • Partager sur Twitter
      22 avril 2006 à 2:15:20

      je ne vais pas me lancer dans une explication bidon de tes premieres questions que tu te poses, car je n'ai pas les connaissances necessaires. (Jamais pratiqué ce genre de truc)

      Mais pour ta derniere question, un simple saut, c'est seulement une histoire de modification de coordonné. Tu fais une bloucle dans laquel tu changes les coordonnées, puis tu affiche l'image à une nouvelle coordonné, puis tu change encore les coordonnée, puis tu réafiches, etc. Et la boucle continu jusqu'à ce que ton perso n'a pas touché le sol.

      Bon alors pour ça, t'as 3 solutions (d'apres moi)

      1) la solution bête et bourine: tu fais une premiere boucle qui fait monter ton perso jusqu'à la hauteur que tu veux. Puis ensuite tu refais une boucle qui fait dessendre ton perso, et celle ci s'arette quand ton perso touche le sol

      2) la solution qui a le meilleur raport réalisme/temps d'éxecution: tu cherches une fonction mathématique don le graph a la forme qui corespond le mieux à ce que tu veux (un truc qui monte et qui redessent), j'sais pas genre une fonction polynomial du second degré.

      3) la solution la plus réaliste, mais qui, je pense, doit ralentir beaucoup le programme, c'est de programmer ce que j'appel un "moteur physique" (j'appel ça un moteur physique, mais si ça se trouve un vrai moteur physique ce n'est pas ça du tout, je n'ai aucune connaissance en moteur physique).
      Alors là tu fais des fonctions qui calcul des phénomes physique: chute, rebond. Si tu entres en parametres les diferentes accelerations qui s'appliquent sur ton bonhomme, ou les diférentes forces, ça te calcul sa vitesse, et ses coordonnées.
      • Partager sur Facebook
      • Partager sur Twitter
        22 avril 2006 à 18:48:16

        Salut.

        Pour le scrolling vertical, j'ai un peu cogité sur la question et je suis arrivé à ceci:
        /*
        main.c

        programme: scroll-vert
        objectif : faire un scrolling vertical, genre "jeu de voiture"
        date     : 22avr2006 jmb, sdz
        */


        #include <stdlib.h>
        #include <stdio.h>
        #include <time.h>
        #include <SDL/SDL.h>

        // Dimensions en sprite => taille de fenetre
        #define TAILLE_SPRITE 12
        #define NB_SPRITES_LARGEUR 30
        #define NB_SPRITES_HAUTEUR 50


        // Pour changer le profil de la route, on va choisir une valeur entre 0 et 100
        // et faire un 0/+1/-1 sur la position des bords en fonction de cette valeur
        #define ON_CHANGE_PAS  60  // entre 0 et 59, on change rien
        #define PLUS_DIFFICILE 85  // de 61 à 84 la route va rétrécir
                                   // de 85 à 99 la route va s'élargir

        #define LARGEUR_MINI NB_SPRITES_LARGEUR/4    // Largeur minimale de la route

        // Retourner un nombre choisi entre deux bornes
        int pifometre(int mini, int maxi)
        {
                return (rand() % (maxi-mini+1))+mini;
        }

        // Convertir une valeur entre 0 et 100 en 0, +1 ou -1 (variation de la route)
        int estimerDecalage(int valeur)
        {
            int resultat;

            if(valeur<ON_CHANGE_PAS)
                resultat=0;
            else if(valeur<PLUS_DIFFICILE)
                resultat=1;
            else
                resultat=-1;

            return resultat;
        }

        // Programme principal
        int main(int argc, char *argv[])
        {
            // Déclarations SDL standards
            SDL_Surface *ecran=NULL, *route=NULL, *bordure=NULL, *champ=NULL;
            SDL_Rect position;
            SDL_Event event;

            // Alias pour les sprites
            enum {ROUTE,BORDURE,CHAMP};

            // Tableau de pointeur de sprites pour simplifier le blittage
            SDL_Surface *ptrSurf[3];

            // Tableau 2D pour memoriser la route
            int piste[NB_SPRITES_HAUTEUR][NB_SPRITES_LARGEUR]={ROUTE};

            // Variables pour génération de la route
            int positionBordGauche=3;
            int positionBordDroit=NB_SPRITES_LARGEUR-6;

            // Variables diverses
            int ligneAGenerer=0;
            int indexLigneDuBas=0;
            int continuer=1;
            int i,j;

            // Initialisation de la SDL
            SDL_Init(SDL_INIT_VIDEO);

            // Chargement des sprites (SDL_LoadBMP...)
            route=SDL_CreateRGBSurface(SDL_HWSURFACE,TAILLE_SPRITE,TAILLE_SPRITE,32,0,0,0,0);
            bordure=SDL_CreateRGBSurface(SDL_HWSURFACE,TAILLE_SPRITE,TAILLE_SPRITE,32,0,0,0,0);
            champ=SDL_CreateRGBSurface(SDL_HWSURFACE,TAILLE_SPRITE,TAILLE_SPRITE,32,0,0,0,0);
            SDL_FillRect(route, NULL, SDL_MapRGB(route->format, 128, 128, 128));
            SDL_FillRect(bordure, NULL, SDL_MapRGB(bordure->format, 255, 128, 64));
            SDL_FillRect(champ, NULL, SDL_MapRGB(champ->format, 128, 255, 128));

            // Mise à jour du tableau de pointeur de sprites
            ptrSurf[ROUTE]=route;
            ptrSurf[BORDURE]=bordure;
            ptrSurf[CHAMP]=champ;

            // Démarrer le générateur pifométrique
            srand(time(NULL));

            // Ouverture de la fenêtre avec titre
            ecran=SDL_SetVideoMode(TAILLE_SPRITE*NB_SPRITES_LARGEUR, TAILLE_SPRITE*NB_SPRITES_HAUTEUR, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
            SDL_WM_SetCaption("Scrolling vertical",NULL);

            // Boucle principale (enfin !)
            while(continuer)
            {
                // Gestion des événements
                SDL_PollEvent(&event);
                switch(event.type)
                {
                    case SDL_QUIT:
                        continuer=0;
                        break;

                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym)
                        {
                            case SDLK_ESCAPE:
                                continuer=0;
                                break;
                        }
                        break;
                }

                // Générer une nouvelle ligne
                indexLigneDuBas++;
                if(indexLigneDuBas==NB_SPRITES_HAUTEUR)
                    indexLigneDuBas=0;

                ligneAGenerer=indexLigneDuBas-1;
                if(ligneAGenerer<0)
                    ligneAGenerer=NB_SPRITES_HAUTEUR-1;

                // Calcul décalage des bords
                positionBordGauche+=estimerDecalage(pifometre(0,100));
                positionBordDroit-=estimerDecalage(pifometre(0,100));

                // Ne pas défoncer les cotés gauche et droit
                if(positionBordGauche<0)
                    positionBordGauche=0;

                if(positionBordDroit==NB_SPRITES_LARGEUR)
                    positionBordDroit=NB_SPRITES_LARGEUR-1;

                // Ménager une largeur minimale pour la route LOGIQUE A VERIFIER
                if(positionBordDroit-positionBordGauche==LARGEUR_MINI-1)
                    if(positionBordGauche<=1)
                        positionBordDroit+=2;
                    else
                        positionBordGauche-=2;

                if(positionBordDroit-positionBordGauche==LARGEUR_MINI)
                    if(positionBordGauche==0)
                        positionBordDroit++;
                    else
                        positionBordGauche--;

                // Remplir la ligne
                for(i=0; i<NB_SPRITES_LARGEUR; i++)
                {
                    if(i<positionBordGauche)
                        piste[ligneAGenerer][i]=CHAMP;
                    else if(i==positionBordGauche)
                        piste[ligneAGenerer][i]=BORDURE;
                    else if(i<positionBordDroit)
                        piste[ligneAGenerer][i]=ROUTE;
                    else if(i==positionBordDroit)
                        piste[ligneAGenerer][i]=BORDURE;
                    else
                        piste[ligneAGenerer][i]=CHAMP;
                }

                // Blit-Time, Yeah !
                for(j=0; j<NB_SPRITES_HAUTEUR; j++)
                {
                    if(j<indexLigneDuBas)
                        position.y=(indexLigneDuBas-j-1)*TAILLE_SPRITE;
                    else
                        position.y=(NB_SPRITES_HAUTEUR+indexLigneDuBas-j-1)*TAILLE_SPRITE;

                    for(i=0; i<NB_SPRITES_LARGEUR; i++)
                    {
                        position.x=i*TAILLE_SPRITE;
                        SDL_BlitSurface(ptrSurf[piste[j][i]],NULL,ecran,&position);
                    }
                }

                // Mise à jour de l'affichage
                SDL_Flip(ecran);
                sleep(50);
            }

            // Nettoyage de la place
            SDL_FreeSurface(ecran);
            SDL_FreeSurface(route);
            SDL_FreeSurface(bordure);
            SDL_FreeSurface(champ);
            SDL_FreeSurface(ptrSurf);
        }


        C'est évidement améliorable, mais en gros ma façon de faire c'est d'avoir un tableau comme dans le cours de M@teo, et de changer une ligne à chaque tour de "while(continuer)".
        Plutôt que de copier chaque ligne dans la suivante pour faire un scrolling, j'ai juste un index qui change, et je blitte suivant 2 cas. o_O
        Bon, mettons un tableau de 50 lignes, si celle du bas c'est la ligne 18, alors je blitte de 18 à 50, puis de 0 à 17.
        Ensuite j'incrémente l'index et on recommence.

        Bon, euh, si ça t'interesse, je vais essayer de trouver une façon d'expliquer ça plus clairement... :-°
        • Partager sur Facebook
        • Partager sur Twitter
          22 avril 2006 à 20:48:17

          pour le saut 'jai essayé

          if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_SPACE)
                   {
                       Sleep(5);
                    for (i=0 ; i<50 ; i++) {
                        rect1.y-=1;
                        Sleep(10);
                        SDL_BlitSurface(balle,NULL,screen,&rect1);     
                                  }             
                   for (i=0 ; i<50 ; i++) {
                        rect1.y+=1;
                        Sleep(10);
                        SDL_BlitSurface(balle,NULL,screen,&rect1);
                                  }             
                   }   


          mais les sleep sont ignoré
          en le mettant au debut du programme, ca marche mais le saut ne se voit pas

          j'ai oublié un truc ? (j'ai bien pensé a inclure windows.h, la fonction pour recuperé le prochain evenement ainsi que ce code dans une boucle infini)
          • Partager sur Facebook
          • Partager sur Twitter
            22 avril 2006 à 20:52:44

            Ca marche pas car tu réaffiches pas, puis c'est pas le bon principe.

            Bye bye Sleep, bonjour SDl_Delay.

            A revoir : le principe d'une animation.
            Touche : met un booleen à vrai
            Dans la boucle bouge si c'est vrai. Au bout d'une certaine hauteur, change le sens.
            Pour faire des mouvements qui dépendent du temps écoulé utilsie SDL_GetTicks
            Tu peux voir un code de mouvement qui dépend du temps ici :
            http://www.siteduzero.com/tuto-3-6386-1-enfin-de-la-3d-partie-2-2.html#ss_part_3 , à toi d'adapter.
            • Partager sur Facebook
            • Partager sur Twitter
              22 avril 2006 à 20:58:45

              ok merci je vais voir cette page (d'ailleur j'ai edité mon code en haut en meme temps que ton post lol), sinon j'avais oublié d'effacé l'ancienne position de la balle, ca fait deja ca de trouvé lol

              edit : j'avais l'impression d'avancé, mais j'ai arretté car je commencé plutot a reculé lol, je vais essayé de revoir ca demain ou + tard ce soir

              actuelement la balle se deplace en continu et trop rapidement, comme si elle etait dans une boucle infini, or le if n'est valable que si la touche espace est appuyé, donc je comprend pas
              je vais essayé de voir ca differement

              ensuite, quand il n'y a pas ce deplacement continu, la balle se deplace instantannément
              en clair, pas de mouvement, elle reste a la meme place puisqu'elle monte puis redescent, donc trop rapide pour l'ecran, pas de saut

              dés que j'aurai compris pourquoi, je pourais avancé

              apres autre probleme, pour supprimé les anciennes position successif de la balle, donc je recopie le fond d'ecran avant de recopié la balle a l'ecran
              mais lorsque je fait ca, je ne vois meme plus la balle (qui est pourtant bien collé sur l'arriere plan et pas derriere)

              voila tout ce que j'ai a resoudre avant de passé aux problemes suivant XD

              • Partager sur Facebook
              • Partager sur Twitter
                23 avril 2006 à 11:50:05

                pas encore retourné dans mon saut pour le moment, c'est juste pour dire que j'ai testé le scrolling, c'est impec ce qu'il me fallais

                j'vais regardé ce que tu a fait et adapté, merci gpa
                • Partager sur Facebook
                • Partager sur Twitter

                Scrolling, tiles, lecture et enregistrement de lvl

                × 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