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 :

Pb traitement d'evenements


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de donkeyquote
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 195
    Par défaut Pb traitement d'evenements
    Hello,

    J'ai un petit souci avec le traitement d'evenements de la SDL que j'essaie d'apprendre et pratiquer.

    En fait dans le code que je vous joint, lors du traitement d'un evenement, quelque soit la touche que je frappe, il m'affiche les 2 messages superposes...

    L'idee c'est d'afficher le message contenu par aUpPressedKey quand j'appuie sur la fleche du curseur "up" et aDownPressedKey quand j'appuie sur la fleche du curseur "down".

    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
    58
    59
    60
    61
     
    	//Un moyen de s'assurer que le programme va nous attendre pour quitter 
    	bool aQuit = false;
     
    	//Tant que l'utilisateur ne veut pas quitter 
    	while( aQuit == false ) 
    	{
    		//Tant qu'il y a un événement à traiter 
    		while( SDL_PollEvent( &aEvent ) ) 
    		{
    			//Si l'utilisateur a cliqué sur le X de la fenêtre
    			if( aEvent.type == SDL_QUIT ) 
    			{ 
    				//On quitte le programme 
    				aQuit = true; 
    			} 
     
     
    			if( aEvent.type == SDL_KEYUP ) 
    			{
    std::cout<<"UP"<<std::endl;
     
    				if( aUpKeyPressed != NULL ) 
    				{ 
    					SDL_Surface * aOptimizedMessage = Tools::loadText( aUpKeyPressed );
     
    					Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
     
    					//On met à NULL le pointeur vers la surface message 
    					aUpKeyPressed = NULL;
    				}
     
    				//Mise à jour de l'écran 
    				if( SDL_Flip( aScreen ) == -1 ) 
    				{ 
    					return 1; 
    				}
    			}
     
    			if( aEvent.type == SDL_KEYDOWN ) 
    			{
    std::cout<<"DOWN"<<std::endl;
    				if( aDownKeyPressed != NULL ) 
    				{ 
    					SDL_Surface * aOptimizedMessage = Tools::loadText( aDownKeyPressed );
     
    					Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
     
    					//On met à NULL le pointeur vers la surface message 
    					aDownKeyPressed = NULL;
    				}
     
    				//Mise à jour de l'écran 
    				if( SDL_Flip( aScreen ) == -1 ) 
    				{ 
    					return 1; 
    				}
    			}
     
    		}
    	}
    Vous savez ce que je fais de mal?

    Merci d'avance

  2. #2
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    Salut a toi ^^

    C'est normal.

    En fait SDL_KEYDOWN et SDL_KEYUP ne correspondent pas a la fleche haut ou a la fleche bas. Ils correspondent au evenement.

    SDL_KEYDOWN : Touche appuyé
    SDL_KEYUP : Touche relaché

    si tu veux détecter quelle touche a été appuyer, tu dois utiliser la "sous-variable" event.key.keysym.sym.

    De plus, pour plus de clarté (et surtout pour pouvoir rajouter facilement des événement ou même d'autre touche), je te conseil fortement d'utiliser un switch case.

    Je n'ai pas tester le code en dessous mais il devrait marcher :

    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
     
     
     
    	//Un moyen de s'assurer que le programme va nous attendre pour quitter 
    	bool continuer = true;
     
    	//Tant que l'utilisateur ne veut pas quitter 
    	while( continuer  ) 
    	{
    		//Tant qu'il y a un événement à traiter 
                    SDL_Event event;
    		while( SDL_PollEvent( &event ) ) 
    		{
     
                           switch(event.type) /* On teste le type d'évènement */
                           {
                                   case SDL_QUIT: /* Si c'est un évènement QUITTER */
                                          continuer = false; /* On met le booléen à 0, donc la boucle va s'arrêter */
                                          break;
     
                                   case SDL_KEYDOWN: /* Si appui d'une touche */
                                           switch (event.key.keysym.sym)
                                           {
                                                    case SDLK_UP: /* Appui sur la touche haut */
                                                           std::cout<<"UP"<<std::endl;
                                                           break;
                                                    case SDLK_DOWN: /* Appui sur la touche bas */
                                                           std::cout<<"DOWN"<<std::endl;
                                                           break;
                                           }
                                          break;
                            }
     
     
    		//Mise à jour de l'écran, UN SEUL dans la boucle ! 
    		if( SDL_Flip( aScreen ) == -1 ) 
    		{ 
    			return 1; 
    		}
    	}

    Pour ce qui est de l'affichage, je te fais confiance car je n'ai pas compris comment tu faisais.

    Si tu veux avoir des information sur la gestion des événement, il y a des bon tutos sur developpez.

    En espérant ne pas avoir dit de connerie et avoir répondu a tes questions

  3. #3
    Membre confirmé Avatar de donkeyquote
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    195
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 195
    Par défaut
    Hello,

    Merci bcp pour ta reponse , ca marche tres bien et tes explications et ton example sont tres pedagogiques.

    Par contre les images se superposent quand on frappe "up" et en suite "down" et vice-versa... j'ai essaye de faire disparaitre l'un des surfaces de texte quand l'autre est appelee en liberant la memoire alloue par la surface de texte mais j'ai pas eu de succes... et je ne sais pas si ca se fait comme ca... :S

    Le code que j'ai tente est le suivant:
    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
    58
    59
    60
     
    	//Un moyen de s'assurer que le programme va nous attendre pour quitter 
    	bool aContinue = true;
     
    	//Tant que l'utilisateur ne veut pas quitter 
    	while( aContinue ) 
    	{
    		//Tant qu'il y a un événement à traiter 
                    SDL_Event aEvent;
    		while( SDL_PollEvent( &aEvent ) ) 
    		{
     
                           switch(aEvent.type) /* On teste le type d'évènement */
                           {
    				case SDL_QUIT: /* Si c'est un évènement QUITTER */
    					aContinue = false; /* On met le booléen à 0, donc la boucle va s'arrêter */
    					break;
     
    				case SDL_KEYDOWN: /* Si appui d'une touche */
    				{
    					SDL_Surface * aOptimizedMessage = NULL;
     
    					switch (aEvent.key.keysym.sym)
    					{
                                                    case SDLK_UP: /* Appui sur la touche haut */
    						{
    							std::cout<<"UP"<<std::endl;
    							if (aMessage != NULL)
    								SDL_FreeSurface(aMessage);
     
    							aMessage = TTF_RenderText_Solid( aFont, "Upkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
     
                                                    case SDLK_DOWN: /* Appui sur la touche bas */
    						{
    							std::cout<<"DOWN"<<std::endl;
    							if (aMessage != NULL)
    								SDL_FreeSurface(aMessage);
     
    							aMessage = TTF_RenderText_Solid( aFont, "Downkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
    					}
    					break;
    				}
                            }
     
     
    			//Mise à jour de l'écran, UN SEUL dans la boucle ! 
    			if( SDL_Flip( aScreen ) == -1 ) 
    			{ 
    				return 1; 
    			}
    		}
    	}
    Pouvez vous me donner un coup de main avec ca ?

    Merci d'avance!

  4. #4
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    salut,

    Bon, j'ai du mal a explique comment résoudre ton problème, alors je vais tenter l'explication suivante:

    Ta fenêtre est une SDL_Surface conservé en mémoire.
    Lorsque tu fais Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    tu viens modifier la SDL_Surface aScreen en mémoire.

    Du coup aScreen contient ton fond d'ecran (noir par défaut, ce qui est le cas chez toi je suppose) avec la modification engendrer par l'appel a Tools::applySurface.
    aScreen contient donc un fond noir avec ecrit dessus "Up key as been pressed".

    Ensuite tu fais appel a SDL_Flip(aScreen) qui effectue son boulot et affiche la surface aScreen.

    Alors d'ou vient ton probleme ?

    Il vient du fait que la modification par Tools::applySurface est permanente TANT QUE une autre surface n'est pas blitter dessus.
    Si tes message se superpose, cela vient du fait que la surface ou va etre coller ton prochain message a deja ete modifier de facon permanente par ton ancien message.

    Alors voici une solution, elle tient en une ligne :

    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
    58
    59
    60
    61
    62
    63
     
            // Permet de se passer des std:: ->  std::cout devient cout
            using namespace std;
     
    	//Un moyen de s'assurer que le programme va nous attendre pour quitter 
    	bool aContinue = true;
     
    	//Tant que l'utilisateur ne veut pas quitter 
    	while( aContinue ) 
    	{
    		//Tant qu'il y a un événement à traiter 
                    SDL_Event aEvent;
    		while( SDL_PollEvent( &aEvent ) ) 
    		{
     
    			// La solution, SDL_FillRect avec le 2eme parametre a NULL ( premet de remplir TOUT l'ecran )
    			// La couleur du fond d'ecran sera ici noir 
    			SDL_FillRect(aSreen, NULL, SDL_MapRGB(aScreen->format, 0, 0, 0));
     
                           switch(aEvent.type) /* On teste le type d'évènement */
                           {
    				case SDL_QUIT: /* Si c'est un évènement QUITTER */
    					aContinue = false; /* On met le booléen à 0, donc la boucle va s'arrêter */
    					break;
     
    				case SDL_KEYDOWN: /* Si appui d'une touche */
    				{
    					SDL_Surface * aOptimizedMessage = NULL;
     
    					switch (aEvent.key.keysym.sym)
    					{
                                                    case SDLK_UP: /* Appui sur la touche haut */
    						{
    							cout <<"UP"<< endl;
     
    							aMessage = TTF_RenderText_Solid( aFont, "Upkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
     
                                                    case SDLK_DOWN: /* Appui sur la touche bas */
    						{
    							cout <<"DOWN"<< endl;
     
    							aMessage = TTF_RenderText_Solid( aFont, "Downkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
    					}
    					break;
    				}
                            }
     
     
    			//Mise à jour de l'écran, UN SEUL dans la boucle ! 
    			if( SDL_Flip( aScreen ) == -1 ) 
    			{ 
    				return 1; 
    			}
    		}
    	}

    En fait, a chaque passage de boucle, tu remplie totalement ton ecran de noir, ce qui a pour effet "d'effacer" les message.
    Il faut dabord remplir de noir et ensuite afficher le nouveau message car sinon on ne verrait pas le nouveau message ( celui ci serait recouvert par le SDL_Fill_Rect avant d'etre vu ).
    Avec ce code, quand tu relache la touche, ton message doit normalement ( j'ai pas tester ^^') s'effacer.
    Si tu veux que ton message reste a l'ecran meme apres avoir relacher la touche, il suffit de dire que tu ne veux pas remplir ton ecran de noir tout le temps mais seulement quand on appuie sur une touche ( pour effacer le message deja present ).
    Le code devient donc :

    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
     
            using namespace std;
     
    	bool aContinue = true;
    	while( aContinue ) 
    	{
                    SDL_Event aEvent;
    		while( SDL_PollEvent( &aEvent ) ) 
    		{
                           switch(aEvent.type) 
                           {
    				case SDL_QUIT: 
    					aContinue = false; 
    					break;
     
    				case SDL_KEYDOWN: 
    				{
                                           // Seul et unique modification pour permettre d'afficher le message même si la touche est relâché
                                            SDL_FillRect(aSreen, NULL, SDL_MapRGB(aScreen->format, 0, 0, 0));
    					SDL_Surface * aOptimizedMessage = NULL;
     
    					switch (aEvent.key.keysym.sym)
    					{
                                                    case SDLK_UP:
    						{
    							cout <<"UP"<< endl;
     
    							aMessage = TTF_RenderText_Solid( aFont, "Upkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
     
                                                    case SDLK_DOWN: 
    						{
    							cout <<"DOWN"<< endl;
     
    							aMessage = TTF_RenderText_Solid( aFont, "Downkey has been pressed", aTextColor );
    							aOptimizedMessage = Tools::loadText( aMessage );
    							Tools::applySurface( 100, 400, aOptimizedMessage, aScreen );
    						}
    						break;
    					}
    					break;
    				}
                            }
     
     
    			if( SDL_Flip( aScreen ) == -1 ) 
    			{ 
    				return 1; 
    			}
    		}
    	}
    Voila, voila
    J'espère ne pas avoir été trop confus et assez clair.
    Si j'ai dit une connerie, corrigé moi.

    Bonne soirée a tous

Discussions similaires

  1. Réponses: 4
    Dernier message: 24/05/2011, 21h44
  2. Traitement lourd et Evenement
    Par alacaraibe dans le forum C#
    Réponses: 6
    Dernier message: 14/05/2009, 15h28
  3. Problème avec traitement des evenements bouton
    Par ramon.dekker dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 11/09/2008, 09h13
  4. Evenement prévenir traitement terminer
    Par birdy85 dans le forum VB.NET
    Réponses: 1
    Dernier message: 01/01/2008, 19h56
  5. Réponses: 4
    Dernier message: 04/07/2006, 09h35

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