Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pb chrono en SDL

Pb avec PollEvent et WaitEvent

    30 juin 2019 à 12:05:48

    Bonjour,

    Je suis à la fin du cours du C de Mathéo, j'ai commencé un jeu de clic. Le problème c'est que le chrono ne s'actualise que quand je clique. J'ai essayé de mettre PollEvent à la place du Wait Event, pas de problème le chrono marche bien mais dès que je clique 1 fois j'arrive à la fin du jeu direct !!!

    D'ailleurs autre problème, si je tape au clavier le compteur s'incrémente quand même, je ne comprends pas parce que j'ai bien mis les évènement SDL_MOUSSEBUTTONDOWN.

    Enfin, 3ème problème : il y a un décompte de 3 secondes dans le main mais si je clique avant la fin du décompte le compteur de coups s'incrémente par avance alors qu'il n'est pas dans le main... Là dessus je coince.

    Voici le code du main.c :

    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <SDL/SDL_TTF.h>
    
    #include "jeu.h"
    
    
    
    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL, *titre = NULL, *regle = NULL, *decompte = NULL;
        SDL_Rect positionRegle, positionDecompte, positionTitre;
        SDL_Event event;
        TTF_Font *policeRegle = NULL, *policeDecompte = NULL, *policeTitre = NULL;
        SDL_Color couleurBlanc = {255, 255, 255}, couleurNoir = {0, 0, 0};
    
    
        int tempsActuel = 0, tempsPrecedent = 0, i = 0, j = 0, continuer = 1;
        char decompteConverti[100] = "";
    
    
        SDL_Init(SDL_INIT_VIDEO);
    
        ecran = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Clic Clic", NULL);
    
        if(TTF_Init() == -1)
        {
        fprintf(stderr, "Erreur d'initialisation de TTF_Init : %s\n", TTF_GetError());
        exit(EXIT_FAILURE);
        }
    
        policeRegle = TTF_OpenFont("cabin.ttf", 35);
        regle = TTF_RenderText_Blended(policeRegle, "Clique le plus vite possible pour faire disparaître le texte...", couleurBlanc);
        positionRegle.x = (1024-regle->w)/2;
        positionRegle.y = 450;
    
        policeTitre = TTF_OpenFont("cabin.ttf", 50);
        titre = TTF_RenderText_Blended(policeTitre, "Clic Clic...", couleurBlanc);
        positionTitre.x = (1024-titre->w)/2;
        positionTitre.y = 100;
    
        policeDecompte = TTF_OpenFont("cabin.ttf", 70);
    
    
        do
        {
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, i, i, i));
            SDL_BlitSurface(regle, NULL, ecran, &positionRegle);
            SDL_BlitSurface(titre, NULL, ecran, &positionTitre);
    
            SDL_Flip(ecran);
    
            j = 3;
            SDL_WaitEvent(&event);
            switch(event.type)
                {
                    case SDL_QUIT:
                        continuer = 0;
                        break;
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym)
                        {
                            case SDLK_ESCAPE:
                                continuer = 0;
                                break;
                        }
                }
    
            SDL_PollEvent(&event);
            switch(event.type)
                {
    
                    case SDL_MOUSEBUTTONDOWN:
    
    
                                    do
                                    {
                                        sprintf(decompteConverti, "%d", j);
                                        SDL_FreeSurface(decompte);
                                        decompte = TTF_RenderText_Shaded(policeDecompte, decompteConverti, couleurBlanc, couleurNoir);
                                        positionDecompte.x = (1024-decompte->w)/2;
                                        positionDecompte.y = 250;
    
                                        SDL_BlitSurface(decompte, NULL, ecran, &positionDecompte);
    
                                        SDL_Flip(ecran);
    
                                        tempsActuel = SDL_GetTicks();
                                        if (tempsActuel - tempsPrecedent >= 1000)
                                            {
                                                j--;
                                                tempsPrecedent = tempsActuel;
                                            }
    
                                        else
                                            {
                                                SDL_Delay(1000 - (tempsActuel - tempsPrecedent));
                                            }
    
    
                                    }while (j > 0);
    
                                    jouer(ecran);
    
                                    break;
    
                }
    
    
    
    
        }while (continuer);
    
        TTF_CloseFont(policeRegle);
        TTF_CloseFont(policeDecompte);
        TTF_CloseFont(policeTitre);
        TTF_Quit();
    
        SDL_FreeSurface(titre);
        SDL_FreeSurface(regle);
    
        SDL_Quit();
    
        return EXIT_SUCCESS;
    }
    

    Voici le code du jeu.c :

    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <SDL/SDL_TTF.h>
    #include <time.h>
    
    #include "jeu.h"
    #include "fichiers.h"
    
    void jouer(SDL_Surface* ecran)
    {
        SDL_Surface *regle = NULL, *compteur = NULL, *victoire = NULL, *dureeTotale = NULL, *texteRejouer = NULL, *texteRecord = NULL, *chrono = NULL;
        SDL_Rect positionRegle, positionCompteur, positionVictoire, positionDuree, positionRejouer, positionRecord, positionChrono;
        SDL_Event event;
        TTF_Font *policeRegle = NULL, *policeCompteur = NULL, *policeRejouer = NULL;
        SDL_Color couleurBlanc = {255, 255, 255};
        SDL_Color couleurNoir = {0, 0, 0};
        SDL_Color couleurRouge = {255, 0, 0};
    
        int continuer = 1, fin = 0, compteurCoups = 0,  nombreAleatoire = 0, recordLu = 0, recordEcrit = 0, recordSecondes = 0, recordMillisecondes = 0;
        double i = 0;
        const int nombreMIN = 10, nombreMAX = 20;
        int temps = 0, tempsDebut = SDL_GetTicks(), secondes = 0, millisecondes = 0;
        char compteurConverti[100] = " ";
        char tempsConverti[100] = "";
        char recordConverti[100] = "";
        char chronoConverti[100] = "";
    
        srand(time(NULL));
        nombreAleatoire = (rand() % (nombreMAX - nombreMIN + 1)) + nombreMIN;
    
    
        policeRegle = TTF_OpenFont("cabin.ttf", 35);
        regle = TTF_RenderText_Blended(policeRegle, "Clic Clic Clic...", couleurBlanc);
    
        positionRegle.x = (1024-regle->w)/2;
        positionRegle.y = 250;
    
        policeCompteur = TTF_OpenFont("cabin.ttf", 40);
        policeRejouer = TTF_OpenFont("cabin.ttf", 15);
    
        if (!lireRecord(recordLu))
            exit(EXIT_FAILURE);
    
        lireRecord(recordLu);
        recordSecondes = lireRecord(recordLu) / 1000;
        recordMillisecondes = lireRecord(recordLu) % 1000;
    
        sprintf(recordConverti, "Record : %d '' %d", recordSecondes, recordMillisecondes);
        texteRecord = TTF_RenderText_Blended(policeCompteur, recordConverti, couleurBlanc);
        positionRecord.x = (1024-texteRecord->w)/2;
        positionRecord.y = 50;
    
    
        do
        {
                temps = SDL_GetTicks() - tempsDebut;
                secondes = temps /1000;
                millisecondes = (temps % 1000);
    
                sprintf(chronoConverti, "%d '' %d", secondes, millisecondes);
                chrono = TTF_RenderText_Blended(policeCompteur, chronoConverti, couleurBlanc);
                positionChrono.x = (1024-chrono->w)/2;
                positionChrono.y = 150;
    
    
                SDL_WaitEvent(&event);
                switch(event.type)
                {
                    case SDL_QUIT:
                        continuer = 0;
                        break;
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym)
                        {
                            case SDLK_ESCAPE:
                                continuer = 0;
                                break;
                            default:
                                break;
                        }
    
                    case SDL_MOUSEBUTTONDOWN:
                         if (event.button.button == SDL_BUTTON_RIGHT || event.button.button == SDL_BUTTON_LEFT)
                            {
                            if (i <= (255 - (255/nombreAleatoire)))
                                {   compteurCoups++;
                                    sprintf(compteurConverti, "Nombre de coups : %d", compteurCoups);
                                    compteur = TTF_RenderText_Blended(policeCompteur, compteurConverti, couleurBlanc);
                                    positionCompteur.x = (1024-compteur->w)/2;
                                    positionCompteur.y = 500;
                                    i+=(255/nombreAleatoire);
                                    fin = 1;
                                }
    
                            else
                                {
                                    compteur = TTF_RenderText_Blended(policeCompteur, compteurConverti, couleurBlanc);
    
                                    sprintf(tempsConverti, "Durée : %d '' %d", secondes, millisecondes);
                                    dureeTotale = TTF_RenderText_Shaded(policeCompteur, tempsConverti, couleurNoir, couleurBlanc);
                                    positionDuree.x = (1024-dureeTotale->w)/2;
                                    positionDuree.y = 200;
    
    
                                    texteRejouer = TTF_RenderText_Shaded(policeRejouer, "Tape n'importe quelle touche pour continuer...", couleurNoir, couleurBlanc);
                                    positionRejouer.x = (1024-texteRejouer->w)/2;
                                    positionRejouer.y = 600;
    
    
                                    if (secondes*1000+millisecondes < lireRecord(recordLu))
                                            {
                                            recordSecondes = secondes;
                                            recordMillisecondes = millisecondes;
                                            sprintf(recordConverti, "NOUVEAU RECORD !!! %d '' %d", recordSecondes, recordMillisecondes);
                                            texteRecord = TTF_RenderText_Shaded(policeCompteur, recordConverti, couleurRouge, couleurBlanc);
                                            positionRecord.x = (1024-texteRecord->w)/2;
                                            positionRecord.y = 50;
    
                                            recordEcrit = (recordSecondes * 1000 ) + recordMillisecondes;
                                            ecrireRecord(recordEcrit);
    
                                            victoire = TTF_RenderText_Shaded(policeCompteur, "BRAVO !", couleurNoir, couleurBlanc);
                                            positionVictoire.x = (1024-victoire->w)/2;
                                            positionVictoire.y = (768-victoire->h)/2;
                                            }
    
                                    else
                                        {
                                            victoire = TTF_RenderText_Shaded(policeCompteur, "Partie terminée... !", couleurNoir, couleurBlanc);
                                            positionVictoire.x = (1024-victoire->w)/2;
                                            positionVictoire.y = (768-victoire->h)/2;
    
                                        }
    
                                    do
                                        {
                                            SDL_WaitEvent(&event);
                                            switch(event.type)
                                                {
                                                    case SDL_QUIT:
                                                        continuer = 0;
                                                        break;
                                                    case SDL_KEYDOWN:
                                                        switch(event.key.keysym.sym)
                                                            {
                                                                case SDLK_ESCAPE:
                                                                    fin = 0;
                                                                    break;
                                                                default:
                                                                    fin = 0;
                                                                    break;
                                                            }
                                                    break;
                                                }
    
    
                                        SDL_BlitSurface(victoire, NULL, ecran, &positionVictoire);
                                        SDL_BlitSurface(dureeTotale, NULL, ecran, &positionDuree);
                                        SDL_BlitSurface(compteur, NULL, ecran, &positionCompteur);
                                        SDL_BlitSurface(texteRejouer, NULL, ecran, &positionRejouer);
                                        SDL_BlitSurface(texteRecord, NULL, ecran, &positionRecord);
    
                                        SDL_Flip(ecran);
    
                                        }while(fin);
    
                                        continuer = 0;
    
    
                                }
                         }
    
    
                       break;
    
    
                }
    
    
                SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, i, i, i));
    
                SDL_BlitSurface(regle, NULL, ecran, &positionRegle);
                SDL_BlitSurface(compteur, NULL, ecran, &positionCompteur);
                SDL_BlitSurface(texteRecord, NULL, ecran, &positionRecord);
                SDL_BlitSurface(chrono, NULL, ecran, &positionChrono);
    
                SDL_Flip(ecran);
    
        }while (continuer);
    
    
        TTF_CloseFont(policeRegle);
        TTF_CloseFont(policeCompteur);
        TTF_CloseFont(policeRejouer);
    
        SDL_FreeSurface(regle);
        SDL_FreeSurface(compteur);
        SDL_FreeSurface(victoire);
        SDL_FreeSurface(dureeTotale);
        SDL_FreeSurface(texteRejouer);
        SDL_FreeSurface(texteRecord);
        SDL_FreeSurface(chrono);
      }
    

    et le fichiers.c :

    #include <stdlib.h>
    #include <stdio.h>
    
    
    int lireRecord(int recordLu)
    {
        FILE* fichier = NULL;
    
        fichier = fopen("record.txt", "r");
    
        if (fichier == NULL)
               return 0;
    
        fscanf(fichier, "%d", &recordLu);
    
    
        fclose(fichier);
    
        return recordLu;
    }
    
    
    void ecrireRecord(int recordEcrit)
    {
        FILE* fichier = NULL;
    
        fichier = fopen("record.txt", "w+");
    
        if (fichier == NULL)
               return 0;
    
        fprintf(fichier, "%d", recordEcrit);
    
    
        fclose(fichier);
    
    }
    

    Et voilà, si quelqu'un a le temps d'y jeter un oeil, je l'en remercie d'avance.



    • Partager sur Facebook
    • Partager sur Twitter
      30 juin 2019 à 12:21:30

      Salut,

      J'ai pas tout regardé, mais voici déjà quelques conseils.

      • Indente mieux ton code. Là il y a des parties pas très lisibles.
      • Fais plus de fonctions. Une bonne fonction fais un truc et le fais bien. En général ça prend moins de trente lignes et je suis gentil.
      • Vérifie le retour des fonctions à risques.
      • Déclare tes variables au plus près de leur utilisation (et en les initialisant directement avec la valeur correcte si possible).
      • SDL_PollEvent est censé s'utiliser dans une boucle. Mais pour une meilleure gestion des évènements, je t'invite à aller lire le tutoriel de @Fvirtman sur le sujet.
      • Commence par faire un programme simple qui marche. Là je vois des trucs avec des nombres aléatoires, de la gestion des meilleurs scores, alors que l'idée principale (cliquer le plus possible) ne fonctionne pas encore.

      Et finalement, je ne peux que t'encourager à délaisser la SDL 1.2 pour passer à la SDL 2. Ça fait plus de cinq ans maintenant qu'elle est sortie et cinq ans c'est beaucoup.

      • Partager sur Facebook
      • Partager sur Twitter
      Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
        30 juin 2019 à 12:32:25

        Merci d'avoir répondu, je vais creuser les pistes. En fait avant de faire ce jeu, j'ai fait le nombre mystère, le pendu et le Sokoban de Mathéo et là comme je suis arrivé à la fin du cours, j'ai voulu faire un jeu tout seul avec ce que j'avais appris. Je sais bien que la SDL2 est sorti mais je voulais finir le cours avec la 1.2.

        En fait le jeu marche bien avec l'enregistrement du meilleur score, le chrono qui s'affiche mais que lorsque je clique. Après il y a des petits bugs, comme le fait de pouvoir commencer à cliquer avant la fin du décompte, le "1" du décompte qui s'affiche mal (on dirait qu'il reste une trace d'un chiffre affiché précemment), et enfin le fait de pouvoir taper au clavier alors que j'ai mis que les clics à la souris.

        En tout cas merci d'avoir pris le temps de répondre.

        Edit : Bon j'ai trouvé pourquoi il restait une trace du nombre lors du décompte, j'avais oublié le SDL_FillRect dans la boucle du décompte pour effacer l'écran...

        -
        Edité par BusshiBlanc 30 juin 2019 à 13:03:47

        • Partager sur Facebook
        • Partager sur Twitter
          30 juin 2019 à 15:25:14

          Hello,

          Pas tout lu, mais ligne 83 de jeu.c il manque un break. Les break des lignes 79 et 81 ne font que te sortir du switch de la ligne 76

          Mauvaise idée que du cumuler waitEvent() et PollEvent(). Il faut tout traiter dans une boucle, avec soit l'une soit l'autre:

          #include <stdbool.h>
          
          bool done=false;
          do
              if(SDL_PollEvent(&event))
                  switch(event.type) {
                      case SDL_QUIT:
                          done=true;
                          break;
                      case SDL_KEYDOWN:
                          done=event.key.keysym.sym==SDLK_ESCAPE;
                          break;
                      case SDL_MOUSEBUTONDOWN:
                          count++;
                          break;
                  }
          while(!done);

          -
          Edité par edgarjacobs 30 juin 2019 à 15:31:32

          • Partager sur Facebook
          • Partager sur Twitter

          On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

            30 juin 2019 à 16:39:11

            Merci c’est exactement ce que je recherchais. En fait il me manquait le if du SDL_PollEvent !! :) merci beaucoup.

            Le break manquant était la cause du problème du compteur qui s’incrémentait avec l’appui au clavier.

            il ne me reste plus qu’a trouver comment faire attendre le programme avant de compter les clics pendant le compte à rebours du début du jeu.

            • Partager sur Facebook
            • Partager sur Twitter
              1 juillet 2019 à 20:51:00

              Salut,

              Je te conseille de mettre :

              while(SDL_PollEvent(&event))
              {
              ...
              
              }

              Mieux que le if, il dépilera tous les events et évitera une accumulation.

              Car si par exemple tu t'énerves sur ta souris, et qu'elle fait davantage d'évents que de FPS, tu auras du lag avec le if. Pas avec le while.

              • Partager sur Facebook
              • Partager sur Twitter

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

              Pb chrono en SDL

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