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

SFML Discussion :

Gestion des évènements


Sujet :

SFML

  1. #1
    Membre actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut Gestion des évènements
    Bonsoir tout le monde,

    je commence à peine à comprendre quelques notions du C++ en utilisant la librairie SFML comme me l'a conseillé "ternel" , mais il y a une chose très importante, et que je n'arrive toujours pas à cerner, c'est les évènements, chaque librairie graphique propose sa propre méthode de gestion d'évènement (Signal/Slot) pour Qt par exemple, même chose pour le projet TGUI issu de SFML. Mais là (en SFML tout court), je ne trouve que la boucle principale, donc ma question est : comment je pourrais gérer un ou plusieurs évènements pour chaque élément graphique (un primitif) ?

    voici ce que j'ai pu créer avec la boucle principale, le problème c'est que l'évènement au lieu d'être partagé il est dupliqué (j'avais essayé avec des fonctions static mais le résultat était pire) :

    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
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include "CButton.h"
     
     
    int main()
    {
        sf::RenderWindow window(sf::VideoMode(800, 600), "GUITest");
     
     
        std::vector<CButton> mesRec;
     
     
     
        while (window.isOpen())
        {
            sf::Event event;
     
            while (window.pollEvent(event))
            {
     
               if (event.type == sf::Event::Closed)
               {
                    window.close();
               }
     
               if (event.type == sf::Event::Resized) {
                    window.setView(sf::View(sf::FloatRect(0, 0, event.size.width, event.size.height)));
     
               }
     
     
                   if (event.type == sf::Event::KeyPressed)
                   {
     
                       if(event.key.code == sf::Keyboard::A)
                       {
     
                           mesRec.push_back(CButton(50,50));
     
                       }
     
                   }
     
     
                 for(unsigned int i = 0; i < mesRec.size(); i++)
                 {
     
                   mesRec[i].movement(event);
     
                 }
     
     
         }
     
            window.clear(sf::Color(128,128,128));
     
            for(unsigned int i = 0; i < mesRec.size(); i++)
            {
     
                window.draw(mesRec[i].getbtn());
     
            }
     
     
            window.display();
     
        }
     
        return 0;
    }

    CButton (Header)
    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
     
    #ifndef CBUTTON_H
    #define CBUTTON_H
     
    #include <SFML/Graphics.hpp>
    #include <iostream>
     
     
    class CButton
    {
        public:
     
            CButton();
            CButton(int c_width,int c_height,int c_x = 50,int c_y = 50);
            virtual ~CButton();
            sf::RectangleShape getbtn();
            void movement(sf::Event &event);
     
        private:
     
            /******************************************/
            bool isInside(int x, int y);
            bool isPressed;
            bool wasInside;
            int xOffset;
            int yOffset;
            /******************************************/
            sf::RectangleShape c_Button;
     
    };
     
    #endif // CBUTTON_H
    CButton (Source)
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    #include "CButton.h"
     
    CButton::CButton()  :c_Button(sf::Vector2f(60,25))
    {
     
     
    /******************************************/
    isPressed = false;
    wasInside = false;
    xOffset = 0;
    yOffset = 0;
    /******************************************/
     
    }
     
    CButton::CButton(int c_width,int c_height,int c_x,int c_y)
                 : c_Button(sf::Vector2f(c_width,c_height))
    {
     
       c_Button.setPosition(sf::Vector2f(c_x,c_y));
     
       /**********RANDOM COLOR***********/
     
       c_Button.setFillColor(sf::Color((rand() % 256),(rand() % 256),(rand() % 256)));
     
       /*********************************/
     
       isPressed = false;
       xOffset = 0;
       yOffset = 0;
     
     
    }
     
    CButton::~CButton()
    {
        //dtor
    }
     
     
    sf::RectangleShape CButton::getbtn(){
     
        return c_Button;
     
    }
     
    /******************************************/
     
     
    void CButton::movement(sf::Event &event){
     
           if (event.type == sf::Event::MouseButtonPressed)
           {
     
     
               if (event.mouseButton.button == sf::Mouse::Left)
               {
     
                   std::cout << "IS PRESSED "<< std::endl;
                   isPressed = true;
                   wasInside = isInside(event.mouseButton.x,event.mouseButton.y);
                   if(wasInside)
                   {
                   xOffset = c_Button.getPosition().x - event.mouseButton.x;
                   yOffset = c_Button.getPosition().y - event.mouseButton.y;
     
                   }
     
               }
     
           }
     
     
           if (event.type == sf::Event::MouseButtonReleased)
           {
     
                   std::cout << "IS RELEASED "<< std::endl;
                   isPressed = false;
                   wasInside = false;
     
           }
     
     
     
           if (event.type == sf::Event::MouseMoved){
     
     
                 if(isPressed && wasInside){
     
                   std::cout << "IS DRAGGED "<< std::endl;
                   c_Button.setPosition((event.mouseMove.x + xOffset),(event.mouseMove.y + yOffset));
     
                 }
     
           }
     
     
    }
     
     
    bool CButton::isInside(int x, int y){
     
        if(  x >= c_Button.getPosition().x && x <= (c_Button.getPosition().x+c_Button.getSize().x)
          && y >= c_Button.getPosition().y && y <= (c_Button.getPosition().y+c_Button.getSize().y)){
     
         return true;
     
         }else{
     
         return false;
     
         }
     
    }
    Je tiens à préciser que ce code fonctionne (sans bug ni rien) mais je sens qu'il y a des choses qui sont mal faites. Merci pour votre aide !

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Salut,

    tu as bien trouvé la bonne fonction, tu poll les évènements puis tu les dispatch à chaque élément de ton jeu.
    Il s'agit d'architecturer le tout pour que l'évènement arrive au bon endroit et soit intercepté par les bons éléments.
    Classiquement j'ai toujours une classe de EventManager qui sert de dispatch, chaque élément qui peut intercepter un évènement est un EventListener.
    Un EventListener possède toutes les fonctions nécessaires OnMouseMove, OnMouseClick etc... qui return true si l'évènement doit continuer sa propagation, false sinon.
    Les EventListener sont en général une classe de GuiManager où chaque élément de GUI s'enregistre, c'est le listener à plus haute priorité puisque la GUI est affichée on top, puis vient le Gameplay, et enfin éventuellement d'autres choses (gestionaire de scripts, trucs en background, ...).

  3. #3
    Membre actif
    Avatar de guatto
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2014
    Messages : 179
    Points : 226
    Points
    226
    Par défaut
    C'est ce que j'avais pensé moi aussi (en ayant parlé des fonctions static) et je suis revenu dessus pour aboutir à une solution qui me semble la plus adaptée, voici le code complet :

    Gestion (Header) :
    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
     
    #ifndef GESTION_H
    #define GESTION_H
     
    #include <iostream>
    #include <SFML/Graphics.hpp>
     
    class Gestion
    {
        public:
     
            Gestion();
            virtual ~Gestion();
            static void movement(sf::Event &event, std::vector<sf::RectangleShape> &objets);
     
        private:
     
            static bool isInside(int x, int y, sf::RectangleShape &objet);
            static sf::RectangleShape getElmUnder();
            static bool isPressed;
            static bool wasInside;
            static int xOffset;
            static int yOffset;
            static sf::RectangleShape *hovered;
     
    };
     
    #endif // GESTION_H
    Gestion (Source) :
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    #include "Gestion.h"
     
      bool Gestion::isPressed = false;
      bool Gestion::wasInside = false;
      int Gestion::xOffset = 0;
      int Gestion::yOffset = 0;
      sf::RectangleShape *Gestion::hovered(0);
     
     
    Gestion::Gestion(){}
     
    Gestion::~Gestion(){}
     
    void Gestion::movement(sf::Event &event, std::vector<sf::RectangleShape> &objets){
     
          if (event.type == sf::Event::MouseButtonPressed)
           {
     
               if (event.mouseButton.button == sf::Mouse::Left)
               {
     
                   std::cout << "IS PRESSED "<< std::endl;
                   isPressed = true;
     
                   for(unsigned int i = objets.size(); i >= 0; --i)
                   {
     
                       if(!wasInside)
                       {
     
                        wasInside = isInside(event.mouseButton.x,event.mouseButton.y, objets[i]);
     
                       }else
                       {
     
                        break;
     
                       }
     
                   }
     
     
                   if(wasInside)
                   {
     
                   xOffset = hovered->getPosition().x - event.mouseButton.x;
                   yOffset = hovered->getPosition().y - event.mouseButton.y;
     
     
                   }
     
               }
     
           }
     
     
           if (event.type == sf::Event::MouseButtonReleased)
           {
     
                   std::cout << "IS RELEASED "<< std::endl;
                   isPressed = false;
                   wasInside = false;
     
           }
     
     
     
           if (event.type == sf::Event::MouseMoved){
     
     
                 if(isPressed && wasInside){
     
                   std::cout << "IS DRAGGED "<< std::endl;
                   hovered->setPosition((event.mouseMove.x + xOffset),(event.mouseMove.y + yOffset));
     
                 }
     
           }
     
    }
     
    bool Gestion::isInside(int x, int y, sf::RectangleShape &objet){
     
        if(  x >= objet.getPosition().x && x <= (objet.getPosition().x+objet.getSize().x)
          && y >= objet.getPosition().y && y <= (objet.getPosition().y+objet.getSize().y))
    	{
     
    	  hovered = &objet;
          return true;
     
        }else{
     
           return false;
     
        }
     
    }
    J'espère juste ne pas m'être trompé sur l'encapsulation, j'attendrai votre réponse si vous voulez bien merci !

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

Discussions similaires

  1. [XML] [EXPAT] xml_parse et la gestion des événements...
    Par Herode dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 05/02/2006, 20h59
  2. Gestion des évènements Netscape 7.0
    Par RATHQUEBER dans le forum Autres langages pour le Web
    Réponses: 6
    Dernier message: 19/12/2005, 16h26
  3. Problème avec la gestion des événements
    Par CynO dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/10/2005, 10h07
  4. [JTable] gestion des événements
    Par soulhouf dans le forum Composants
    Réponses: 4
    Dernier message: 19/08/2005, 13h21
  5. Gestion des évènements lors d'un clique sur une image.
    Par yoghisan dans le forum Débuter
    Réponses: 7
    Dernier message: 23/06/2005, 19h04

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