Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - L01man

Pages: [1] 2 3 4 Suivante »
1
C'est super, ça. D'OpenVG je suis tombé sur cairo dont j'avais déjà entendu parlé, et je suis arrivé sur Papyrus, son port C++. Il y a quelques points communs avec la SFML !

2
Oui, pas maintenant.
Mais je ne pense pas que tous viennent partager leurs problèmes : je ne l'ai jamais fait, par exemple, mais ces sujets m'ont au passage fait avancé.
Le sondage n'est pas du type "avez-vous un problème ?", mais plutôt "Quelle structure utilisez-vous en ce moment ?". La pire des structures proposées peut fonctionner à un certain niveau et l'utilisateur en question peut ne pas la changer et ne pas demander de l'aide ici.
Les sondages sont simples à mettre en place et ont beaucoup plus de participation qu'un forum. Ils vont très bien de paire avec les forums.

3
D'ailleurs, me revoilà.
Je viens juste partager une réflexion qui ne concerne en aucun cas une proposition pour la SFML ::). Une classe ressemblant à, tiens, Transformable, représentant quelque-chose de géométrique, devrait avoir en premier lieu un tableau de points, de sommets, ainsi qu'une relation qui relie les points entre eux, des courbes. En fait, la librairie parfaite implémente du dessin vectoriel au sommet. Quand aux textures, elles sont soit elles-mêmes en vectoriel, soit des images qui s'affichent dans un polygone vectoriel. Les calculs de collision sont applicables pour tout, avec une extrême puissance ; les classes comme Shape n'ont plus de raison d'être car elles se retrouvent dans Transformable ; tout peut posséder une texture, une couleur, etc. Quant à Text, c'est soit un groupe de polygones vectoriels, chacun formant une lettre, soit un rectangle sans fond et au bord transparent dans lequel est dessiné le texte avec la fonte donnée. Ça peut marcher : ça s'imagine très bien et ça existe déjà. Je suis par contre effrayé des performances au sein d'un jeu, peut-être à tord.

4
D'accord. Que penses-tu de faire un sondage demandant : votre code ressemble-t-il plus à ça : class Player/Tile/Missile : sf::Sprite { ... };, à ça : class Player/Tile/Missile {
  public:
    int x, y;

    void update() {
      Graphics.SetPosition(x, y);
    }

   private:
     sf::Sprite Graphics;
};
ou à ça : class Player/Tile/Missile : sf::Transformable {
  private:
    sf::Sprite Graphics;
};
? Tu appelles ça "Sondage anonyme pour l'amélioration de la SFML" et tu obtiens n * 1000000 de votes, où n est le nombre de jours depuis la publication du sondage. La fonction est simple ;).
D'ailleurs,  comment t'y prends-tu actuellement pour voir la façon dont les gens se débrouillent ? Tu le fais à partir des demandes d'aides ?

5
Oui, quand les allocations dynamiques pointent leur nez, c'est pas génial.
Citer
de bons tutoriels
Pourrait-on mettre l'accent sur le piège qu'on veut éviter de façon à ce que l'utilisateur ne tombe pas dedans dans les tutoriels sur les graphismes ?
Citer
Gérer une bibliothèque avec beaucoup d'utilisateurs, c'est aussi savoir faire des compromis
En voilà un (pour SFML3) : on sépare effectivement Sprite et ses sœurs de sf::Transformable, mais on crée une troisième hiérarchie de classes qui héritent Sprite et Transformable, etc. pour qu'on puisse parvenir à un bon design sans "mauvaises manipulations" et que la simplicité soit toujours au rendez-vous ? Quand aux nouveaux noms, pour les classes qui héritent Sprite et les autres avec Transformable, je propose : FullSprite, StandaloneSprite ou quelque-chose d'autre dans le genre. A moins qu'on ne fasse l'inverse et que les Sprite qui ne viennent que de Drawable soient nommés SimpleSprite, BaseSprite, HalfSprite, ou autre afin que les codes de SFML2 fonctionnent toujours.

Quant à l'utilisation de SFML2, je ne suis pas sûr que les utilisateurs remarquent la nouvelle Transformable et qu'en plus ils aient l'idée de bousculer leur design actuel pour l'hériter, en sachant que Sprite et les autres le font déjà. Si tu veux, on peut arrêter d'en parler temporairement ^^.

6
Pas de factorisation, même en C++ ? Alors ça n'emmène effectivement à rien.
(Mais je reviendrai.)

7
Ca ne te gène plus que la plupart (sûrement) des utilisateurs débutants tombent dans des pièges de structure qui, en plus, finissent par les bloquer ? Avant, tu tenais absolument à soutenir le contraire, il me semble.
Citation de: Laurent
Maintenant avec SFML 2 on peut faire simple ou bien carré, les gens n'ont qu'à choisir ce qu'ils veulent, moi ça me va.
Mais les gens ne choisissent pas vraiment, ils sont "naturellement" attirés vers le mauvais choix à cause de cet héritage multiple ! Le casser permettrait toujours de recréer le vice avec une classe héritant de sf::Sprite et sf::Transformable, par exemple, mais on serait plus conscient que c'est un mauvais choix et le choix naturel serait le bon. La SFML est très souvent utilisée comme base pour un design, alors il faut enlever les erreurs de ce genre quand elles sont détectées. On ne peut pas laisser un utilisateur construire une structure qui tombera inexorablement, c'est trop bête et trop frustrant !
Citation de: Laurent
Je suis d'accord mais malheureusement on ne vit pas dans ce monde où tout est carré et bien séparé
En programmation, c'est possible. En tout cas, il y a peut-être une limite mais on ne l'atteint pas en séparant le visuel de la logique, qui est un principe fondamental.
Citer
et qui veulent garder le niveau de simplicité initial
Justement, ça devient de plus en plus compliqué parce-qu'on a voulu trop réunir au départ ! C'est aller à l'encontre des classes.

Regardons ce que ça change concrètement.
sf::Texture Tex("machin.png");
sf::Sprite Spr(Tex);

Spr.SetPosition(50, 50);
Spr.Rotate(45);

sf::RenderWindow Win(...);
Win.Draw(Spr);
il suffira d'ajouter deux lignes de code, juste après la déclaration du sprite :
sf::Transformable Transf;
Spr.attachTo(Transf);
et de remplacer les "Spr.machin" par des "Transf.machin".

Et on se débarrassera surtout de l'abominable :
class Player : public sf::Sprite {
  public:
    Player() {
    }
     void update() {
       SetPosition(50, 50);
       SetRotation(45);
     }
}
ou d'un
//meilleur design mais lourd à mettre en place donc peu utilisé. Comme il a l'air mal formé, l'utilisateur va penser qu'il se trompe et va choisir la pire solution possible alors qu'il avait raison, mais la SFML l'a induit en erreur !!
class Player : public sf::Transformable {
  public:
    Player() :
      Graphics(new sf::Sprite()) {
    }
    ~Player() {
      delete Graphics;
    }
     void update() {
       SetPosition(50, 50);
       SetRotation(45);

       //et c'est parti mesdames et messieurs
       Graphics->SetPosition(GetPosition());
       Graphics->SetRotation(45);
     }

  private:
    sf::Drawable* Graphics;
}
au profit de
//on est plus tenté d'hériter Sprite grâce à sa séparation de Transformable et à sa fonction attachTo qui indique qu'il serait bizarre de faire "attachTo(*this);" et on est orienté vers le deuxième design mais de façon moins lourde en lignes de code et en mémoire consommée inutilement.
class Player : public sf::Transformable {
  public:
    Player() :
      Graphics(new sf::Sprite()) {
      Graphics->attachTo(*this);
    }
    ~Player() {
      delete Graphics;
    }
     void update() {
       SetPosition(50, 50);
       SetRotation(45);
       /*on peut même à tout moment changer de Graphics:
         delete Graphics;
         Graphics = new sf::RectangleShape(10, 10); */
     }

  private:
    sf::Drawable* Graphics;
}

8
J'ai trouvé l'usage géométriquement pur qu'on peut faire d'un getRect : l'inscription. En fait, un setRect n'a pas de sens, de même qu'un attribut Rect donné à tous les Transformable, tu as raison.
Mais par contre, savoir si un Transformable est inscrit dans un rectangle, dans un cercle, etc., me paraît plutôt géométrique.
Pour éviter de créer une fonction virtuelle pure qui empêcherait une instanciation d'un sf::Transformable, on peut créer une méthode statique surchargée dans sf::Transformable ou sf::Transform, qui donnerait la figure géométrique dans lequel un Transformable est inscrit.
Un pseudo-code illustrant le tout :
sf.Transform.getRectInscription drawable = case type drawable
    sf.Sprite -> Rect(drawable.getPosition(), drawable.getSize())
    sf.CircleShape -> Rect(drawable.radius * 2, drawable.radius * 2)
    sf.Shape -> #un calcul plus compliqué
    #etc.

9
Oui, mais même si ces changements sont effectués dans  ans ils pourraient ne nécessiter que 5 minutes de code.
Citation de: Laurent
On peut déjà séparer sans problème avec l'API actuelle (tu peux ignorer la transformation du sprite et lui en passer une perso lors du draw)
: j'ai répondu en quoi c'était dangereux et ça favorisait ce que tu cherches à absolument éviter dans la première partie de mon avant-dernier message.
Citer
mais j'ai quand même voulu garder la simplicité des classes actuelles (reprises de 1.6)
Dans un vrai projet, un bon design, séparant Transformable et Drawable, simplifiera plus le code qu'un design où ce n'est pas le cas car on évite les opérations inutiles comme "tu peux ignorer la transformation du sprite et lui en passer une perso lors du draw".
Citation de: Laurent
car la plupart des gens les utilisent comme ça.
Citation de: Laurent
C'est une mauvaise chose car ça oriente très fortement les gens vers une direction qui n'est pas forcément la bonne. En mettant des classes très haut-niveau, "finales", dans SFML, j'incite les gens à faire pareil pour leurs propres classes, et donc utiliser les mêmes classes de base. Mais les classes des gens ne sont pas celles de SFML, et on voit très vite arriver plein de gens sur le forum qui se plaignent de limitations ou autres.
Citer
Et je ne veux pas que les gens utilisent des collections hétérogènes de Drawable. Je veux qu'ils utilisent des collections hétérogènes de leurs propres classes, avec des sprites, textes, etc. comme attributs de certaines.
N'est-ce pas la solution ultime qui n'apporte que du plus ?
Citation de: Laurent
toi tu voudrais du minimalisme (pourquoi faire ?) [...]
La "simplicité" n'est qu'illusoire et n'est qu'un chemin vers le côté obscur qui attend tous les débutants à bras ouverts.
Mettre sf::Transformable et sf::Drawable dans sf::Sprite et les autres, c'est comme mettre sf::Texture directement dans sf::Sprite.

10
Orwel, Germino, vous avez eu les mêmes suggestions qui ont été faites dans ce sujet.

11
Laurent pointe le bout de son nez ! Vite, entraînons-le dans une discussion de laquelle il ne pourra plus sortir et sera donc contraint d'accepter le changement.

En pratique le changement est assez simple et ne s'appuie sur aucune de mes autres idées. Il est principalement exprimé dans le premier post et consiste en ce qui suit :
  • Enlever l'héritage de sf::Transformable dans toutes les filles de Drawable qui en héritent, comme Sprite, Shape et Text, mais pas VertexArray
  • A la place, créer une méthode attachToTransformable(sf::Transformable&) afin que les attributs de ce sf::Transformable soient appelés dans le Draw()
Je pense que c'est tout. Après, tu auras sûrement d'autres idées plus astucieuses quant à l'interaction entre le Drawable et le Transformable mais ça devrait ressembler à ça.
Ce qui fait couler le plus d'encre, en revanche, c'est le débat sur l'application de ce changement :P. Je pense avoir le mieux répondu dans mon message précédent, et j'attends avec impatience de nouveaux arguments !

12
Je vais préciser le :
Citer
En premier, une consommation mémoire inutile (c'est bête en C++), et une mauvaise conscience .
Commençons par la "mauvaise conscience". Peut-être le codeur va commencer par créer un attribut Sprite à son propre objet, mais il se rendra compte qu'il doit dupliquer les attributs de coordonnées, de rotation, etc. puis les passer à son attribut Sprite à chaque fois. Il va se lasser de la recopie, ne pas apprécier qu'on puisse accéder à ces attributs autrement que par Sprite.get/setAttribut, va aussi penser à l'aspect "consommation inutile", et va finalement commettre une grosse erreur (c'est exactement mon parcours que je vous donne) : il va faire hériter sa classe Player de Sprite, et va ensuite continuer dans cette lancée en créant des listes hétérogènes de Drawable* (malheur !).
Ensuite, une consommation mémoire inutile, qui doit être faite pour éviter un mauvais design, est tout simplement, comme le nom l'indique, inutile. Elle n'a pas lieu d'être. Elle est facilement contournable. Mieux encore, elle force à choisir le bon design, à faire ce que toi et Laurent pensez !
Je me souviens d'une version plutôt récente d'OpenGL qui "cassait" aussi ses fonctions et nous laissait ainsi plus de libertés, d'augmentations de performances, etc., car ces fonctions réunissaient sûrement plusieurs opérations ensemble alors que certaines n'étaient utiles que dans certains cas.
Sur ce coup, je suis sûr d'avoir raison. A la limite, au diable mes qui consistent à "remonter" des méthodes, si c'est pour considérer celle-ci. D'un point vu théorique reconnu par tous et au niveau de mon expérience personnelle, qui selon Laurent est plutôt répandue chez les débutants puisqu'il veut absolument éviter les comportements qu'induisent la réunion des attributs de Transformable et de Drawable dans Sprite, etc., j'en suis convaincu.
Certes, pour faire un "Hello World" + Sprite, il faudra créer un objet supplémentaire et appeler une fonction en plus. Mais sur tous les autres projets, utilisant des classes Player, etc. contenant un attribut Drawable permettant de la flexibilité, évitant de transmettre tous les attributs à son Drawable puisqu'il utilisera directement celles de la classe le contenant, etc., des lignes de codes seront même gagnées.

En tout cas, merci, Orwel (Georges ?), de faire vivre le sujet :).

13
Citer
Pourquoi le fait d'avoir plus d'attribut que nécessaire te rebut???
En premier, une consommation mémoire inutile (c'est bête en C++), et une mauvaise conscience :P.
Citer
Qui peut le plus, peut le moins
Mais si on peut facilement faire mieux (moins)... Pourquoi faire moins bien (plus et pas de séparation alors qu'un bon design l'impose). Je ne sais pas comment ça marche chez vous, mais chez moi, je ne fais en fait pas "le plus" : j'ai ma propre classe Shape et mes propres Rectangle, Circle, etc., ce qui me fait mal au coeur à chaque fois que j'y pense. J'évite ainsi du "plus" (attributs Drawable là ou j'en voudrais pas : bounding boxes) mais c'est au prix de "hacks" du design.

Citer
Puis si on fait ce que tu demande, mon système d'affichage de bounding boxes de Box2D s'appuyant sur DebugDraw ne fonctionne plus. Et là je vais devoir bricoler(rien de méchant, mais évitable).
Ma fois, je ne saurais te répondre ici, ne connaissant que Box2D de nom et pas DebugDraw. Peux-tu préciser vite-fait ?
Citer
Le malheur des uns, fait le bonheur des autres
Et au final, le bonheur de tout le monde. Le conservatisme est un frein à l'évolution. Le mieux aurait été de séparer dès le départ, pour éviter aux utilisateurs d'avoir à adapter leurs codes, car ils auraient bien démarré dès le début. Mais
Citer
Mieux vaut tard que jamais
.

Je suis sûr que ça éviterait à 99% le comportement que Laurent abhorre : la création d'un design basé sur les Sprite, les Shape, etc. puisque ce serait impossible >:(. A la place, on dériverait Transformable, et on traiterait la partie graphique naturellement à part.

class Player : sf::Transformable {
  public:
    Player() {
        attachTo(new sf::Sprite(textureMachin));
    }
};
Drawable.Draw() utilise les attributs du Transformable associé avec attachTo().
Personne ne sera tenté de faire :
class Player : sf::Sprite {
};
mis dans une collection hétérogène de sf::Drawable.
Et un jour, quand on veut que le joueur soit fait avec plusieurs sprites
class Player : std::vector<sf::Sprite*> {
};
Et si chaque classe est différente : l'une est sf::Sprite, l'autre est std::vector<sf::Sprite*>, l'autre est composé de Sprites et de RectangleShapes, eh ben chacune doit changer son parent et c'est pas propre. Le vrai parent recherché est sf::Transformable. C'est ses attributs qu'on ré-utilise dans toutes ces classes utilisateurs quel que soit le Drawable utilisé. Mais ça, tous ne le savent pas. En forçant la séparation, tout le monde le saura.

14
En enlevant les attributs de Drawable de Shape, on pourrait utiliser cette classe pour les bounding boxes, et à tout moment, pour du debugging par exemple, les attacher à des Drawable afin qu'on puisse visualiser les collisions sans vraiment changer le code.

15
Oui, c'est vrai que ça n'a pas trop de sens. C'est peut-être mieux de répéter certaines méthodes.

Pages: [1] 2 3 4 Suivante »