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 :

Gestion des events


Sujet :

SDL

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Août 2006
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 213
    Points : 103
    Points
    103
    Par défaut Gestion des events
    Bonjour,

    Dans mon programme, j'ai une boucle principale situeé dans la fonction main(), où sont traités les événements principaux comme "quitter le programme" si on appui sur escape.

    Mon problème, c'est que j'ai une classe ou je veux également tester les evenements par exemple "se déplacer à droite" si on appui sur "->". Seulement, cette classe est appellée apres la gestion des evenements principaux, et à ce moment la, la variable event est nulle, puisque le SDL_PollEvent de la boucle principale a tout supprimé.

    Je cherche donc un moyen, pour que soit les événement soient tous enregistrer dans 2 variables distincts, soit que la boucle principale parcourt les événements sans les détruire.

    Voici grosso modo le code :

    main()

    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
    	//Boucle principale
    	while(!done)
    	{
     
    		//Gestion des événements clavier et sourie
    		while(SDL_PollEvent(&event))
    		{
    			switch(event.type)
    			{
    				case SDL_QUIT:
    					done = true;
    					break;
    				case SDL_KEYDOWN :
    					keys = SDL_GetKeyState(NULL);
    					if ( keys[SDLK_ESCAPE] ) {done = true;}
    					break;
    			}
     
    		}
     
    		//Joue la scene
                   Engine.PlayScene();
     
    		//Contrôle de la fréquence d'affichage
    		SDL_framerateDelay(&manager);
     
    		//Permuttation des écrans (double buffering)
    		SDL_GL_SwapBuffers();
     
     
    	}
    et ici une méthode appellée par Engine.PlayScene()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    		while(SDL_PollEvent(&event))
    		{
    			switch(event.type)
    			{
    				case SDL_QUIT:
    					done = true;
    					break;
    				case SDL_KEYDOWN :
    					keys = SDL_GetKeyState(NULL);
    					if ( keys[SDLK_RIGHT] ) {....;}
    					break;
    			}

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si tu veux du vrai orienté objet, le truc qui marche bien c'est une classe qui centralise les évènements, et auprès de laquelle on s'enregistre si l'on veut recevoir ceux-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
    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
    class EventListener;
     
    class EventManager // singleton ou truc du genre
    {
    public :
     
        void AddListener(EventListener* Listener) 
        {
            if (Listener)
                myListeners.insert(Listener);
        }
     
        void RemoveListener(EventListener* Listener) 
        {
            myListeners.erase(Listener);
        }
     
        void Update()
        {
            SDL_Event Event;
            while (SDL_PollEvent(&Event))
            {
                // convertir et dispatcher l'évènement aux écouteurs...
            }
        }
     
    private :
     
        std::set<EventListener*> myListeners;
    };
     
    class EventListener
    {
    public :
     
        virtual ~EventListener()
        {
            EventManager::GetInstance().RemoveListener(this);
        }
     
        virtual void OnKeyPressed(int Code) {}
        virtual void OnButtonPressed(int Code) {}
        virtual void OnResize(int Width, int Height) {}
     
    protected :
     
        EventListener()
        {
            EventManager::GetInstance().AddListener(this);
        }
    };
     
    class Game : public EventListener
    {
        ...
    };
     
    class Character : public EventListener
    {
        ...
    };

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Ce n'est pas la facon à faire. La plus propre est de gérer dans le main les messages importants SDL_QUIT par exemple.

    Et ensuite appelé une fonction pour gérer les autres événements. La fonction prendra un pointeur de type SDL_Event.

    Jc

  4. #4
    Membre régulier

    Profil pro
    Inscrit en
    Août 2006
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 213
    Points : 103
    Points
    103
    Par défaut
    Si j'ai bien compris, il faut que je fasse un truc de ce genre :

    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
    	while(!done)
    	{
             	while(SDL_PollEvent(&event))
    		{
    			switch(event.type)
    			{
    				case SDL_QUIT:
    					done = true;
    					break;
                                    .....
    			}
                            Engine.UpdateEvents(&event);	
    		}
                   Engine.PlayScene();
                   ...
    	}
    et dans Engine::UpdateEvents(SDL_Event event)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Editor->UpdateEvents(&event);
    et ainsi de suite jusqu'a la sous classe ou je teste les événements

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Août 2006
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 213
    Points : 103
    Points
    103
    Par défaut
    J'ai donc testé et sa marche correctement. Par contre, j'ai bien fait attention a passer une copie de event dans les méthodes, pour éviter que l'appelle de SDL_PollEvent(&event) dans les sous-tests n'effacent les événements de la boucle principal.

    Merci a vous.

  6. #6
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par BruceBoc
    J'ai donc testé et sa marche correctement. Par contre, j'ai bien fait attention a passer une copie de event dans les méthodes, pour éviter que l'appelle de SDL_PollEvent(&event) dans les sous-tests n'effacent les événements de la boucle principal.

    Merci a vous.
    Oui, c'est comme ca que c'est le mieux, généralement je fais comme ceci :

    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
    	while(!done)
    	{
             	while(SDL_PollEvent(&event))
    		{
    			switch(event.type)
    			{
    				case SDL_QUIT:
    					done = true;
    					break;
                                    .....
                                    default:
                                          Engine.UpdateEvents(&event);	
    			}
    		}
                   Engine.PlayScene();
                   ...
    	}
    Quelle est la différence ? Le main capture les messages les plus importants et les capture s'il le veut. Les messages ignorés passent au moteur. Le moteur peut en capturer avant de les faire passer au reste.

    Jc

  7. #7
    Membre régulier

    Profil pro
    Inscrit en
    Août 2006
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 213
    Points : 103
    Points
    103
    Par défaut
    C'est nickel, je crois que je vais faire comme ça.

    Merci encore FearYourself.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    433
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 433
    Points : 240
    Points
    240
    Par défaut
    Je confirme, j'ai adopté la structure de fearyourself dans mon projet et c'est une très bonne solution.

    Car par la suite, dans ton objet "Engine" tu peux ensuite choisir à nouveau ou rediriger l'évennement. Par exemple dans un jeu on peu avoir deux états: un menu et une phase jeu. La class Engine permet, à la reception d'un évennement, de switcher entre les deux états (à l'appuis sur Echap par exemple), et dans Engine.UpdateEvents() ensuite on regarde selon la variable d'état et on redirige l'évennement sur la phase en cours (dans la class Menu ou alors dans la class Jeu).

    Ainsi, si on est dans le menu, le jeu ne recevra plus d'évennement et restera figé (en gros).


    Note: marquer le topic comme "Résolu" serait une bonne chose.

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

Discussions similaires

  1. gestion des events dans MFC
    Par subzero01 dans le forum MFC
    Réponses: 2
    Dernier message: 04/07/2008, 15h37
  2. [débutant]gestion des Events
    Par sacoum dans le forum C++/CLI
    Réponses: 8
    Dernier message: 26/06/2008, 11h04
  3. [Conception] classes internes ou gestion des events
    Par TTKiBosse dans le forum Général Java
    Réponses: 2
    Dernier message: 06/12/2006, 18h25
  4. Gestion des event avec un objet ole MsExcel
    Par rdemont dans le forum Delphi
    Réponses: 3
    Dernier message: 03/07/2006, 16h08
  5. [C#] Gestion des Events d'un control Composite
    Par lord_paco dans le forum ASP.NET
    Réponses: 3
    Dernier message: 07/10/2005, 09h10

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