Partage
  • Partager sur Facebook
  • Partager sur Twitter

jeu qui ralentit au fil du temps

problème d'animation

    24 février 2018 à 2:02:02

    Bonsoir,

    Je suis actuellement en train de coder un jeu assez connu sous le nom de "fish" en C avec la SDL, où il faut manger des poissons plus petits que nous pour grossir (comme agar.io au final mais sans les cercles :) ). J'ai décidé d'animer les poissons en utilisant des sprites sur un site qui en vend (j'ai pris les gratuits). En gros, le jeu commence avec notre poisson qui apparait au milieu de l'écran, et plusieurs poissons apparaissent au fil du temps, de taille variable et proportionnelle à celle de notre poisson (qui peuvent être jusqu'à 1.5 fois plus gros).

    capture d'écran du jeu

    (un petit apperçu du jeu ;) )

    J'ai donc réfléchi longuement à un problème ; comment faire grossir le poisson que j'ai (et donc faire grossir ses animations) pendant le jeu ?

    J'ai pensé à SDL_gfx, puisque l'on peut zoomer avec.

    Mais j'ai rencontré un problème qui m'a amené à poster ce sujet : lorsque les poissons sur la map sont plus gros, les animations se font moins rapidement ... pourquoi ? est-ce dû au fait que blitter des images plus grosses est plus long ou est-ce mon code ? 

    Voilà le bout de code qui traite l'évolution et l'animation (l'animation n'est pas encore dans une fonction pour que vous puissiez voir comment j'ai fait)

        //INITIALISATION
    
    
        SDL_Event event;
        while (continuer == 1)
        {
            SDL_PollEvent(&event);
            switch(event.type)
            {
                case SDL_QUIT:
                    continuer = -1;
                    break;
    
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_ESCAPE:
                            continuer = -1;
                            break;
    
                        //...déplacement
                    }
                    break;
    
                case SDL_KEYUP:
                    switch (event.key.keysym.sym)
                    {
                        //...déplacement
                    }
                    break;
            }
    
            //avant que l'on rentre dans le code problématique, quelques infos :
            //la structure "monAnim" et "adversaires" comportent tout ce qui est sprites, tailles, positions, ... des poissons (du notre pour monAnim et des adversaires pour l'autre)
            //tempsMaintenant et tempsPrecedent sont juste des int pour pouvoir calculer les fps (pareil pour lastTime et newTime, je sais pas trop pourquoi j'ai fait 2 variables mais c'est pas le problème xD)
            //ecran et fond sont des SDL_Surface *
            //et après je crois que c'est plutôt clair ; si y'a un truc que vous comprenez pas, demandez moi
    
            tempsMaintenant = SDL_GetTicks();
    
            if(tempsMaintenant - tempsPrecedent > 1000/FPS && continuer==1)   //réglage des FPS
            {
                update(&monAnim); //là je mets à jour les poissons ( pour les déplacements)
                for(i=0;i<NB_ADVERSAIRES_MAX;i++)//pour chaque poisson qui existe
                    if(adversaires[i].vivant==1)//et qui soit vivant
                        updateAdv(&adversaires[i]);//j'update differement, je les fais se déplacer aléatoirement
    
    
                clipper.x = monAnim.oldPos.x;   //là j'utilise la technique du clipper pour optimiser mes animations _ ici c'est celui du poisson du joueur
                clipper.y = monAnim.oldPos.y;
                clipper.h = monAnim.animsEntite[monAnim.etat].taille_Y;
                clipper.w = monAnim.animsEntite[monAnim.etat].taille_X;
    
                SDL_SetClipRect(ecran,&clipper);
    
                positionFond.x = 0;
                positionFond.y = 0;
    
                SDL_BlitSurface(fond, NULL, ecran, &positionFond);
    
                SDL_SetClipRect(ecran,NULL);
    
                monAnim.oldPos.x = monAnim.position.x;
                monAnim.oldPos.y = monAnim.position.y;
    
    
                //...j'affiche aussi le score avec un autre clipper
    
                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                {
                    if(adversaires[i].vivant==1)    //je fais le clipper pour tous les autres poissons ennemis sur la map
                    {
                        clipper.x = adversaires[i].oldPos.x;
                        clipper.y = adversaires[i].oldPos.y;
                        clipper.h = adversaires[i].animsEntite[adversaires[i].etat].taille_Y;//ça faut pas en avoir peur, c'est juste la taille en pixel du poisson en question (parce que j'ai plusieurs sortes de poissons)
                        clipper.w = adversaires[i].animsEntite[adversaires[i].etat].taille_X;
    
                        SDL_SetClipRect(ecran,&clipper);
    
                        positionFond.x = 0;
                        positionFond.y = 0;
    
                        SDL_BlitSurface(fond, NULL, ecran, &positionFond);
    
                        SDL_SetClipRect(ecran,NULL);
                        adversaires[i].oldPos.x=adversaires[i].position.x;
                        adversaires[i].oldPos.y=adversaires[i].position.y;
                    }
                }
    
                //(les clippers servent à "effacer" les poissons de l'écran et éviter d'effacer tout l'écran et réafficher un a un les poissons (+le fond + les scores ... bref ))
    
    
                SDL_BlitSurface(monAnim.animsEntite[monAnim.etat].anim[monAnim.animActuelle],NULL,ecran,&monAnim.position); //je blitte notre poisson
                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                    if(adversaires[i].vivant==1)
                        SDL_BlitSurface(adversaires[i].animsEntite[adversaires[i].etat].anim[adversaires[i].animActuelle],NULL,ecran,&adversaires[i].position);//et là les autres
    
    
                SDL_BlitSurface(texte, NULL, ecran, 0); //là c'est juste le score
    
    
                SDL_Flip(ecran);
    
    
                //là ça serait la fin de la fonction affichage
    
    
    
    
    
                monAnim.tempsActuel = SDL_GetTicks();
    
                if(monAnim.tempsActuel - monAnim.tempsPasse > monAnim.temps)  //changement d'anim pour notre poisson
                {
                    if(monAnim.animActuelle+1<monAnim.animsEntite[monAnim.etat].anims_totales)
                        {monAnim.animActuelle++;}
                    else
                        {monAnim.animActuelle=0;}
                    monAnim.tempsPasse = monAnim.tempsActuel;
                }
    
    
                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                {
                    if(adversaires[i].vivant==1)
                    {
                        adversaires[i].tempsActuel = SDL_GetTicks();
    
                        if(adversaires[i].tempsActuel - adversaires[i].tempsPasse > adversaires[i].temps)  //changement d'anim pour tous les autres
                        {
                            if(adversaires[i].animActuelle+1<adversaires[i].animsEntite[adversaires[i].etat].anims_totales)
                                {adversaires[i].animActuelle++;}
                            else
                                {adversaires[i].animActuelle=0;}
                            adversaires[i].tempsPasse = adversaires[i].tempsActuel;
                        }
                    }
                }
    
    
                continuer = verification(&monAnim,adversaires,ecran);//je vérifie ce qui se passe. le "continuer =" c'est parce que cette fonction renvoit 1 pour "il ne s'est rien passé" et des valeurs différentes sinon. Et ce continuer est
                tempsPrecedent = tempsMaintenant;
    
            }
            else if (continuer==1)
            {
                    SDL_Delay((1000/FPS)-(tempsMaintenant-tempsPrecedent)); //FPS
            }
        }
    
        //FIN DU JEU
    

    Je suis désolé de mettre 150 lignes :/

    J'ai fait de mon mieux pour commenter et pour résumer, mais si vous ne comprenez pas quelque chose demandez moi.

    Au final, dès que les poissons sont un peu plus gros que la base, le jeu commence à ralentir et j'ai aussi remarqué qu'il prenait de plus en plus de CPU à chaque fois que tout le monde grossissait ......

    Bref, j'espère que quelqu'un pourra m'aider !

    Cordialement,

    Un petit geek





    EDIT : en fait, ça ne bug pas, c'est seulement que les animations sont moins fluides .... je suis désolé d'avoir posté ce sujet inutile xD est-ce que en attendant quelqu'un d'expérimenté pourrait me dire s'il y a des choses incohérentes dans mon code ? et après je mettrai en résolu ;) 

    -
    Edité par Diablo-hell 24 février 2018 à 2:19:43

    • Partager sur Facebook
    • Partager sur Twitter
      24 février 2018 à 11:00:56

      Bonjour, 

      Ligne 91: perdu: il est plus rapide d'effacer l'écran(disons de blitter le fond d'écran) puis de blitter ensuite chacun de tes poissons!

      (Pareil ligne 54 je présume!, pas bon du tout!)

      -
      Edité par breizhbugs 24 février 2018 à 11:05:37

      • Partager sur Facebook
      • Partager sur Twitter
      ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
        24 février 2018 à 11:14:12

        Bonjour,

        Tu devrais passer à la SDL 2.0 , le 'blittage' y est beaucoup plus rapide, et la gestion des touches du clavier est plus en adéquation avec ce qui existe (disons plus universelle). Voici un tutoriel sur la SDL 2.x : https://zestedesavoir.com/tutoriels/1014/utiliser-la-sdl-en-langage-c/

        -
        Edité par Warren79 25 février 2018 à 9:59:17

        • Partager sur Facebook
        • Partager sur Twitter

        Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

          24 février 2018 à 12:41:25

          Salut,

          Je rajoute que tu utilises mal SDL_PollEvent qui doit être placé dans une boucle (je te laisse faire une petite rechercher à ce sujet).

          • Partager sur Facebook
          • Partager sur Twitter
          Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
            24 février 2018 à 14:25:19

            Bonjour,

            Merci à vous, je vais changer ça :) j'ai toujours pensé que les clippers étaient plus rapides et plus efficaces ... 

            Je vais mettre la SDL2 :) est-ce que cela change beaucoup de chose à la 1 ? je veux dire est-ce que je vais devoir reprendre tout mon code ?

            mon SDL_PollEvent  est placé dans la boucle while comme ceci 

            while (continuer == 1)
            {
                SDL_PollEvent(&event);

            Ce n'est pas ce qu'il faut faire ? j'avais effectivement vu plusieurs personnes le mettre dans une fonction à part et l'appeler à chaque boucle ...

            Merci pour vos réponses en tout cas !

            • Partager sur Facebook
            • Partager sur Twitter
              24 février 2018 à 15:55:49

              Bonjour,

              Il faut tester le retour de SDL_PollEvent() (avec un while pour dépiler tout)  une bonne structure est ainsi :

              Init();			 // Chargement des surfaces
              
              while (continuer)
              {
                  while (SDL_PollEvent(&event))
                  {
                      switch(event.type)  // Traitement des évènements
                      {
                        // ..
                      }
                  }
              
                  Actualisation();	// Mise à jour des positions en fonction du traitement des évènements
                  Affichage();	// Blit puis Flip
                  GesFrame();		// Gestion du nombre d'affichages / seconde
              
              }
              
              Fin();			// Free, Quit ...



              • Partager sur Facebook
              • Partager sur Twitter
              Architecture SDL                     Multithreading         
                24 février 2018 à 16:31:51

                léovendeville a écrit:

                [...]

                Je vais mettre la SDL2 :) est-ce que cela change beaucoup de chose à la 1 ? je veux dire est-ce que je vais devoir reprendre tout mon code ?

                [...]

                Avec la SDL 2.0 le plus courant est d'utiliser le type 'SDL_Renderer' sous forme de pointeur pour y coller des SDL_Texture (elles aussi sous forme de pointeurs). Les SDL_Surface* sont utilisés comme intermédiaire entre les textures sous forme de fichiers sur un support de stockage (fichiers png ou bmp, etc..) et les SDL_Texture* qui sont stockés la plupart du temps dans la mémoire de la carte graphique.

                Tu verra tout ça si tu suis le tuto que j'ai mis en lien. Utiliser la SDL2 n'est pas plus compliqué que la SDL1.2 , il y a toujours des bonnes pratiques comme vérifier que la SDL a bien été initialisée, les textures ont été correctement chargées, etc...

                • Partager sur Facebook
                • Partager sur Twitter

                Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

                  24 février 2018 à 21:59:32

                  D'accord ! merci à vous deux.

                  Je vais suivre vos conseil et modifier tout ça ;)

                  Et merci picosoft, je ne savais pas, il me semblait (d'après le tuto en C d'openclassroom) que j'avais juste :p

                  Bonne soirée !

                  -
                  Edité par Diablo-hell 24 février 2018 à 21:59:40

                  • Partager sur Facebook
                  • Partager sur Twitter
                    25 février 2018 à 10:39:19

                    Warren79 a écrit:

                    [...]Les SDL_Surface* sont utilisés comme intermédiaire entre les textures sous forme de fichiers sur un support de stockage (fichiers png ou bmp, etc..) [...]

                    Plutôt inexact. En fait les SDL_Surface sont en RAM et ne sont tout simplement plus utiles en SDL 2 à une ou deux exceptions près. Pour l'instant la seule raison (presque) valable d'utiliser une SDL_Surface (que j'aie pu trouver) est qu'il est dangereux de créer une texture dans un thread, donc j'en sort une surface à convertir en texture dans le programme principal... Et encore, le thread pourrait sortir un RWops (virtualisation de fichier) et ensuite en extraire directement une texture. Oui, SDL_img() charge des surfaces et passe par la conversion surface -> texture, mais ce n'est pas notre problème.

                    Ceci dit, SDL_Gfx() est très clairement très lent et peut vite plomber le fps d'un jeu.

                    Passer de la SDL1 à la 2 peut prendre un peu de temps surtout si tu codes tout dans ton main. Bien lire la doc, il y a quelques changements au-delà des surfaces/textures. Notamment les entrés qui passent de keysym à scancode, vu ce que tu veux en faire... Au moins, il sera possible d'abandonner SDL_Gfx() et d'avoir des transformations "natives" d'une rapidité fulgurante.

                    Bonne continuation.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Bonhomme !! | Jeu de plateforme : Prototype.

                      25 février 2018 à 17:27:24

                      drx a écrit:

                      Warren79 a écrit:

                      [...]Les SDL_Surface* sont utilisés comme intermédiaire entre les textures sous forme de fichiers sur un support de stockage (fichiers png ou bmp, etc..) [...]

                      Plutôt inexact. En fait les SDL_Surface sont en RAM et ne sont tout simplement plus utiles en SDL 2 à une ou deux exceptions près. Pour l'instant la seule raison (presque) valable d'utiliser une SDL_Surface (que j'aie pu trouver) est qu'il est dangereux de créer une texture dans un thread, donc j'en sort une surface à convertir en texture dans le programme principal... Et encore, le thread pourrait sortir un RWops (virtualisation de fichier) et ensuite en extraire directement une texture. Oui, SDL_img() charge des surfaces et passe par la conversion surface -> texture, mais ce n'est pas notre problème.

                      Ceci dit, SDL_Gfx() est très clairement très lent et peut vite plomber le fps d'un jeu.

                      Passer de la SDL1 à la 2 peut prendre un peu de temps surtout si tu codes tout dans ton main. Bien lire la doc, il y a quelques changements au-delà des surfaces/textures. Notamment les entrés qui passent de keysym à scancode, vu ce que tu veux en faire... Au moins, il sera possible d'abandonner SDL_Gfx() et d'avoir des transformations "natives" d'une rapidité fulgurante.

                      Bonne continuation.

                      Bonjour à toi,

                      Merci beaucoup pour ces précisions !

                      J'ai seulement une question ; comment abandonner SDL_gfx ? quelle est la solution "fulgurante" dont tu me parles ? :)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        25 février 2018 à 18:06:20

                        La solution dont il parle est la SDL 2 qui permet nativement d’afficher des textures redimensionnées.

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
                          25 février 2018 à 21:48:18

                          d'accord, je regarderai merci !

                          j'ai également une autre question (eh oui, je code même à cette heure là xD) concernant quelque chose qu'on appelle d'après ce que j'ai compris la collision ; quand deux poissons se touchent, alors y'en a un des deux qui mange l'autre. Donc pour voir s'ils se touchent, je compare les positions relatives des poissons. Cependant, je compare ainsi des "rectangles" sauf qu'en réalité, les poissons à l'intérieur de ces rectangles ne se touchent pas... 

                          Cet exemple devrait être plus parlant :)

                          Ici, j'ai mon poisson qui meurt parce que son "rectagle" a touché celui du bleu. Ma question est la suivante : Est-il possible de ne prendre en compte non pas les rectangles mais les figures à l'intérieur avec la SDL 1 ou 2 ?

                           Merci de votre attention.

                          -
                          Edité par Diablo-hell 26 février 2018 à 4:29:12

                          • Partager sur Facebook
                          • Partager sur Twitter
                            26 février 2018 à 10:40:50

                            Salut,

                            Tu peux regarder ce tuto, tu devrais y trouver des idées :

                            https://openclassrooms.com/courses/theorie-des-collisions

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Architecture SDL                     Multithreading         
                              26 février 2018 à 22:53:35

                              Salut,

                              merciiiii tu me sauves !!

                              • Partager sur Facebook
                              • Partager sur Twitter
                                8 mars 2018 à 16:51:20

                                drx a écrit:

                                Warren79 a écrit:

                                [...]Les SDL_Surface* sont utilisés comme intermédiaire entre les textures sous forme de fichiers sur un support de stockage (fichiers png ou bmp, etc..) [...]

                                Plutôt inexact. En fait les SDL_Surface sont en RAM et ne sont tout simplement plus utiles en SDL 2 à une ou deux exceptions près. Pour l'instant la seule raison (presque) valable d'utiliser une SDL_Surface (que j'aie pu trouver) est qu'il est dangereux de créer une texture dans un thread, donc j'en sort une surface à convertir en texture dans le programme principal... Et encore, le thread pourrait sortir un RWops (virtualisation de fichier) et ensuite en extraire directement une texture. Oui, SDL_img() charge des surfaces et passe par la conversion surface -> texture, mais ce n'est pas notre problème.

                                Ceci dit, SDL_Gfx() est très clairement très lent et peut vite plomber le fps d'un jeu.

                                Passer de la SDL1 à la 2 peut prendre un peu de temps surtout si tu codes tout dans ton main. Bien lire la doc, il y a quelques changements au-delà des surfaces/textures. Notamment les entrés qui passent de keysym à scancode, vu ce que tu veux en faire... Au moins, il sera possible d'abandonner SDL_Gfx() et d'avoir des transformations "natives" d'une rapidité fulgurante.

                                Bonne continuation.


                                En fait , je voulais dire que Les SDL_Surfaces sont intermédiaires entre les SDL_Textures qui sont souvent en VRAM "et" Les fichiers de textures (png, bmp, etc..) je savais que les SDL_Surfaces résidaient en RAM. Je me suis mal exprimé et je m'en excuse. :-°
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

                                  20 mars 2018 à 20:22:20

                                  Re bonjour,

                                  Warren79 a écrit:

                                  Bonjour,

                                  Tu devrais passer à la SDL 2.0 , le 'blittage' y est beaucoup plus rapide, et la gestion des touches du clavier est plus en adéquation avec ce qui existe (disons plus universelle). Voici un tutoriel sur la SDL 2.x : https://zestedesavoir.com/tutoriels/1014/utiliser-la-sdl-en-langage-c/

                                  -
                                  Edité par Warren79 25 février 2018 à 9:59:17

                                  Je viens de me rendre compte à la suite de plusieurs tests que c'est bien le blittage qui est vraiment pas le fort de la SDL (ou de mon code ...) puisque sans les animations, dès que je mets en plein écran et dès qu'il y a des figures "grandes" à afficher, ça commence à ne plus être fluide ...

                                  Par contre, lorsque je ne suis pas en plein écran et que je réduis la taille de la fenêtre de moitié, là c'est très fluide ...

                                  Donc je ne comprends pas tout, alors si quelqu'un a une explication je suis preneur ^^

                                  Merci

                                  -
                                  Edité par Diablo-hell 20 mars 2018 à 20:24:50

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    20 mars 2018 à 23:34:58

                                    Salut,

                                    Ok, si on dit que la SDL est "lente", ce n'est qu'un relent du siècle dernier. En effet, aux début de la SDL (fin 90/ début 2K) les PC présentaient  des performances, disons un peu moindre à ceux d'aujourd'hui. Aujourd'hui même un pc bon marché absorbe sans souci le boulot d'un pc de l'époque. Un I7 actuel, c'est au bas mot 300% d'un pentium II de l'époque.

                                    Donc, la SDL a été lente, ce n'est plus vraiment significatif aujourd'hui tant qu'on ne fait pas n'importe quoi, surtout avec le rotozoom qui, lui, est vraiment significativement lent, même de nos jours. J'imagine que tu l'utilises pour agrandir tes poissons... Dans ce cas, tu as tout intérêt à ne pas faire tes zooms à la volée. Idéalement, tu devrais préparer tes surface avant de lancer le jeu. Par exemple, pour chaque poisson, tu te fais une table de SDL_Surface* dans laquelle tu auras passé ton poisson au rotozoom avec un rapport allant crescendo. Comme ça, tes différentes tailles de poissons sont prêtes et tu t'épargnes le rotozoom pendant l'exécution du jeu.

                                    La différence entre un affichage en fenêtre et le full screen n'entre pas en ligne de compte et c'est la carte graphique qui s'en charge. Donc à moins d'avoir une Rage ou une GeForce 2 auquel cas, tu ne pourrais probablement même pas afficher le bureau de ton OS, il n'y a pas de souci. En plus, rien n'est plus "grand", c'est pareil, juste étiré.

                                    Si tu vas voir dans ma signature, il y a une version SDL1 de mon jeu revolver, c'est du 1280*720 avec par moment beaucoup de sprites, 2 plans et même du rotozoom, et j'ai quand-même du le limiter sans quoi je suis entre 250 et 300 de fps. Sachant qu'en moyenne, le fps utile est de 60 (inutile d'avoir plus d'images que ne peut en afficher le moniteur généralement en 60Hz, parfois en 100Hz), ça laisse de la marge.

                                    Ok, ça a presque doublé en passant sur la SDL2.

                                    Après, ce n'est pas forcément moins fluide, il est possible qu'on perçoive mieux les petits défauts quand l'image est plus grande. Par exemple imagine que ton sprite se déplace de 10 en 10 pixels. En fenêtre, tu as un rapport de 1, donc ton sprite se déplace effectivement de 10 pixels/image et ça semble fluide. Si tu as un gros rapport en fullscreen, disons de 3, ton déplacement va passer à 30 pixels/image, ce qui peut donner une impression de "saut". Et ça va aller en s’aggravant quand le rapport va augmenter et le "saut" va carrément se transformer en téléportation.

                                    Il est également possible qu'il y ait une mauvaise gestion dans ton code... Mais sans le code, impossible à dire.

                                    Bonne continuation.

                                    -
                                    Edité par drx 20 mars 2018 à 23:39:12

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Bonhomme !! | Jeu de plateforme : Prototype.

                                      20 mars 2018 à 23:39:29

                                      Re Bonjour,

                                      Plus que les Blit, c'est le Flip qui prend du temps; mais même en plein écran SDL 1.2 est largement suffisante pour du 50 à 100 FPS et donc pas de problème de fluidité.

                                      Peut-être que ta gestion de FPS n'est pas bonne, fais voir ton code ...

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Architecture SDL                     Multithreading         
                                        21 mars 2018 à 23:08:37

                                        Bonsoir,

                                        Merci beaucoup pour vos réponses.

                                        Je veux bien mettre mon code, mais il fait 1 000 lignes en tout ^^ le code concerné est plus au dessus, mais je vous le remet (j'ai modifié quelques trucs).

                                        while (continuer == 1)
                                        {
                                            tempsDepart = SDL_GetTicks();
                                        
                                            SDL_Event event;
                                            while(SDL_PollEvent(&event))
                                            {
                                                switch(event.type)
                                                {
                                                    case SDL_QUIT:
                                                        continuer = -1;
                                                        break;
                                        
                                                    case SDL_KEYDOWN:
                                                        switch (event.key.keysym.sym)
                                                        //La je regarde les touches ...
                                                        break;
                                        
                                                    case SDL_KEYUP:
                                                        //La je regarde encore les touches etc ...
                                                        break;
                                                }
                                            }
                                        
                                        
                                            /***ANIM***/
                                        
                                            newtime[0] = SDL_GetTicks();
                                        
                                            if(newtime[0] - lasttime[0] > 200)  //changement de direction probable => je lance un dé pour chacun des poissons pour les faire changer de direction aléatoirement ou pas toutes les 200 ms
                                            {
                                                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                                    if(adversaires[i].vivant==1)
                                                        changeDirection(&adversaires[i]);
                                                lasttime[0] = newtime[0];
                                            }
                                        
                                        
                                            newtime[1] = SDL_GetTicks();
                                        
                                            if(newtime[1] - lasttime[1] > 500)  //spawn probable => je lance encore un dé qui détermine si un poisson spawn toutes les 500 ms 
                                            {
                                                nouveau(&ajoutAdversaire);
                                                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                                    if(adversaires[i].vivant==0)
                                                        if(ajoutAdversaire==1)
                                                        {
                                                            adversaires[i].vivant=1;
                                                            spawn(&adversaires[i],ecran,0,monAnim.poids);
                                                            ajoutAdversaire = 0;
                                                            break;
                                                        }
                                                lasttime[1] = newtime[1];
                                            }
                                        
                                            newtime[2] = SDL_GetTicks();
                                        
                                            if(newtime[2] - lasttime[2] > 10)  //mouvement => j'update les positions des poissons toutes les 10 ms et du "poisson du joueur"
                                            {
                                                update(&monAnim);
                                                for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                                    if(adversaires[i].vivant==1)
                                                        updateAdv(&adversaires[i]);
                                                lasttime[2] = newtime[2];
                                            }
                                            if(continuer==1)
                                                continuer = verification(&monAnim,adversaires,ecran,*sons); //je vérifie si il y a collision
                                        
                                                
                                                
                                            //ici je fais varier les anims
                                        
                                            monAnim.tempsActuel = SDL_GetTicks();
                                        
                                            if(monAnim.tempsActuel - monAnim.tempsPasse > monAnim.temps)  //changement d'anim
                                            {
                                                if(monAnim.animActuelle+1<monAnim.animsEntite[monAnim.etat].anims_totales)
                                                    {monAnim.animActuelle++;}
                                                else
                                                    {monAnim.animActuelle=0;}
                                                monAnim.tempsPasse = monAnim.tempsActuel;
                                            }
                                        
                                            //ici je fais varier les anims des bots
                                        
                                            for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                            {
                                                if(adversaires[i].vivant==1)
                                                {
                                                    adversaires[i].tempsActuel = SDL_GetTicks();
                                        
                                                    if(adversaires[i].tempsActuel - adversaires[i].tempsPasse > adversaires[i].temps)  //changement d'anim
                                                    {
                                                        if(adversaires[i].animActuelle+1<adversaires[i].animsEntite[adversaires[i].etat].anims_totales)
                                                            {adversaires[i].animActuelle++;}
                                                        else
                                                            {adversaires[i].animActuelle=0;}
                                                        adversaires[i].tempsPasse = adversaires[i].tempsActuel;
                                                    }
                                                }
                                            }
                                        
                                        
                                        
                                            clipper.x = monAnim.oldPos.x;
                                            clipper.y = monAnim.oldPos.y;
                                            clipper.h = monAnim.animsEntite[monAnim.etat].taille_Y;
                                            clipper.w = monAnim.animsEntite[monAnim.etat].taille_X;
                                        
                                            SDL_SetClipRect(ecran,&clipper); 
                                            positionFond.x = 0;
                                            positionFond.y = 0;
                                        
                                            SDL_BlitSurface(fond, NULL, ecran, &positionFond); 
                                        
                                            SDL_SetClipRect(ecran,NULL); 
                                        
                                            monAnim.oldPos.x = monAnim.position.x;
                                            monAnim.oldPos.y = monAnim.position.y;
                                        
                                        
                                            clipper.h = texte->h;
                                            clipper.w = texte->w;
                                        
                                            sprintf(score, "Fattitude : %d / %d",monAnim.poids,POIDS_GAIN);
                                            texte = TTF_RenderText_Blended(police, score, couleur);
                                        
                                            clipper.x = 0;
                                            clipper.y = 0;
                                        
                                            SDL_SetClipRect(ecran,&clipper);
                                        
                                            positionFond.x = 0;
                                            positionFond.y = 0;
                                        
                                            SDL_BlitSurface(fond, NULL, ecran, &positionFond);
                                        
                                            SDL_SetClipRect(ecran,NULL); 
                                        
                                        
                                            for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                            {
                                                if(adversaires[i].vivant==1||adversaires[i].vivantAvant==1)
                                                {
                                                    if(adversaires[i].vivantAvant==1)
                                                        adversaires[i].vivantAvant=0;
                                                    clipper.x = adversaires[i].oldPos.x;
                                                    clipper.y = adversaires[i].oldPos.y;
                                                    clipper.h = adversaires[i].animsEntite[adversaires[i].etat].taille_Y;
                                                    clipper.w = adversaires[i].animsEntite[adversaires[i].etat].taille_X;
                                        
                                                    SDL_SetClipRect(ecran,&clipper);
                                        
                                                    positionFond.x = 0;
                                                    positionFond.y = 0;
                                        
                                                    SDL_BlitSurface(fond, NULL, ecran, &positionFond);
                                        
                                                    SDL_SetClipRect(ecran,NULL);
                                                    adversaires[i].oldPos.x=adversaires[i].position.x;
                                                    adversaires[i].oldPos.y=adversaires[i].position.y;
                                                }
                                            }
                                        
                                            //Au dessus, on clippe tous les poissons à l'écran et on met à jour les scores
                                            
                                        
                                            SDL_BlitSurface(monAnim.animsEntite[monAnim.etat].anim[monAnim.animActuelle],NULL,ecran,&monAnim.position);
                                            for(i=0;i<NB_ADVERSAIRES_MAX;i++)
                                                if(adversaires[i].vivant==1)
                                                    SDL_BlitSurface(adversaires[i].animsEntite[adversaires[i].etat].anim[adversaires[i].animActuelle],NULL,ecran,&adversaires[i].position);
                                            //ici, on affiche les poissons à l'écran
                                        
                                            SDL_BlitSurface(texte, NULL, ecran, 0);
                                        
                                        
                                            SDL_Flip(ecran);
                                            
                                        
                                            //gestion des FPS ( d'après ce que j'ai compris, c'est ce qu'il faut. j'ai réglé la variable FPS à 60)
                                            if(1000/FPS>SDL_GetTicks()-tempsDepart)
                                                SDL_Delay((1000/FPS)-(SDL_GetTicks()-tempsDepart)); 
                                        
                                        
                                        }
                                        



                                        Je pense que le problème c'est que je bouge mon poisson à 10 px oui et donc c'est fluide en petit mais pas en grand ; voici le bout code qui correspond à la gestion de la distance (c'est dans update() et updateAdv() ):

                                        Ma fonction update :

                                        void update(Sprits *monAnim)
                                        {
                                            if(monAnim->mouvement[AVANCE] == 0 && monAnim->mouvement[RECULE] == 0 && monAnim->mouvement[DESCEND] == 0 && monAnim->mouvement[MONTE] == 0)
                                            {
                                                if(monAnim->etat == BOUGE)
                                                    monAnim->animActuelle=0;
                                                monAnim->etat = BOUGEPAS;
                                        
                                            }
                                            else
                                            {
                                                if(monAnim->etat == BOUGEPAS)
                                                    monAnim->animActuelle=0;
                                                monAnim->etat = BOUGE;
                                            }
                                        
                                        
                                            if(monAnim->mouvement[AVANCE]==1)
                                            {
                                                if(monAnim->position.x+monAnim->animsEntite[0].taille_X+monAnim->vitesse+monAnim->mouvement[ACCELERE]<ECRAN_X)
                                                    monAnim->position.x+=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.x+monAnim->animsEntite[0].taille_X+monAnim->vitesse<ECRAN_X)
                                                    monAnim->position.x+=(monAnim->vitesse);
                                            }
                                            if (monAnim->mouvement[RECULE]==1)
                                            {
                                                if(monAnim->position.x-monAnim->vitesse-monAnim->mouvement[ACCELERE]>0)
                                                    monAnim->position.x-=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.x-monAnim->vitesse>0)
                                                    monAnim->position.x-=(monAnim->vitesse);
                                            }
                                            if(monAnim->mouvement[DESCEND]==1)
                                            {
                                                if(monAnim->position.y+monAnim->animsEntite[0].taille_Y+monAnim->vitesse+monAnim->mouvement[ACCELERE]<ECRAN_Y)
                                                    monAnim->position.y+=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.y+monAnim->animsEntite[0].taille_Y+monAnim->vitesse<ECRAN_Y)
                                                    monAnim->position.y+=(monAnim->vitesse);
                                            }
                                            if (monAnim->mouvement[MONTE]==1)
                                            {
                                                if(monAnim->position.y-monAnim->vitesse-monAnim->mouvement[ACCELERE]>0)
                                                    monAnim->position.y-=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.y-monAnim->vitesse>0)
                                                    monAnim->position.y-=(monAnim->vitesse);
                                            }
                                        }

                                        La fonction updtate pour les adversaires ; elle est différente puisqu'ils rebondissent sur les bords ( j'ai voulu démarrer avec des trucs simples xD) :

                                        void updateAdv(Sprits *monAnim)
                                        {
                                        
                                            if(monAnim->mouvement[AVANCE] == 0 && monAnim->mouvement[RECULE] == 0 && monAnim->mouvement[DESCEND] == 0 && monAnim->mouvement[MONTE] == 0)
                                            {
                                                if(monAnim->etat == BOUGE)
                                                    monAnim->animActuelle=0;
                                                monAnim->etat = BOUGEPAS;
                                        
                                            }
                                            else
                                            {
                                                if(monAnim->etat == BOUGEPAS)
                                                    monAnim->animActuelle=0;
                                                monAnim->etat = BOUGE;
                                            }
                                        
                                        
                                            if(monAnim->mouvement[AVANCE]==1)
                                            {
                                                if(monAnim->position.x+monAnim->animsEntite[0].taille_X+monAnim->vitesse+monAnim->mouvement[ACCELERE]<ECRAN_X)
                                                    monAnim->position.x+=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.x+monAnim->animsEntite[0].taille_X+monAnim->vitesse<ECRAN_X)
                                                    monAnim->position.x+=(monAnim->vitesse);
                                                else
                                                {
                                                    monAnim->mouvement[AVANCE] = 0;
                                                    monAnim->mouvement[RECULE] = 1;
                                                }
                                            }
                                            if (monAnim->mouvement[RECULE]==1)
                                            {
                                                if(monAnim->position.x-monAnim->vitesse-monAnim->mouvement[ACCELERE]>0)
                                                    monAnim->position.x-=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.x-monAnim->vitesse>0)
                                                    monAnim->position.x-=(monAnim->vitesse);
                                                else
                                                {
                                                    monAnim->mouvement[AVANCE] = 1;
                                                    monAnim->mouvement[RECULE] = 0;
                                                }
                                            }
                                            if(monAnim->mouvement[DESCEND]==1)
                                            {
                                                if(monAnim->position.y+monAnim->animsEntite[0].taille_Y+monAnim->vitesse+monAnim->mouvement[ACCELERE]<ECRAN_Y)
                                                    monAnim->position.y+=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.y+monAnim->animsEntite[0].taille_Y+monAnim->vitesse<ECRAN_Y)
                                                    monAnim->position.y+=(monAnim->vitesse);
                                                else
                                                {
                                                    monAnim->mouvement[DESCEND] = 0;
                                                    monAnim->mouvement[MONTE] = 1;
                                                }
                                            }
                                            if (monAnim->mouvement[MONTE]==1)
                                            {
                                                if(monAnim->position.y-monAnim->vitesse-monAnim->mouvement[ACCELERE]>0)
                                                    monAnim->position.y-=(monAnim->vitesse+monAnim->mouvement[ACCELERE]);
                                                else if(monAnim->position.y-monAnim->vitesse>0)
                                                    monAnim->position.y-=(monAnim->vitesse);
                                                else
                                                {
                                                    monAnim->mouvement[DESCEND] = 1;
                                                    monAnim->mouvement[MONTE] = 0;
                                                }
                                            }
                                        }

                                        Voilà en espérant que cela peut vous aider à m'aider :)

                                        Si vous avez besoin d'autre chose comme code, demandez moi.

                                        Bonne soirée !

                                        PS : pour les vitesses je les ai initialisées comme ça :

                                            monAnim->vitesse=6;
                                        //ça c'est pour mon poisson
                                            monAnim->vitesse=(rand() % (VITESSE_MAX - 3 + 1)) + 3;
                                        //ça c'est une vitesse comprise entre 3 et 4 pour l'instant pour les poissons ennemis



                                        -
                                        Edité par Diablo-hell 21 mars 2018 à 23:12:45

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          21 mars 2018 à 23:41:25

                                          Salut,

                                          Jeu qui ralentit au fil du temps, c'est souvent des fuites mémoire qui vont mettre ton PC à genou.

                                          Regarde dans ton gestionnaire de tâche l'utilisation mémoire ne doit faire que croître... Et au bout d'un moment, ça swap et ralentit.

                                          Dans ton code, je vois au moins une fuite : 

                                          Ta variable texte, allouée a chaque itération de ta boucle et jamais libérée.

                                          Appelle un SDL_FreeSurface après l'avoir blitté. 

                                          Dis nous si ça va mieux, et surtout si ton utilisation mémoire reste stable ou non.

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                            21 mars 2018 à 23:52:16

                                            Bonsoir,

                                            J'avais pas pensé à ça ! je l'ai fait et ça change pas grand chose ... ^^

                                                    SDL_BlitSurface(texte, NULL, ecran, 0);
                                                    SDL_FreeSurface(texte);

                                            Mais du coup j'ai 36 % de CPU utilisé alors que j'ai un bon pc ... :o 

                                            Et maintenant que tu me le dis, c'est ce que ça me faisait : le jeu commençait tranquille, et au bout d'un moment le CPU utilisé augmentait jusque n'en plus pouvoir et ça buggait x)

                                            tu as d'autres idées ? Peut être que c'est seulement à cause de gfx, mais j'ai testé sans jouer, c'est à dire juste faire apparaitre 6 poissons gros sur l'écran et les animer et ça bugge de ouf ...

                                            Merci pour ta réponse rapide !

                                            edit : ce que je remarque par contre c'est que plus la taille des poissons à l'écran augmente, plus ça bug ... et le CPU reste le même depuis que j'ai bien réglé les FPS donc c'est pas ça non plus ... :/

                                            -
                                            Edité par Diablo-hell 22 mars 2018 à 0:06:36

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              22 mars 2018 à 8:15:15

                                              Salut,

                                              et la mémoire ? Le CPU c'est une chose, mais la mémoire ? Elle augmente ? 

                                              Ou charges tu tes ressources ? Comment les charges tu ? Surtout ton image de fond, est elle en VRAM avec le même display format que la surface screen ?

                                              Que fait ta fonction spawn ?

                                              Voici un exemple ou je déplace 2000 balles en même temps de façon fluide avec SDL 1.2

                                              http://fvirtman.free.fr/recueil/02_02_01_01_multimove.c.php


                                              -
                                              Edité par Fvirtman 22 mars 2018 à 8:18:06

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                                22 mars 2018 à 12:58:11

                                                Salut,

                                                D'après ce que tu montres la boucle principale devrait tourner avec une période de 16ms.
                                                Pour le vérifier tu peux enrichir le code ainsi :

                                                if(1000/FPS>SDL_GetTicks()-tempsDepart)
                                                        SDL_Delay((1000/FPS)-(SDL_GetTicks()-tempsDepart)); 
                                                else
                                                	printf("Surcharge CPU au temps = %i \n",SDL_GetTicks());



                                                Il est assez difficile de s'y repérer dans toutes les conditions et je vois que tu rajoutes une condition liée au temps (ligne 58) pour les fonctions update().

                                                Je te conseillerais de faire une mise à jour des positions une seule fois dans la boucle et sans condition de la forme : position = position + vitesse
                                                et avec les conditions tu travailles uniquement sur la valeur de "vitesse".

                                                Autre chose pour ne pas avoir de saccades, cette équation doit être faite avec des float ou des doubles ( caster en int à la fin juste pour le blit).

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Architecture SDL                     Multithreading         
                                                  22 mars 2018 à 16:40:00

                                                  @Léovendeville : n'hésite pas à découper ton code en fonctions plus petites (la taille idéale , c'est pas plus de 20 lignes par fonctions si tu le peux). Et ça rend le debuggage du programme plus facile. :)

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Mon site web de jeux SDL2 entre autres : https://www.ant01.fr

                                                    22 mars 2018 à 21:46:39

                                                    Salut !

                                                    Merci pour vos réponses. 

                                                    Fvirtman, je te joins ci dessous quelques extraits de mon code qui correspond à ce que tu me demandes avec des commentaires (clairs j'espère :) ). La mémoire est fixe (par contre, vu que j'ai vérifié, j'ai vu qu'elle augmentait dans mon menu : même problème, j'avais pas libéré la surface "texte" avant de la re-remplir xD) et le CPU aussi ... Après tu verras, je charge tout avec des IMG_Load () parce que j'avais jamais appris les SDL_DisplayFormat ^^  et que veux tu dire par "Surtout ton image de fond, est elle en VRAM avec le même display format que la surface screen ?" ? Ma fonction spawn associe au nouveau poisson qui spawn une taille, une vitesse, une position, un état (bouge ou fixe) et un tableau de sprites pour l'animation, correspondant à la taille (voir en dessous).

                                                    Picosoft, merci pour tes conseils, je vais faire ça. Je comprends que ça ne soit pas trop clair mon code je sais pas trop comment faire pour que ça soit bien présenté et facile à comprendre ^^. Mais pourquoi il faudrait calculer avec des floats (ou double) pour les positions pour ensuite les caster ? ... ça ne revient pas au même ? quel est le but ?

                                                    Warren79, merci pour ton conseil ! j'avoue que j'aurais dû faire plusieurs fonctions pour ce qui est de l'affichage mais je voulais tester pour voir si cela fonctionne et après tout réorganiser en fonctions, mais je me doute que ce n'est pas la manière la plus logique de faire :p

                                                        temp = IMG_Load("Images/fond.jpg");
                                                        fond = SDL_DisplayFormat(temp);
                                                        fond = zoomSurface(fond,ZOOM_X,ZOOM_Y,0);
                                                        //ça c'est pour le fond, il est mis à l'échelle avec un zoom
                                                        //il est chargé dans la fonction principale "jeu"
                                                     //FONCTION INIT
                                                        for(j=0;j<2;j++)
                                                        {
                                                            for(i=0;i<monAnim->animsEntite[j].anims_totales;i++)
                                                            {
                                                                if(j==BOUGEPAS)
                                                                    sprintf(nomImg, "Images/Poisson_%d/Poissons_bougePas/Poissons_bougePas_%d.png",sortePoisson,i);
                                                                else
                                                                    sprintf(nomImg, "Images/Poisson_%d/Poissons_bouge/Poissons_bouge_%d.png",sortePoisson,i);
                                                    
                                                                printf("%s\n",nomImg);  //là je marque juste on s'en fout
                                                    
                                                                monAnim->animsEntite[j].animBase[i] = IMG_Load(nomImg);   //on ouvre l'image avec le nom 
                                                                //Ce que je fais, c'est que je load tout en taille normale dans "anim.base" et après je la traite en dessous par exemple pour le spawn des bots
                                                                monAnim->animsEntite[j].animBase[i] = zoomSurface(monAnim->animsEntite[j].animBase[i],ZOOM_X,ZOOM_Y,0); //on met a l'echelle
                                                    
                                                                if(monAnim->animsEntite[j].animBase[i] == NULL)
                                                                    printf("fail");
                                                            }
                                                        }
                                                        //FONCTION SPAWN
                                                        for(j=0;j<2;j++)
                                                        {
                                                            for(i=0;i<monAnim->animsEntite[j].anims_totales;i++)
                                                            {
                                                    
                                                                monAnim->animsEntite[j].anim[i] = rotozoomSurface(monAnim->animsEntite[j].animBase[i],0.0,monAnim->grosseur,0)/*zoomSurface(monAnim->animsEntite[j].animBase[i],monAnim->grosseur,monAnim->grosseur,0)*/;
                                                    
                                                                if(i==0 && j==0)
                                                                {
                                                                    monAnim->animsEntite[BOUGEPAS].taille_X = monAnim->animsEntite[BOUGEPAS].anim[0]->w;
                                                                    monAnim->animsEntite[BOUGEPAS].taille_Y = monAnim->animsEntite[BOUGEPAS].anim[0]->h;
                                                                }
                                                                if(i==0 && j==1)
                                                                {
                                                                    monAnim->animsEntite[BOUGE].taille_X = monAnim->animsEntite[BOUGE].anim[0]->w;
                                                                    monAnim->animsEntite[BOUGE].taille_Y = monAnim->animsEntite[BOUGE].anim[0]->h;
                                                                }
                                                    
                                                            }
                                                        }


                                                    Merci encore votre aide m'est précieuse ! :)

                                                    EDIT :

                                                    Fvirtman, je viens de trouver la solution sur ton site avec tes cours sur la SDL, et c'est ce que tu m'avais dit plus haut sur SDL_DisplayFormat qui m'a mis la puce à l'oreille ; je me permets de citer, comme ça ça pourra aider d'autres (si cela ne te dérange pas bien sûr !) :

                                                    "Ce qui est intéressant est le SDL_DisplayFormat, ou je recrée une deuxième surface à partir de la première, qui aura comme particularité d'avoirCe qui est intéressant est le SDL_DisplayFormat, ou je recrée une deuxième surface à partir de la première, qui aura comme particularité d'avoir les mêmes propriétés que le "vidéo buffer", c'est à dire votre "screen". Si vous ne le faites pas, et que les surfaces n'ont pas le même format, elles sont converties à chaque blit : c'est long et lourd. Si vous le faites, vous gagnez énormément en vitesse."

                                                    J'ai donc simplement rajouté à chacun de mes load un displayformat et c'est nickel, je peux animer 40 poissons et le CPU reste en dessous de 10% :o :) 

                                                    -
                                                    Edité par Diablo-hell 22 mars 2018 à 22:22:15

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      22 mars 2018 à 23:36:31

                                                      Salut,

                                                      Soyons clair : Il n'y a rien en VRAM avec la SDL1.x. Pas sous Windows en tout cas et de mémoire, sous linux non-plus.

                                                      Très simple à démontrer :

                                                      if (SDL_Init(SDL_INIT_VIDEO)<0)
                                                          {/*initialisation de la SDL*/
                                                              fprintf(stderr, "Err initialisation SDL impossible : %s\n",SDL_GetError());
                                                              goto exit_err;
                                                          }
                                                          else
                                                          {
                                                              SDL_VideoInfo   *videoInfo = SDL_GetVideoInfo();
                                                              printf("possible to create hardware surfaces=%s\n",(videoInfo->hw_available)? "yes" : "no");
                                                              printf("window manager available=%s\n",(videoInfo->wm_available)? "yes" : "no");
                                                              printf("hardware to hardware blits accelerated=%s\n",(videoInfo->blit_hw)? "yes" : "no");
                                                              printf("hardware to hardware colorkey blits accelerated=%s\n",(videoInfo->blit_hw_CC)? "yes" : "no");
                                                              printf("hardware to hardware alpha blits accelerated=%s\n",(videoInfo->blit_hw_A)? "yes" : "no");
                                                              printf("software to hardware blits accelerated=%s\n",(videoInfo->blit_sw)? "yes" : "no");
                                                              printf("software to hardware colorkey blits accelerated=%s\n",(videoInfo->blit_sw_CC)? "yes" : "no");
                                                              printf("software to hardware alpha blits accelerated=%s\n",(videoInfo->blit_sw_A)? "yes" : "no");
                                                              printf("color fills accelerated=%s\n",(videoInfo->blit_fill)? "yes" : "no");
                                                          }

                                                      La réponse à toutes les solutions hardware est non...

                                                      Les formats d'images les mieux adaptés sont les jpg (ou jpeg) pour tout ce qui est fond et png avec transparence pour les sprites.

                                                      Convertir les sprites avec SDL_DisplayFormatAlpha(). Avec des couleurs 32 bits bien entendu.

                                                      Reclipper des bouts du fond pour effacer tes sprites avant de les afficher de nouveau n'est pas nécessaire, reblit le tout. Quelle est ta définition de base ? Avec 2 plans de 1280*720 plus les sprites, j'avais encore plus de 200 affichages par seconde...

                                                      Bonne continuation.

                                                      Edit : Nouvelle mesure, j'ai changé de PC depuis ^^ :

                                                      Petit comparatif avec la SDL2 :

                                                      -
                                                      Edité par drx 23 mars 2018 à 0:05:55

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Bonhomme !! | Jeu de plateforme : Prototype.

                                                        23 mars 2018 à 0:11:14

                                                        Salut !

                                                        Ben écoute je suis en 1920/1080 du coup, comme ça c'est grand et joli pour mon pc ; cependant, j'ai fait en sorte que ça s'adapte aux résolutions du joueur :)

                                                        J'ai fait en reblittant tout, et je crois que ça altère pas la qualité :D

                                                        Pour avoir le nb de fps max je vais essayer de coder ça avant d'aller me coucher et je te mets ça en édit :p

                                                        EDIT :

                                                        Voilà donc ça c'est en plein écran donc ça va beaucoup mieux grâce à displayformat :) par contre quand je le mets en 1920/2;1080/2 y'a 750 FPS xD :o :D

                                                        EDIT 2: wow en effet la différence est vraiment notable entre SDL et SDL2 :o Merci beaucoup drx !

                                                        -
                                                        Edité par Diablo-hell 23 mars 2018 à 0:33:05

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          23 mars 2018 à 9:38:20

                                                          Salut !

                                                          En effet, DisplayFormat évite les conversions à chaque blit. (+ de 1 million de pixels à chaque fois !)

                                                          Tu ne m'as pas dit, quand tu charges ton image de fond (et tes poissons) c'est bien avant ta boucle, et une fois pour toutes ? (je pense que oui, sinon ton ordi serait bien à la ramasse)

                                                          Pour la différence entre SDL1 et SDL2, SDL1 utilise les technologies de blitting obsolètes des cartes graphiques. Elle permet de mettre les images en VRAM malgré tout : on peut faire l'essai en créant des surfaces avec SW_SURFACE ou HW_SURFACE. 

                                                          Mais à l'heure actuelle, les cartes graphiques sont faites pour la 3D et uniquement la 3D.

                                                          Donc il est beaucoup plus rapide, même pour faire de la 2D, de créer un polygone sur le plan Z = 0 (la 2D n'est qu'un cas particulier de la 3D) et de le texturer ! C'est ce que fait SDL 2 .

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                                            23 mars 2018 à 16:46:02

                                                            Re, désolé d'insister, mais le HW_SURFACE ne sert à rien, il ne passe jamais :

                                                               SDL_Init(SDL_INIT_VIDEO);
                                                               /*contrôle tati tata*/
                                                            
                                                                ecran = SDL_SetVideoMode(1280, 800, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
                                                                /*contrôle etc*/
                                                            
                                                                if (ecran->flags & SDL_HWSURFACE)
                                                                    fprintf(stdout, "utilise le HW\n");    
                                                                else
                                                                    fprintf(stdout, "Perdu...\n");
                                                            
                                                                if (ecran->flags & SDL_DOUBLEBUF)
                                                                    fprintf(stdout, "utilise le double buffering\n");    
                                                                else
                                                                    fprintf(stdout, "Ha ? Bin non plus...\n");

                                                            Le code du post plus haut démontrait déjà clairement que la SDL 1.x n'a accès à aucune solution matérielle. Je n'ai pas testé les autres plateformes (megadrive, psp etc) mais sous Win et Linux, il est sûr et certain que ça n'arrive pas.

                                                            Bonne continuation.

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            Bonhomme !! | Jeu de plateforme : Prototype.

                                                              23 mars 2018 à 18:12:15

                                                              Salut !

                                                              Fvirtman a écrit:

                                                              Salut !

                                                              En effet, DisplayFormat évite les conversions à chaque blit. (+ de 1 million de pixels à chaque fois !)

                                                              Tu ne m'as pas dit, quand tu charges ton image de fond (et tes poissons) c'est bien avant ta boucle, et une fois pour toutes ? (je pense que oui, sinon ton ordi serait bien à la ramasse)

                                                              Pour la différence entre SDL1 et SDL2, SDL1 utilise les technologies de blitting obsolètes des cartes graphiques. Elle permet de mettre les images en VRAM malgré tout : on peut faire l'essai en créant des surfaces avec SW_SURFACE ou HW_SURFACE. 

                                                              Mais à l'heure actuelle, les cartes graphiques sont faites pour la 3D et uniquement la 3D.

                                                              Donc il est beaucoup plus rapide, même pour faire de la 2D, de créer un polygone sur le plan Z = 0 (la 2D n'est qu'un cas particulier de la 3D) et de le texturer ! C'est ce que fait SDL 2 .

                                                              Du coup bien sûr, je la charge qu'une fois, je connais ça t'inquiète :) Je ne savais pas la différence et maintenant je comprends merci :D je vais passer à la SDL_2 très bientot alors !

                                                              drx a écrit:

                                                              Re, désolé d'insister, mais le HW_SURFACE ne sert à rien, il ne passe jamais :

                                                                 SDL_Init(SDL_INIT_VIDEO);
                                                                 /*contrôle tati tata*/
                                                              
                                                                  ecran = SDL_SetVideoMode(1280, 800, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
                                                                  /*contrôle etc*/
                                                              
                                                                  if (ecran->flags & SDL_HWSURFACE)
                                                                      fprintf(stdout, "utilise le HW\n");    
                                                                  else
                                                                      fprintf(stdout, "Perdu...\n");
                                                              
                                                                  if (ecran->flags & SDL_DOUBLEBUF)
                                                                      fprintf(stdout, "utilise le double buffering\n");    
                                                                  else
                                                                      fprintf(stdout, "Ha ? Bin non plus...\n");

                                                              Le code du post plus haut démontrait déjà clairement que la SDL 1.x n'a accès à aucune solution matérielle. Je n'ai pas testé les autres plateformes (megadrive, psp etc) mais sous Win et Linux, il est sûr et certain que ça n'arrive pas.

                                                              Bonne continuation.

                                                              D'accord merci ^^ donc au final la SDL_1 c'est la base, mais y'a complètement mieux, c'est ça ? :)

                                                              Bonne soirée !



                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              jeu qui ralentit au fil du temps

                                                              × 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