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

Auteur Sujet: [Résolu] Conception d'une classe Bouton  (Lu 2095 fois)

0 Membres et 1 Invité sur ce sujet

Greak

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
[Résolu] Conception d'une classe Bouton
« le: Février 10, 2016, 09:28:23 pm »
Bonjour !

Je suis actuellement en réflexion pour la conception d'une classe Bouton.
En fait, cette classe est déjà codée mais je ne suis pas très satisfait de son fonctionnement actuel.

Tout se déroule dans 3 classes : une classe "principale" qui gère le jeu de manière générale (ainsi que l'affichage), une classe "interface" qui va représenter par exemple un menu, et la classe Bouton.
Actuellement, la classe principale instancie la classe Menu. Menu instancie à son tour des boutons. On retourne ensuite dans la classe principale. Celle-ci traite les évènements dans une boucle :
  • Lors de l'évènement mouseMoved, on appelle une méthode de la classe Menu qui va indiquer à chaque bouton la position de la souris. Si la souris est sur un bouton particulier, celui-ci changera de texture.
  • Lors de l'évènement "clic gauche", on appelle une méthode de la classe Menu qui va indiquer à chaque bouton que la souris est enfoncée. Si la souris est sur un bouton, celui-ci changera de texture. Si la souris bouge par la suite (mais que le clic gauche est maintenu), on saura qu'elle est enfoncée et d'autres boutons changeront éventuellement de texture si la souris se pose dessus.
  • Lors de l'évènement "clic gauche relâché", on appelle la méthode précédente pour indiquer que le bouton n'est plus enfoncé et on appelle une méthode pour récupérer une enum indiquant quel bouton a été cliqué. Suivant le retour, on exécute le code approprié (dans un switch, dans la classe principale). Il peut s'agir de sauvegarder la partie, quitter le jeu, etc.

Cette solution est donc un peu lourde à utiliser. Il faut penser à appeler ces 3 méthodes à différents endroits du code de la classe principale. C'est un peu compliqué au début. Bref, ce n'est pas très bien pensé.

Je réfléchis donc à une autre solution, et celle-ci m'est venue en tête : utiliser des pointeurs de fonction.
Chaque bouton disposera d'un pointeur de fonction sur une méthode-membre de la classe principale permettant d'exécuter son code. Dans la boucle principale, on appellera également une méthode handleEvent des boutons leur indiquant l'évènement. Ensuite, le bouton change de texture si l'évènement est mouseMoved / buttonClicked, utilise le pointeur de fonction si l'évènement est buttonReleased...
Les avantages : c'est beaucoup plus facile à utiliser. On appelle une méthode pour donner quelques pointeurs au bouton quand on le crée, et on fait un for pour appeler la méthode handleEvent de chaque bouton à chaque fois qu'un nouvel évènement se produit. Le reste est géré par la classe Bouton.
Les inconvénients : chaque bouton doit désormais disposer de 4 pointeurs supplémentaires : un pointeur de fonction, comme je l'ai indiqué précédemment ; un pointeur vers l'instance de la classe principale pour utiliser le pointeur de fonction ; un pointeur vers la fenêtre (ou un getter dans la classe principale) pour savoir où se trouve la souris par exemple ; et un pointeur vers une éventuelle View (si le bouton est dans une View, il faudra disposer de la View pour convertir les coordonnées comme il faut et savoir si la souris est sur le bouton ou non).
En plus de ces 4 pointeurs, il y aura un for pour chaque bouton pour appeler handleEvent, même si l'évènement n'a rien à voir (on appuie sur une touche du clavier par exemple). Ce n'est pas très optimisé...


Là non plus, ce n'est pas idéal je trouve. J'aimerais donc savoir ce que vous pensez de ces 2 solutions, et si vous en avez d'autres à proposer, je vous écoute !
« Modifié: Février 12, 2016, 11:30:07 pm par Greak »

Nixon

  • Newbie
  • *
  • Messages: 7
    • Voir le profil
Re : Conception d'une classe Bouton
« Réponse #1 le: Février 12, 2016, 01:34:49 pm »

Salut,

Pour la première méthode:

c'est une méthode "classique" et c'est aussi à peu près comme cela que j'aurai procédé dans un premier temps.
Je pense qu'elle a l'avantage d'être robuste, simple à débugger.
Toute fois si tu reste sur celle-ci, tu peux surement l'améliorer.
Il serai judicieux d'utiliser les entrées temps réel :

sf::Mouse::isButtonPressed(sf::Mouse::Left) te dit directement si la sourie est enfoncée ou non et tu n'as plus qu'a vérifier si elle est sur un bouton ou non
voir : http://www.sfml-dev.org/tutorials/2.0/window-inputs-fr.php

La deuxième méthode :
Mon conseil, oublie les pointeurs de fonction, c'est plutôt dangereux.
En revanche, tu peux très bien récupérer un pointeur vers ta classe principale et faire un principale->taFonction() , ce sera bien plus propre.
Je pense que c'est à essayer. J'avais implémenté le même genre de fonctionnement pour changer d'écran, ça ne m'avais pas vraiment plus mais c'était intéressant à programmer. 

Bonne continuation :)

Greak

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
Re : Conception d'une classe Bouton
« Réponse #2 le: Février 12, 2016, 11:29:39 pm »
Oui je vois. Je crois que je vais prendre un peu des 2.
Déjà je vais utiliser les entrées temps réel, ça sera mieux en effet, et ça supprimera la 2e méthode (lors d'un clic gauche : indiquer à tous les boutons si la souris est désormais enfoncée ou non).
Ensuite je vais peut-être faire comme tu as dit pour la 2e méthode. Ca allègera un peu l'exécution des actions liées au bouton (on n'aura plus un gros switch pour faire ce qu'il faut suivant le bouton. Le menu s'en occupera lui même en appelant la bonne méthode de la classe principale, et cette dernière n'aura plus qu'à indiquer au menu qu'il y a eu un clic.

Merci pour ta réponse très utile ! :)

Edit : Je mets en [Résolu] mais si quelqu'un voulait ajouter un élément à la discussion, qu'il n'hésite pas !