Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Architecture d'un projet SFML  (Lu 6528 fois)

0 Membres et 2 Invités sur ce sujet

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Architecture d'un projet SFML
« le: Octobre 13, 2012, 07:53:13 pm »
Bonjour,

Je me pause quelques questions quand à l'architecture à adopter pour un projet SFML.

Je pensais faire une architecture telle que chacune de mes classes ayant un quelconque comportement implemente une methode Update() et Draw() et la boucle principale du jeu appellerait ces methode en cascade.

La methode Update prendrait en paramètre un entier qui serait le gameTime (en ms).
Or chacune de ces classes aurait besoin de faire des appels à l'objet sf::Window de mon programme.
J'aimerais éviter de "cascader" cet objet dans mes methode Update et Draw de mon jeu.

Quelle serait la meilleur marche à suivre dans mon cas ?


J’espère avoir été suffisamment clair, n'hésitez pas à me demander d'éventuels éclaircissements.

Merci à vous :)

minirop

  • Sr. Member
  • ****
  • Messages: 254
    • Voir le profil
    • http://dev.peyj.com
Re : Architecture d'un projet SFML
« Réponse #1 le: Octobre 13, 2012, 09:51:52 pm »
J'utilise ce système pour mon projet, et la fonction "draw" de mes "écrans" prend un sf::RenderTarget & target en paramètre. et donc tu lui passes ta RenderWindow (je vois pas comment faire autrement¹ et "proprement").
j'ai mis RenderTarget comme ça je peux également utiliser un RenderTexture si j'ai envie.

¹: parce qu'un objet global ou alors passer ta fenêtre dans le constructeur de façon à ce qu'il en garde un pointeur c'est pas spécialement plus "propre". Même si tu peux utiliser la deuxième façon si tu as besoin d'accéder à la fenêtre également dans "update".
« Modifié: Octobre 13, 2012, 09:55:13 pm par minirop »

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Architecture d'un projet SFML
« Réponse #2 le: Octobre 13, 2012, 10:25:24 pm »
J'ai effectivement besoin d'acceder à la fenetre dans ma methode Update aussi.
Pour l'instant j'ai donc défini un objet global. Je suis conscient que ce n'est pas "propre" mais je trouve vraiment lourd le fait de devoir passer en cascade la fenetre dans toutes les méthodes de mes classes. Idem pour le pointeur dans les constructeurs...

Bon he bien si il n'existe pas d'autre manière de faire, tampi ^^

Merci en tout cas.
Je continuerai à suivre la discussion au cas où quelqu'un poste quelque chose de nouveau.

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Architecture d'un projet SFML
« Réponse #3 le: Octobre 18, 2012, 09:37:46 am »
Bonjour,

Je me pause quelques questions quand à l'architecture à adopter pour un projet SFML.

Je pensais faire une architecture telle que chacune de mes classes ayant un quelconque comportement implemente une methode Update() et Draw() et la boucle principale du jeu appellerait ces methode en cascade.

La methode Update prendrait en paramètre un entier qui serait le gameTime (en ms).
Or chacune de ces classes aurait besoin de faire des appels à l'objet sf::Window de mon programme.
J'aimerais éviter de "cascader" cet objet dans mes methode Update et Draw de mon jeu.

Quelle serait la meilleur marche à suivre dans mon cas ?


J’espère avoir été suffisamment clair, n'hésitez pas à me demander d'éventuels éclaircissements.

Merci à vous :)

C'est quelque chose que je ne fais (presque, ça m'est arrivé une fois) jamais pour ma part. Je ne vois pas en quoi tes méthodes draw et surtout update auraient besoin de connaitre ta Window, car pour moi ta méthode draw ne devrait être qu'un getter sur le sprite de ton objet, et ton update ne s'occuper que de la partie "sémantique" de ton objet (i-e les données internes, qu'on affiche pas, genre les coordonnées, l'etat, etc) . Ton problème de conception se situe peut-être là. Tu devrais nous en dire plus sur ton architecture, mais pour ce qui est de "draw" tes objets, je verrai personnellement plus la méthode draw de ta Window être appelée pour tous les objets ayant un comportement quelconque dessinables, et ceci dans ta game loop.

Je penses que SFML a été conçue pour être utilisée dans ce sens, il n'y a qu'à voir la doc et ses nombreux exemples d'utilisation faits par Laurent (et pis même sans voir ce que fait Laurent, en regardant comment est faite SFML). Tout ce qui est "drawable" peut-être affiché par la méthode draw de la fenetre, pourquoi refaire un draw ailleurs ?

« Modifié: Octobre 18, 2012, 09:49:46 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Architecture d'un projet SFML
« Réponse #4 le: Octobre 18, 2012, 09:55:49 am »
Citer
Tout ce qui est "drawable" peut-être affiché par la méthode draw de la fenetre, pourquoi refaire un draw ailleurs ?
Si tu dérives de sf::Drawable tu peux faire un window.draw(mon_truc), mais au final tu retombes quand même dans un MonTruc::draw(sf::RenderTarget&, ...), ce n'est qu'une façade syntaxique. Fondamentalement, ça ne change rien au fait que pour dessiner un objet il faut d'une manière ou d'une autre une fonction de ce genre (qui connaisse la render-target) dans tes classes dessinables.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : Architecture d'un projet SFML
« Réponse #5 le: Octobre 18, 2012, 02:11:21 pm »
Citer
Tout ce qui est "drawable" peut-être affiché par la méthode draw de la fenetre, pourquoi refaire un draw ailleurs ?
Si tu dérives de sf::Drawable tu peux faire un window.draw(mon_truc), mais au final tu retombes quand même dans un MonTruc::draw(sf::RenderTarget&, ...), ce n'est qu'une façade syntaxique. Fondamentalement, ça ne change rien au fait que pour dessiner un objet il faut d'une manière ou d'une autre une fonction de ce genre (qui connaisse la render-target) dans tes classes dessinables.

ok, mais justement, il veut implémenter une méthode draw dans toutes ses classes dessinables. On ne peut rien au fait que les fenetre SFML ne peuvent dessiner que des objets de type  sf::drawable, donc soit il fait hériter ses classes de sf::drawable, soit ses classes (dessinables) ont au moins un attribut de ce même type. Dans tous les cas, un simple getter ou un appel direc permet l'appel à ta façade syntaxique window.draw(mon_truc /*ou monTruc.getDrawable*/). Donc pourquoi aurait-il besoin de se trimbaler partout la window ?

C'est comme si je décidais d'utiliser l'API Titanium (pour faire des appli cross-platformes_mobiles avec du JS (horrible)) dans mon code, mais je me retape moi-même tout la couche qui permet d'identifier sur quel OS je suis, alors que j'ai déjà une méthode d'un module qui me permet de le vérifier quand c'est nécessaire de façon beaucoup plus simple ...

Edit : ce que je vais dire peut paraître grossier, mais fondamentalement,  SFML est une grosse façade syntaxique à OpenGL et deux ou trois autres API plus bas niveau. Autant l'utiliser le plus simplement possible, car c'est ça l'objectif au final d'une conception : faire simple. Et je penses que l'OP ou minirop se compliquent la tâche.
« Modifié: Octobre 18, 2012, 02:27:14 pm par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Architecture d'un projet SFML
« Réponse #6 le: Octobre 18, 2012, 03:03:39 pm »
Citer
monTruc.getDrawable
Ca c'est typique d'une mauvaise conception (désolé ;)).

Une classe doit être pensée en terme de services ("dessine toi") plutôt que de données ("donne moi un truc à dessiner"). C'est beaucoup plus flexible, encapsulé et donc maintenable. L'utilisateur de la classe n'a en effet pas à savoir quel genre de drawable utilise la classe pour réaliser son dessin ; d'ailleurs tu fais comment pour les entités qui ont besoin de dessiner plusieurs drawables d'un coup ?

Du coup, comme je le disais, une classe dessinable bien conçue aura une fonction draw (que ce soit via sf::Drawable ou à sa propre sauce), et celle-ci doit forcément prendre en paramètre le truc dans lequel elle doit dessiner. Pour moi il n'y a pas vraiment d'autre design qui soit valable, pour cette problématique en particulier.

D'ailleurs pour en revenir à l'OP, ça me paraît bien (mais bon ça ne va pas très loin dans le détail ;)), à part peut-être la nécessité d'avoir la fenêtre dans les fonctions update.
« Modifié: Octobre 18, 2012, 03:07:02 pm par Laurent »
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : Architecture d'un projet SFML
« Réponse #7 le: Octobre 18, 2012, 03:57:34 pm »
Citer
monTruc.getDrawable
Ca c'est typique d'une mauvaise conception (désolé ;)).

Une classe doit être pensée en terme de services ("dessine toi") plutôt que de données ("donne moi un truc à dessiner"). C'est beaucoup plus flexible, encapsulé et donc maintenable.
Ce n'est pas que je penses en terme de données, mais je n'aime pas faire hériter mes classes de la SFML, honnêtement je ne le fais jamais car pour moi cela n'a pas de sens. Pour moi un personnage (par exemple) n'EST PAS UN drawable, mais A UNE image que je dois dessiner, etc...

Citer
L'utilisateur de la classe n'a en effet pas à savoir quel genre de drawable utilise la classe pour réaliser son dessin ;
je ne comprends pas ce que tu essaies de dire, tu peux développer ?

Citer
d'ailleurs tu fais comment pour les entités qui ont besoin de dessiner plusieurs drawables d'un coup ?
Au lieu d'encapsuler dans une seule méthode tous mes appels à draw, j'aurais une méthode pour encapsuler tous mes appels aux getters (d'ailleurs assez particulier une classe à sémantique d'entité (si tu l'as employé dans ce sens) qui posséderait plusieurs drawables, mais ça reste largement imaginable), ce qui revient au même (à part que, si j'ai bien compris, avoir des getters sur ses drawables pour les appeler dans la gameloop, c'est maaal).  Non pour être honnête, surement que dans ce cas là j'aurais écris une méthode draw, mais c'était juste pour dire que dans l'autre sens c'est pas aussi gênant que tu le dis. je redéfinierai draw dans les cas où la phase de conception m'y a conduit inévitablement

Citer
Du coup, comme je le disais, une classe dessinable bien conçue aura une fonction draw (que ce soit via sf::Drawable ou à sa propre sauce), et celle-ci doit forcément prendre en paramètre le truc dans lequel elle doit dessiner. Pour moi il n'y a pas vraiment d'autre design qui soit valable, pour cette problématique en particulier.
Donc soit on hérite des drawables (soit à sa sauce, ok), soit notre classe est mal conçue pour cette problématique en particulier (tu veux dire un programme avec plein d'objets à dessiner ?) ? Désolé je fais pas exprès de mal comprendre, mais voilà ce que je comprends.

Parce que si on a un (ou deux) sprite dans notre classe, au lieu d'hériter de drawable,  dans la gameloop on aura sprite.draw(App) au lieu de App.draw(sprite), je trouve pas ça hyper gênant, même pour la maintenabilité..
« Modifié: Octobre 18, 2012, 04:57:19 pm par kamui »

kimci86

  • Full Member
  • ***
  • Messages: 128
    • Voir le profil
Re : Architecture d'un projet SFML
« Réponse #8 le: Octobre 18, 2012, 07:21:58 pm »
D'ailleurs pour en revenir à l'OP, ça me paraît bien (mais bon ça ne va pas très loin dans le détail ;)), à part peut-être la nécessité d'avoir la fenêtre dans les fonctions update.

D'après mes expériences concernant le programmation de widgets, la fenêtre est utile dans les fonctions update tout particulièrement pour convertCoords.
Un exemple simple : imaginez qu'un objet ait besoin de savoir s'il est survolé par la souris. Pour avoir le bon résultat avec une View appliquée à la fenêtre, on a besoin de convertCoords.
« Modifié: Octobre 18, 2012, 09:17:30 pm par kimci86 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Architecture d'un projet SFML
« Réponse #9 le: Octobre 18, 2012, 07:32:14 pm »
Citer
Ce n'est pas que je penses en terme de données, mais je n'aime pas faire hériter mes classes de la SFML
Ca n'a rien à voir avec SFML, tu peux très bien garder la même conception avec tes propres classes de base. Décider d'utiliser getDrawable() ou draw() est un choix conceptuel très important, à savoir utiliser ta classe comme une source de données ou bien de services. Les détails techniques (quelle classe de base, ...) viennent après.

Citer
je ne comprends pas ce que tu essaies de dire, tu peux développer ?
Si tu fais une fonction getDrawable(), il faut que tu détermines un type de retour. Là tu as de la chance car SFML a une classe de base commune à toutes ses classes dessinables, mais ça pourrait très bien ne pas être le cas (ça disparaîtra peut-être un jour). Et même avec ça, tu es obligé de renvoyer un pointeur ou une référence ; que se passe-t-il si la classe veut renvoyer un objet temporaire, qu'elle ne stocke pas ?
Bref, c'est beaucoup moins flexible. Si tu dis à la classe "dessine-toi", au moins elle fait ce qu'elle veut, et sans avoir à dévoiler de détail de son implémentation à l'appelant. C'est ça qu'on appelle l'encapsulation ;)

Citer
Donc soit on hérite des drawables (soit à sa sauce, ok), soit notre classe est mal conçue pour cette problématique en particulier (tu veux dire un programme avec plein d'objets à dessiner ?) ?
Oui -- enfin en prenant pas mal de raccourcis. Il y a sans doute des situations pour lesquelles il faudrait nuancer un peu la solution :)

Citer
Parce que si on a un (ou deux) sprite dans notre classe, au lieu d'hériter de drawable,  dans la gameloop on aura sprite.draw(App) au lieu de App.draw(sprite), je trouve pas ça hyper gênant, même pour la maintenabilité..
Là j'ai pas compris ce que tu voulais dire.

Citer
Un exemple simple : imaginez qu'un objet ai besoin de savoir s'il est survolé par la souris. Pour avoir le bon résultat avec une View appliquée à la fenêtre, on a besoin de convertCoords.
Ok, ça me va comme exemple :P
Laurent Gomila - SFML developer

flow10000

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
    • Project Abyss
Re : Architecture d'un projet SFML
« Réponse #10 le: Octobre 22, 2012, 06:58:46 pm »
Oulà je n'avais pas vu que le topic avait évolué à ce point.

Pour résumer, il semble que l'architecture que j'utilise est bonne.
Et j'ai besoin en effet de la RenderWindow dans mes fonctions Update() pour tout ce qui est gestion de la souris.

Merci à vous tous.