Programme Trop Lent

Résolu
Lemng Messages postés 31 Date d'inscription mardi 3 juillet 2007 Statut Membre Dernière intervention 4 mai 2009 - 2 janv. 2009 à 23:40
cs_stephane57 Messages postés 12 Date d'inscription lundi 17 décembre 2007 Statut Membre Dernière intervention 6 janvier 2009 - 6 janv. 2009 à 22:22
Bonjour tout le monde,

voici mon problème : j'utilise la SDL pour programmer un jeu se jouant a l'aide du clavier et de la souris de la manière suivante : vous, le héros êtes au beau milieu d'un niveau plus grand que l'écran et remplit d'ennemi. Lorsque vous vous approchez d'eux ils vous tirent dessus et vous voyez votre vie descendre. Pour les tuer vous devez cliquer dessus. Je suis assez fier de mon jeux qui incorpore un menu en jeu donnant divers information comme votre vie et vos dégats ou encore votre position sur une mini carte.
Cependant, depuis peu j'ai un gros problème de rapidité. Je ne sais pas a quoi cela est du. Voici la structure de mon programme(seulement l'essentiel)
Tout d'abord j'ai créé des structures ennemis et des structures personnage, un SDL_Rect qui sert de camera pour le scrolling et un tableau d'ennemi, histoire de gerer tout les ennemis a l'aide de ce tableau.

j'arrive ensuite a une boucle des évenements écrite ainsi:

     SDL_Event event;                //variable pour les evenements
     bool continuer = true;
     int oldTime = 0;
     int now = 0;
     int clike = 0;
     while(continuer)
     {
       now = SDL_GetTicks();
       if(now-oldTime >= 20)                    //pour limiter le nombre de fps
       {
       afficherTout(ecran, adversaires, personnage, Camera);         
      //fonction qui parcourt le tableau d'ennemis, les blittes

       IA(ecran, adversaires, &personnage, Camera);
      //fonction qui parcourt le tableau d'ennemi et fait tirer ceux qui sont proche

       afficherMenu(ecran, adversaires, personnage, Camera);
      //tout est dans le nom
       SDL_Flip(ecran);
       SDL_PollEvent(&event);
       switch(event.type)
       {
          case SDL_QUIT:
               continuer = false;
               break;
          case SDL_KEYDOWN:
               if(event.key.keysym.sym == SDLK_UP && Camera.y > 0)
                  Camera.y -= 5;
               else if(event.key.keysym.sym == SDLK_RIGHT && Camera.x < 1000-Camera.w)
                  Camera.x += 5;
               else if(event.key.keysym.sym == SDLK_DOWN && Camera.y < 1000-Camera.h)
                  Camera.y += 5;
               else if(event.key.keysym.sym == SDLK_LEFT && Camera.x > 0)
                  Camera.x -= 5;
               break;
               //ci dessus : les mouvements
          case SDL_MOUSEBUTTONDOWN:
               if(500+206 > event.button.x && event.button.x > 500+10)
               {
                 if(464 > event.button.y && event.button.y > 413)
                   return;      //si on a cliqué sur le bouton quitter du menu, on quitte
               }
               clike = clik(adversaires, event.button.x, event.button.y, Camera);            
              //test pour voire si on tue des ennemi
               if(clike != -1)
                  adversaires[clike].PointDeVies -= personnage.Degats;
               break;          
       };
       }      
     }

D'autres part, j'ai vérifié que je libérais toutes les surfaces après les blits. Et je ne pense pas avoir abusé sur le nombre d'ennemis(5) ni la taille du niveau (1000*1000 dans une fenetre de 500*500).

J'ai entendu parlé de probleme de lenteur avec la SDL. Si la SDL ne sait plus suivre pour un tel programme indiquez moi d'autres bibliothèques 2d un peu plus rapides.

Merci de m'avoir accordé du temps et a bientôt.

8 réponses

cs_stephane57 Messages postés 12 Date d'inscription lundi 17 décembre 2007 Statut Membre Dernière intervention 6 janvier 2009
6 janv. 2009 à 22:22
De rien et bonne continuation ;-)

Ne pas oublier de mettre la question comme résolue stp dans le forum.
3
Pistol_Pete Messages postés 1053 Date d'inscription samedi 2 octobre 2004 Statut Membre Dernière intervention 9 juillet 2013 7
4 janv. 2009 à 13:22
Salut
Je ne connais pas bien la SDL mais voici un petit test que tu peux faire:
Calcul le temps d'exécution de chaque fonction: afficherTout, IA, AfficherMenu etc... et regarde laquelle de ces fonction te bouffe le plus de temps et tu pourras cerner mieux ton problème je pense.
Donne nous les temps moyen d'exécution ainsi que le code de la fonction la plus "consommatrice" et on verra mieux ce qu'il faut faire.
A+
________________________________________________________________________________
Mon site internet :   http://ImAnalyse.free.fr
0
cs_stephane57 Messages postés 12 Date d'inscription lundi 17 décembre 2007 Statut Membre Dernière intervention 6 janvier 2009
4 janv. 2009 à 19:24
salut, j'ai lu ton petit bout de code

ta lenteur semble venir de la façon dont tu gères le temps avec les FPS  avec SDL_GetTicks().

tu écris:
....

    if(now-oldTime >= 20)                    //pour limiter le nombre de fps
       {
       afficherTout(ecran, adversaires, personnage, Camera);         
      //fonction qui parcourt le tableau d'ennemis, les blittes

       IA(ecran, adversaires, &personnage, Camera);
      //fonction qui parcourt le tableau d'ennemi et fait tirer ceux qui sont proche

...

ce n'est pas bon du touttttttttttttttttt.

en effet en mettant un if, tu obliges le programme à attendre jusqu'à 20 sans rien faire !!! d'où la perte de temps.

La solution:

D'ABORD tu dois afficher tout, tu gère l' intelligence artificielle etc etc etc etc
et seulement APRES tu demandes au programme d'attendre jusqu'à ce qu'une certaine valeur entre l'ancien temps et le nouveau temps soit atteinte (pour avoir un affichage constant en nombres de cycles, quel que soit le processeur et le nombres d'actions effectuées à un moment ou à un autre de ton jeu)

voilà bon courage.
0
Lemng Messages postés 31 Date d'inscription mardi 3 juillet 2007 Statut Membre Dernière intervention 4 mai 2009
4 janv. 2009 à 20:31
Merci pour toutes vos réponse. D'abord pour ce qui est de ma fonctio la plus longue voici les temps
afficherTout() : 41
IA() : 2
afficherMenu() : 29
Et le code de ma fonction afficherTout():
void afficherTout(SDL_Surface* ecran, Ennemi adversaires[], Hero personnage, SDL_Rect Camera)
{
     SDL_Rect posBlit;
     SDL_Surface *niveau = IMG_Load("herbe.png");
     SDL_Surface *ennemi = IMG_Load("EnnemiRouge.png");
     SDL_SetColorKey(ennemi, SDL_SRCCOLORKEY, SDL_MapRGB(ennemi->format, 255, 255, 255));
     SDL_Surface *hero = IMG_Load("Hero.png");
     SDL_SetColorKey(hero, SDL_SRCCOLORKEY, SDL_MapRGB(hero->format, 255, 255, 255));
     SDL_BlitSurface(niveau, &Camera, ecran, NULL);
     SDL_FreeSurface(niveau);
     int i=0;
     for(i=0;i<NOMBRE_ENNEMI;i++)
     {
       if(adversaires[i].X > Camera.x && adversaires[i].X + adversaires[i].W < Camera.x+Camera.w && adversaires[i].PointDeVies > 0)
       {
        if(adversaires[i].Y > Camera.y && adversaires[i].Y + adversaires[i].H < Camera.y+Camera.h)
        {
         posBlit.x = adversaires[i].X - Camera.x;
         posBlit.y = adversaires[i].Y - Camera.y;
         SDL_BlitSurface(ennemi, NULL, ecran, &posBlit);
         }
       }
     }
     SDL_FreeSurface(ennemi);
     posBlit.x = Camera.w/2 - personnage.W/2;
     posBlit.y = Camera.h/2 - personnage.H/2;
     SDL_BlitSurface(hero, NULL, ecran, &posBlit);
     SDL_FreeSurface(hero);
}

Pour ce qui est de ma façon de gérer les fps, je ne pense pas que ce soit la cause de la lenteur : même en enlevant la gestion des fps(pas de limitation) ou en faisant SDL_Delay(20-(oldTime-now)), pour ne pas boucler dans le vide, le résultat est le même : ca lague. D'autre part je peut aussi affirmer que les ralentissement apparaissent le plus souvent lors de l'utilisation du clavier et de la souris en même temps (tirer sur un ennemi et bouger en même temps).
Merci pour votre aide.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_stephane57 Messages postés 12 Date d'inscription lundi 17 décembre 2007 Statut Membre Dernière intervention 6 janvier 2009
4 janv. 2009 à 20:40
pour ta fonction d'affichage  AfficherTout, il y a une perte de temps considérable ici:

     SDL_Surface *niveau = IMG_Load("herbe.png");
     SDL_Surface *ennemi = IMG_Load("EnnemiRouge.png");
     ...
     SDL_Surface *hero = IMG_Load("Hero.png");

à chaque rafraîchissement, tu refais une lecture de chacun des fichiers contenant les images. Grosses pertes des capacités!

il faut stocker tes surfaces avant la boucle principale du jeu
et les libérer après la boucle principale du jeu
0
Lemng Messages postés 31 Date d'inscription mardi 3 juillet 2007 Statut Membre Dernière intervention 4 mai 2009
5 janv. 2009 à 18:30
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci  de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.
0
Lemng Messages postés 31 Date d'inscription mardi 3 juillet 2007 Statut Membre Dernière intervention 4 mai 2009
5 janv. 2009 à 18:30
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci  de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.
0
Lemng Messages postés 31 Date d'inscription mardi 3 juillet 2007 Statut Membre Dernière intervention 4 mai 2009
5 janv. 2009 à 18:31
Merci beaucoup stephane 57, tu as trouvé le problème. En passant les images comme arguments voici les temps :
afficherTout : 8
IA : 2
afficherMenu : 6
ya pas photo :) .
Merci  de m'avoir aider, la prochaine fois je ferais plus attention. Je vais poster mon jeu comme source, n'hésite pas à aller la voir.
0
Rejoignez-nous