Partage
  • Partager sur Facebook
  • Partager sur Twitter

Besoin de la fenêtre d'une class dans plusieurs autres class (SFML)

Héritage ? Singleton ? ...

Sujet résolu
    13 février 2008 à 9:09:25

    Salut à tous;

    J'ai une class Window qui contient seulement ma fenêtre de type Sf::RenderWindow : m_win. Cette classe s'occupe de tout ce qu'il y'a en rapport avec la fenêtre.

    Mais j'ai plusieurs autres class; et j'ai besoin de ma variable de la fenêtre contenue dans la class Window. (pour afficher des images etc...)
    Quelle est la meilleure façon pour accèder à m_win ?

    J'ai pensé à l'héritage, mais faire hériter la class Window 4 ou 5 fois c'est "propre" ? En plus ceci va créer 4-5 fois un objet de type Window (et donc 4-5 fenêtres ?!?).
    Ou alors je singletonne ma classe Window, et dans mes classes où j'ai besoin de m_win, je récupère la fenêtre en passant par un getInstance de Window ?
    Ou une autre solution ?

    Quelle est la méthode la plus propre ?

    Merci
    • Partager sur Facebook
    • Partager sur Twitter
      13 février 2008 à 9:21:43

      Je pense que le plus propre est que celui qui demande aux objets de se dessiner leur passe la fenêtre à ce moment. Typiquement, c'est la class Application (ou peu importe son nom -- la grosse classe quoi) qui va gérer à la fois la fenêtre et la liste des objets affichables, donc cela ne pose pas de problème.
      • Partager sur Facebook
      • Partager sur Twitter
        13 février 2008 à 13:15:02

        Hum je ne vois pas trop comment procéder. Imaginons ceci: J'ai une class Menu. Dans cette class j'ai une fonction membre run() qui gére le menu principal. Le code s'organise ainsi : J'ai une boucle qui se termine quand j'ai fait une certain action (Jouer ou Quitter), et dans cette boucle je m'occupe des évènements et de l'affiche des boutons (une simple image .bmp); j'ai donc besoin de la fenêtre unique Sf::RenderWindow.

        Seulement, comment je peux accèder à la fenêtre, c'est à dire à sf::RenderWindow m_win dans ma méthode run() ? Héritage ? Et ceci pour plusieurs class.

        En fait Laurent, je ne comprends pas trop ta solution, puisque tu dis qu'il faut avoir une class Application (ou autre), mais en fait c'est MA class MyWindow non ? Donc ça revient au même, j'aurais toujours besoin de l'attribut (Sf::RenderWindow) de Application dans plusieurs autres class.

        Moi sinon j'ai pensé à faire un truc du genre avec une class Window Singletonnée:

        1. class MyWindow
        2. {
        3.     private:
        4.         static MyWindow *m_window;
        5.         sf::RenderWindow m_win;
        6.     public:
        7.         MyWindow(void)
        8.         {
        9.             m_win.Create(...);
        10.             m_win.SetBackgroundColor(...);
        11.             // ...
        12.         };
        13.         MyWindow* MyWindow::getInstance(void)
        14.         {
        15.             if (m_window == 0)
        16.                 m_window = new MyWindow;
        17.             return m_window;
        18.         };
        19.         sf::RenderWindow* MyWindow::getWindow(void)
        20.         {
        21.             return &m_win;
        22.         };    
        23.     // ...
        24. };
        25. // ...
        26. class Menu
        27. {
        28.     private:
        29.         sf::RenderWindow *m_win;
        30.     public:
        31.         Menu(void)
        32.         {  
        33.             m_win = MyWindow::getInstance()->getWindow();
        34.             // ...
        35.         };
        36.         // ...
        37. };


        Et on fait comme dans Menu pour toutes les classes qui ont besoin de la fenêtre. Ainsi j'ai en attribut ma fenêtre dans Menu, et je peux gérer event, images et autres dans ma fonction Menu::run()

        Mauvaise méthode ?
        • Partager sur Facebook
        • Partager sur Twitter
          13 février 2008 à 14:04:39

          Pourquoi ne pas utiliser un simple pointeur?
          • Partager sur Facebook
          • Partager sur Twitter
            13 février 2008 à 14:21:42

            moi aussi j'ai à peu prés le même problème !!!
            j'ai ma fonction principale main , où il y a la création de la fenêtre : sf::RenderWindow App(blabla ...);
            et je fais appel à des fonctions pour faire des calculs , genre collisions , et je voudrais que c'est fonction modifies donc l'affichage mais à chaque fois que je compile çà me donne une erreur dans le fichier de ma fonction :
            error: 'App' undeclared (first use this function)
            error: (Each undeclared identifier is reported only once for each function it appears in.)

            comment faire pour faire passer à la fonction en paramètre la fenêtre ; pour qu'elle puisse être utiliser ????
            merci beaucoup
            • Partager sur Facebook
            • Partager sur Twitter
              13 février 2008 à 16:17:31

              Je pense que vous ne voyez pas assez grand. Ce genre de problème c'est la base de l'application, énormément de choses seront basées dessus. C'est pour cela qu'il faut prévoir un fonctionnement robuste et efficace dès le départ, et pas seulement se demander "comment passer mon instance de fenêtre au menu ?". Bon ok, c'est pas facile pour les débutants ;)

              Donc, plutôt que de se demander comment passer la fenêtre à telle ou telle classe, partez plutôt sur un design plus générique, un genre de framework de base qui marchera pour n'importe quelle application de ce genre, et qui posera une excellente base pour la suite.

              Par exemple, moi je fais systématiquement une classe Application qui initialise / met à jour / dessine / clôt les objets de l'application. Cette classe application gère d'un côté la fenêtre, et de l'autre tous les objets qui ont besoin d'être mis à jour et dessinés (et éventuellement, comme c'est le cas ici, de gérer les évènements).

              Plutôt qu'un long discours, un peu de code pour illustrer (ne pas le prendre au pied de la lettre, c'est juste pour donner l'idée) :

              1. class Object
              2. {
              3. public :
              4.     virtual void OnEvent(const sf::Event& Event);
              5.     virtual void Update(float ElapsedTime);
              6.     virtual void Draw(sf::RenderWindow& Window) const;
              7. };
              8. class Application
              9. {
              10. public :
              11.     void Run()
              12.     {
              13.         Window.Create(...);
              14.         Running = true;
              15.         while (Running)
              16.         {
              17.             // --- Gestion des évènements ---
              18.             sf::Event Event;
              19.             while (Window.GetEvent(Event))
              20.             {
              21.                 if (Event.Type == sf::Event::Closed)
              22.                 {
              23.                     Running = false;
              24.                 }
              25.                 else
              26.                 {
              27.                     for (int i = 0; i < Objects.size(); ++i)
              28.                         Objects[i].OnEvent(Event);
              29.                 }
              30.             }
              31.             // --- Mise à jour des objets ---
              32.             for (int i = 0; i < Objects.size(); ++i)
              33.                 Objects[i].Update(Window.GetFrameTime());
              34.             // --- Dessins des objets ---
              35.             for (int i = 0; i < Objects.size(); ++i)
              36.                 Objects[i].Draw(Window);
              37.         }
              38.     }
              39. private :
              40.     sf::RenderWindow&    Window;
              41.     std::vector<Object*> Objects;
              42.     bool                 Running;
              43. };
              44. int main()
              45. {
              46.     Application App;
              47.     App.Run();
              48.     return 0;
              49. }

              Ici la classe Application est le squelette de l'appli, c'est elle qui gère les objets et ordonne tout comme il faut. Après toi tu n'as plus qu'à créer des Object particuliers, ils auront quoiqu'il arrive toujours des notifs d'évènements, une mise à jour avec le temps écoulé, et la fenêtre pour se dessiner. Ceci quelque soit la manière dont la fenêtre est gérée en amont.

              Bon, j'espère que j'ai pas été trop confus :D
              • Partager sur Facebook
              • Partager sur Twitter
                14 février 2008 à 11:52:42

                Ah en fait je crois avoir compris le truc : Je suis parti "à l'envers" oui. Le truc c'est qu'il faut, comme tu dis, poser la base, le squelette.

                Je vais essayer de voir si j'arrive à intégrer ce concept dans mon programme. En tout cas c'est plus clair, je ne m'y suis pas pris comme il le fallait. Encore faut-il que j'arrive à intégrer ceci dans mon programme ^^

                Merci Laurent.

                Je reposte si j'ai des soucis pour arriver à mon but :p
                • Partager sur Facebook
                • Partager sur Twitter
                  14 février 2008 à 14:10:46

                  je vais paraître super lourd !!!
                  ce serait possible de mettre un code que l'on puisse compiler ???
                  parce que là je n'arrive pas à comprendre le truc !!!
                  désolé , pourtant j'en ai tellement besoin !!!
                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 février 2008 à 15:22:37

                    Je ne pense pas que compléter le code afin qu'il compile t'apportera grand chose, si tu ne saisis pas le principe. Ici le but n'est pas de donner un bout de code, mais d'expliquer une façon de faire et d'écrire un squelette d'application 2D.

                    Mais bon ce n'est pas facile à appréhender pour un débutant, il te faut juste plus de pratique ;)
                    Moi j'ai mis plusieurs années avant d'arriver à ce genre de conception...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 février 2008 à 16:15:25

                      ok merci quand même !!!
                      je vais réessayer demain après une nuit de sommeil peut être que çà ira mieux ^^
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Besoin de la fenêtre d'une class dans plusieurs autres class (SFML)

                      × 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