IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

SDL - Gestion d'un événement dans une boucle


Sujet :

SDL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut SDL - Gestion d'un événement dans une boucle
    Bonjour à tous,

    je me permet de requérir à votre aide.
    Je viens de dessiner dans un axe Oxy mon signal provenant d'une classe extérieure. Je voudrai maintenant y ajouter des boutons afin de changer les échelles,..
    Mais avant de créer un bouton je voudrai juste gérer les évènements. Je commence par le plus simple: appuyer sur 'echap' et cela ferme le programme.
    Pour le moment lorsque j'appuie sur 'echap' mon programme arrête de dessiner et lorsque je relâche il continue de dessiner.
    J'ai mis ci-dessous, les grandes lignes de mon programme.
    J'ai beau le retourner dans tous les sens, je n'arrive pas à gérer cet évènement, et du coup je n'arrive pas à gérer les autres.

    Merci par avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    SDL_SURFACE *screen,*graph;
     
    //screen est ma fenetre principale
    //graph est ma fenetre pour le dessin
     
    SDL_INIT_VIDEO
    screen = SDL_SetVideoMode
    graph = SDL_CreateRGBSurface
     
    int continuer =1;
    while (continuer)
    	{
    		SDL_FillRect(screen,..);
     
    		for (j=0;j<10;j++)
    		{
    			SDL_Rect position_graph; position_graph.x =10; position_graph.y=30;
    			SDL_FillRect(graph,..);
    			SDL_BlitSurface(graph);
     
    			int i;
    			for(i=0;i<9;i++)
                             {ligne();//fonction qui trace une ligne}
    			/* encore plein de petites boucles afin de dessiner mes axes et graduations */
     
    			for (i=j*640;i<640+j*640;i++) //ma fenetre de dessin fait 640 pixels de large
    			{
    				SDL_PollEvent(&event);
    				switch(event.type)
    				{
    					case SDL_QUIT:
    						continuer =0;
    					case SDL_KEYDOWN:
    						switch(event.key.keysym.sym)
    						{
    							case SDLK_ESCAPE:
    							continuer =0;
    							break;
     
    							default:
    							break;
    						}
     
    					break;
    					default:
    					putpixel(i%640+40,(signal.param[i]*80+370)); //affichage des points de mon signal. Signal contenu dans un tableau d'un classe annexe.
    				}
     
    				SDL_Flip(screen);
    			} 
    		} 
     
    	} 
     
    	SDL_FreeSurface(graph);
    	SDL_Quit();

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    As mon avis tu px jetter ton code a la poubelle (ou du moins le recommencer en grosse partie).

    Tu as bien lu http://loka.developpez.com/tutoriel/sdl/ ?

    La gestion des events, ne doit certainement pas se faire dans tes boucles for (remplace certainement par surement).

    Decouple bien l'affichage et la gestion des evenement pour les mettre "au meme niveau" et ne pas imbriquer la gestion des event dans la boucle qui te sert a "dessiner".
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    ok, merci du conseil.
    je vais relire le tuto, et refaire mon code.

  4. #4
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    En général, les tâches se decomposent comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    - initialisation sdl (et ttf si nécessaire)
    - affichage
    - tant que l'utilisateur ne demande pas l'arrêt
          - attendre la commande utilisateur (SDL_WaitEvent)
          - traiter la commande (ce qui peut bien sur impliquer recalculs, affichage...)
    - libération mémoire
    - fermeture sdl (et ttf éventuellement)
    Une variante que l'on trouve régulièrement dans la boucle d'attente de la commande est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    - tant que l'utilisateur ne demande pas l'arrêt
         - vérifier si une commande est donnée (SDL_PollEvent)
         - si commande, la traiter *
         - effectuer une/des tache(s) *
    * inversables bien entendu
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    merci pour cette vue globale d'un projet !!

    Et pour ma part je me tournerai plus facilement vers SDL_PollEvent, puisque je vais dessiner des données en temps réel et que le programme dessine et n'attend pas un/des évènement(s) de la part de l'utilisateur.

    Encore merci pour cette info !

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    bonjour, j'ai utilisé le plan fourni par edgarjacobs. en effet cela fonctionne(lorsque j'appuie sur echap le programme se ferme). Mais je n'arrive plus a voir mon signal défiler.
    Mon signal est contenu dans un tableau.
    une fois que la première partie du signal a atteint l'extrémité droite de la fenêtre de dessin, je redessine cette fenêtre et je fais apparaître le deuxième partie du signal,. etc.. jusqu'à la fin de mon signal.

    je fais donc:
    -initialisation
    -affichage de ma fenêtre de dessin et de mon signal(entier)
    -tant que l'utilisateur ne demande pas l'arrêt
    -libération mémoire
    -fermeture sdl

    je comprends bien qu'une fois que mon signal a été affiché en entier je ne pourrai plus agir sur lui.
    pour afficher mon signal(qui contient 64 000 points) dans une fenêtre de dessin de 640pixels je fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (j=0;j<10;j++)
    {
      for (i=j*640;i<640+j*640;i++)
      putpixel(i%640+40,(signal.param[i]*80+370));
    }
    la question est donc : comment agir sur mon signal sachant qu'il se trouve dans une boucle sachant que wax78 m'a répondu :
    Decoupe bien l'affichage et la gestion des evenement pour les mettre "au meme niveau" et ne pas imbriquer la gestion des event dans la boucle qui te sert a "dessiner".
    Je n'arrive pas a séparer les events et le dessin.

    je ne sais pas si c'est assez clair, et je m'en excuse par avance.

  7. #7
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    Je ne connais pas ton programme, mais je verrais bien une structure comme celle-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    void afficheSignal(int *positionDebut,....)
    {
    ...
        (*positionDebut)+=qqChose;
    }
     
    void traitement(...)
    {
        positionDebut=0;
        afficheSignal(&positionDebut,...);
        done=0;
        while(!done) {
            if(SDL_PollEvent(&event)) {
                // Traiter l'event
                }
            if(....) dessineSignal(&positionDebut,....);
            }
    }
    mais je n'ai peut-être pas compris ton problème.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Bonjour,


    J'ai simplifié mon problème.
    j'ai un tableau de 2000points que je remplis.
    je voudrai afficher les 600premiers points en continu, c'est-à-dire que tant que l'on ne fait rien le programme affiche les 600premiers points.
    Lorsque l'on appuie sur la touche 'a', il va par exemple afficher du point 500 au point 1100. Et si l'on ne touche a rien il va continuer a afficher les points de 500 à 1100, et va attendre une autre touche qui va afficher un autre intervalle etc...

    Pour cela j'ai utilisé vos méthodes AfficheSignal() et Traitement()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void AfficheSignal(int *PositionDebut)
    {
        int x =2; //commence a dessiner a partir du 2eme pixel a partir du bord de la fenetre
        for (int i = 0;i<NOMBREPRINT;i++) //boucle qui dessine sur 600 pixels
        {
            ligne (x,result[i+(*PositionDebut)]*30+240, x+1,result[i+(*PositionDebut)+1]*30+240,vert);
            x+=1;
     
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    void traitement()
    {
        int positionDebut = 0;
        AfficheSignal(&positionDebut); // va afficher les 600 premiers points de mon signal
        bool done = false;
        while (!done)
        {
            // message processing loop
            SDL_Event event;
            while (SDL_PollEvent(&event))
            {
                // check for messages
                switch (event.type)
                {
                    // exit if the window is closed
                case SDL_QUIT:
                    done = true;
                    break;
     
                    // check for keypresses
                case SDL_KEYDOWN:
                    {
                        // exit if ESCAPE is pressed
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                            done = true;
                        break;
                        if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                               AfficheSignal(&positionDebut+700) ; //va afficher mon signal a partir du 700ème point
                        break;
                    }
                } // end switch
            } // end of message processing
     
     
            // DRAWING STARTS HERE
     
            // clear screen
            SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
     
     
     
            // DRAWING ENDS HERE
     
            // finally, update the screen :)
            SDL_Flip(screen);
        }
     
    }
    le problème est ,je pense,que je ne sors pas de la boucle while(!done), mon programme compile mais crash à l'execution.
    Je suis désolé mais j'ai vraiment du mal avec ces events.

  9. #9
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Et a quel endroit crash-t-il exactement ?
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    j'ai résolu mon problème d'execution.
    donc maintenant il m'ouvre ma fenetre vierge, mais je ne vois aucun dessin apparaitre. par hasard j'ai appuyé sur ma touche 'a', au cas où, mais toujours pas de dessin.

  11. #11
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    C'est parce que, lorsque tu sors de ton while(SDL_PollEvent(&event)), tu redessines et affiches une fenêtre noire.

    De plus, dans ta fonction AfficheSignal, je ne vois pas de SDL_UpdateRect() ou de SDL_Flip(). Donc, même si ton image est bien fabriquée en mémoire, elle n'est jamais envoyée à l'écran (sauf si la fonction ligne() le fait).
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    Bonjour, alors j'ai corrigé avec ce que vous m'avez dit. En effet je n'avais pas de mise à jour d'écran dans ma fonction AfficheSignal (ni dans ma fonction ligne() ).

    Du coup mon programme affiche bien mes premiers points, mais lorsque j'appuie sur la touche 'a', il ne se passe rien. (par contre lorsque j'appuie sur 'Echap', le programme se termine bien.)

    Du coup je me permet de remettre mes deux fonctions corrigées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    void AfficheSignal(int *PositionDebut)
    {
        Uint32 vert = SDL_MapRGB(screen->format,0,255,0); //definition de la couleur du signal
        int x =2;   //commence a dessiner a partir du 2eme pixel a partir du bord de la fenetre
        for (int i = 0;i<NOMBREPRINT;i++) //boucle qui dessine sur 600 pixels
        {
            ligne (x,result[i+(*PositionDebut)]*30+240, x+1,result[i+(*PositionDebut)+1]*30+240,vert);//le coeff *30+240 permet de visualiser le signal en le placant au centre de la fenetre et en augmentant son gain
            x++;
     
        }
        SDL_Flip(screen); //mise a jour de l'ecran
     
    }
     
    void traitement()
    {
        int positionDebut = 0;
        AfficheSignal(&positionDebut); // va afficher les 600 premiers points de mon signal
     
     
        bool done = false;
        while (!done)
        {
            // message processing loop
            SDL_Event event;
            while (SDL_PollEvent(&event))
            {
                // check for messages
                switch (event.type)
                {
                    // exit if the window is closed
                case SDL_QUIT:
                    done = true;
                    break;
     
     
                case SDL_KEYDOWN:
                    {
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                            done = true;
                        break;
                        if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                            {
                                positionDebut=600;
                                AfficheSignal(&positionDebut); //va afficher mon signal a partir du 600ème point
                            }
                        break;
                    }
                } // end switch
            } // end of message processing
        }
    }
    mon programme pour le moment affiche mes premiers points et c'est tout, je ne peux donc toujours pas intéragir avec lui sauf en le quittant.

  13. #13
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    c'est en postant mon dernier message que j'ai trouvé la solution,
    j'ai par hasard tapé sur la lettre 'q' a la place de 'a' et cela a marché, je ne sais pourquoi. (certainement que SDL est codé sur un clavier QWERTY, non ?)
    et il y avait une erreur dans mon switch(event.type)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    case SDL_KEYDOWN:
                    {
     
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                            done = true;
                            //break;
     
                       else if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                            {
                                SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); //remplit ma fenetre de blanc
                                positionDebut=600;
                                AfficheSignal(&positionDebut); //va afficher mon signal a partir du 600ème point
                            }
                        break;
    }
    l'erreur était au niveau du break et des if, mon problème est donc résolu.

    Merci beaucoup !!

  14. #14
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    J'ai exactement le même problème, et je ne sais pas pourquoi*.

    Je l'ai contourné dans un de mes programmes, en ajoutant l'instruction
    et en testant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(event.key.keysym.unicode=='a')
    Mais attention: a=97, A=65, ctrl+(shift+)a=1, b=98, B=66, ctrl+(shift+)b=2 etc..., et ce genre de test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(event.key.keysym.unicode=='a' && event.key.keysym.mod&KMOD_CTRL)
    ne fonctionne plus...

    EDIT: *après avoir fait quelques tests, il s'agit simplement de la disposition du clavier QWERTY...
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    j'ai contourné ce problème en choisissant des touches qui étaient communes a qwerty et azerty, puisque le choix des touches ne m'importe que très peu, mais merci du conseil !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. gestion des erreurs dans une boucle
    Par shimomura22 dans le forum C#
    Réponses: 4
    Dernier message: 17/04/2015, 09h51
  2. Gestion de variables dans une boucle
    Par DoumCSS dans le forum Langage
    Réponses: 4
    Dernier message: 25/04/2013, 12h26
  3. Gestion d'erreur dans une boucle
    Par frto0 dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 07/10/2010, 10h06
  4. Gestion des erreurs dans une boucle While
    Par Gregory.M dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 12/08/2008, 20h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo