En fait, je suis tombé sur ce dilemme avec l'entrée de contrôleur Xbox. Bien que ce ne soit pas exactement le même, c'est assez similaire. Vous pouvez changer le code dans mon exemple pour l'adapter à vos besoins.
Edit: Votre situation utiliserait ceci ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
Et vous pouvez apprendre à créer une classe d'entrée brute via ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Mais .. maintenant sur l'algorithme super génial ... pas vraiment, mais bon .. c'est plutôt cool :)
* Donc ... nous pouvons stocker les états de chaque bouton et qui sont enfoncés, relâchés et maintenus enfoncés !!! Nous pouvons également vérifier le temps d'attente, mais cela nécessite une seule instruction if et peut vérifier n'importe quel nombre de boutons, mais il existe certaines règles, voir ci-dessous pour ces informations.
Evidemment, si nous voulons vérifier si quelque chose est pressé, relâché, etc. ismousepressed "sera en fait faux lors de votre prochaine vérification.
Code complet ici:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Comment ça fonctionne..
Donc, je ne suis pas sûr des valeurs que vous recevez lorsque vous décrivez si un bouton est enfoncé ou non, mais fondamentalement, lorsque je charge dans XInput, j'obtiens une valeur de 16 bits entre 0 et 65535, cela a 15 bits possibles pour "Pressé".
Le problème était à chaque fois que je vérifiais cela. Cela me donnerait simplement l'état actuel des informations. J'avais besoin d'un moyen de convertir l'état actuel en valeurs Pressed, Released et Hold.
Donc ce que j'ai fait est le suivant.
Nous créons d'abord une variable "CURRENT". Chaque fois que nous vérifions ces données, nous définissons le "CURRENT" sur une variable "PREVIOUS", puis stockons les nouvelles données sur "Current" comme on le voit ici ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Avec ces informations, voici où ça devient passionnant !!
Nous pouvons maintenant déterminer si un bouton est enfoncé!
BUTTONS_HOLD = LAST & CURRENT;
Ce que cela fait, c'est essentiellement qu'il compare les deux valeurs et toutes les pressions sur les boutons qui sont affichées dans les deux resteront 1 et tout le reste réglé sur 0.
C'est-à-dire (1 | 2 | 4) & (2 | 4 | 8) donnera (2 | 4).
Maintenant que nous avons les boutons "HELD" enfoncés. Nous pouvons obtenir le reste.
Pressé est simple .. nous prenons notre état "COURANT" et supprimons tous les boutons enfoncés.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Publié est le même que nous le comparons à notre DERNIER état à la place.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Donc, en regardant la situation pressée. Si disons Actuellement, nous en avions 2 | 4 | 8 pressé. Nous avons constaté que 2 | 4 lieu. Lorsque nous supprimons les bits maintenus, il ne nous reste que 8. Il s'agit du bit nouvellement pressé pour ce cycle.
La même chose peut être appliquée pour Released. Dans ce scénario, "LAST" a été défini sur 1 | 2 | 4. Ainsi, lorsque nous supprimons le 2 | 4 bits. Il nous reste 1. Alors le bouton 1 a été relâché depuis la dernière image.
Ce scénario ci-dessus est probablement la situation la plus idéale que vous pouvez offrir pour la comparaison de bits et il fournit 3 niveaux de données sans instructions if ou pour les boucles, juste 3 calculs de bits rapides.
Je voulais également documenter les données de retenue, donc bien que ma situation ne soit pas parfaite ... ce qu'elle fait, nous définissons essentiellement les bits de retenue que nous voulons vérifier.
Ainsi, chaque fois que nous définissons nos données de presse / libération / attente, nous vérifions si les données de conservation sont toujours égales à la vérification actuelle du bit de conservation. Si ce n'est pas le cas, nous réinitialisons l'heure à l'heure actuelle. Dans mon cas, je le définis sur des index de trame, donc je sais pour combien de trames il a été maintenu enfoncé.
L'inconvénient de cette approche est que je ne peux pas obtenir de temps d'attente individuel, mais vous pouvez vérifier plusieurs bits à la fois. C'est-à-dire si je mets le bit de maintien à 1 | 16 si 1 ou 16 ne sont pas tenus, cela échouera. Il faut donc que TOUS ces boutons soient maintenus enfoncés pour continuer à cocher.
Ensuite, si vous regardez dans le code, vous verrez tous les appels de fonction soignés.
Ainsi, votre exemple serait réduit à simplement vérifier si une pression sur un bouton s'est produite et une pression sur un bouton ne peut se produire qu'une seule fois avec cet algorithme. Lors de la prochaine vérification, il n'existera pas, car vous ne pouvez pas appuyer plus d'une fois que vous devrez relâcher avant de pouvoir appuyer à nouveau.