Ich bin tatsächlich mit Xbox Controller Input auf dieses Dilemma gestoßen. Obwohl es nicht genau das gleiche ist, ist es ziemlich ähnlich. Sie können den Code in meinem Beispiel an Ihre Bedürfnisse anpassen.
Bearbeiten: Ihre Situation würde dies verwenden ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
Und Sie können lernen, wie Sie eine rohe Eingabeklasse über -> erstellen
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Aber ... jetzt zu dem super genialen Algorithmus ... nicht wirklich, aber hey ... es ist ziemlich cool :)
* Also ... wir können die Zustände jeder Taste speichern, die gedrückt, losgelassen und gedrückt gehalten werden !!! Wir können auch die Haltezeit überprüfen. Dies erfordert jedoch eine einzelne if-Anweisung und kann eine beliebige Anzahl von Schaltflächen überprüfen. Für diese Informationen gelten jedoch einige Regeln (siehe unten).
Wenn wir überprüfen möchten, ob etwas gedrückt, freigegeben usw. ist, würden Sie natürlich "If (This) {}" ausführen. Dies zeigt jedoch, wie wir den Druckstatus abrufen und ihn dann beim nächsten Frame ausschalten können, damit Ihr " "ismousepressed" wird beim nächsten Überprüfen tatsächlich falsch sein.
Vollständiger Code hier:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Wie es funktioniert..
Ich bin mir also nicht sicher, welche Werte Sie erhalten, wenn Sie angeben, ob eine Taste gedrückt wurde oder nicht, aber wenn ich in XInput lade, erhalte ich einen 16-Bit-Wert zwischen 0 und 65535. Dies hat 15-Bit-Zustände für "Gedrückt".
Das Problem war jedes Mal, wenn ich dies überprüfte. Es gab mir einfach den aktuellen Stand der Informationen. Ich brauchte eine Möglichkeit, den aktuellen Status in "Gedrückt", "Freigegeben" und "Werte halten" umzuwandeln.
Also, was ich getan habe, ist das Folgende.
Zuerst erstellen wir eine "CURRENT" -Variable. Jedes Mal, wenn wir diese Daten überprüfen, setzen wir den "CURRENT" auf eine "PREVIOUS" -Variable und speichern die neuen Daten unter "Current", wie hier zu sehen ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Mit diesen Informationen wird es hier spannend !!
Wir können jetzt herausfinden, ob ein Button heruntergedrückt wird!
BUTTONS_HOLD = LAST & CURRENT;
Im Grunde werden die beiden Werte verglichen, und alle in beiden angezeigten Tastendrücke bleiben auf 1 und alle anderen auf 0 gesetzt.
Dh (1 | 2 | 4) & (2 | 4 | 8) ergibt (2 | 4).
Nun, da wir welche Tasten haben, sind "HELD" gedrückt. Wir können den Rest besorgen.
Gedrückt ist einfach. Wir nehmen unseren "CURRENT" -Zustand an und entfernen alle gedrückten Knöpfe.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Released ist dasselbe, nur dass wir es stattdessen mit unserem LAST-Status vergleichen.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Also schaut euch die Pressed-Situation an. Sagen wir mal Derzeit hatten wir 2 | 4 | 8 gedrückt. Wir fanden, dass 2 | 4 wo gehalten. Wenn wir die gehaltenen Bits entfernen, bleiben uns nur noch 8 übrig. Dies ist das neu gedrückte Bit für diesen Zyklus.
Gleiches gilt für Freigegeben. In diesem Szenario wurde "LAST" auf 1 | gesetzt 2 | 4. Wenn wir also die 2 | entfernen 4 Bits. Wir bleiben mit 1 zurück. Also wurde die Taste 1 seit dem letzten Frame losgelassen.
Dieses obige Szenario ist wahrscheinlich die idealste Situation, die Sie für den Bitvergleich anbieten können, und bietet 3 Datenebenen ohne if-Anweisungen oder für Schleifen nur 3 schnelle Bitberechnungen.
Ich wollte auch Haltedaten dokumentieren, obwohl meine Situation nicht perfekt ist. Wir haben im Grunde genommen die Haltebits festgelegt, auf die wir prüfen möchten.
Jedes Mal, wenn wir unsere Press / Release / Hold-Daten einstellen, prüfen wir, ob die Hold-Daten immer noch der aktuellen Hold-Bit-Prüfung entsprechen. Wenn dies nicht der Fall ist, wird die Zeit auf die aktuelle Zeit zurückgesetzt. In meinem Fall setze ich es auf Frame-Indizes, damit ich weiß, für wie viele Frames es gedrückt wurde.
Der Nachteil dieses Ansatzes ist, dass ich keine einzelnen Haltezeiten erhalte, aber Sie können mehrere Bits gleichzeitig prüfen. Dh wenn ich das Haltebit auf 1 | setze 16, wenn entweder 1 oder 16 nicht gehalten werden, würde dies fehlschlagen. Daher müssen ALLE diese Schaltflächen gedrückt gehalten werden, um das Ticking fortzusetzen.
Wenn Sie dann in den Code schauen, sehen Sie alle ordentlichen Funktionsaufrufe.
Ihr Beispiel würde sich also darauf beschränken, einfach zu überprüfen, ob ein Tastendruck stattgefunden hat und ein Tastendruck mit diesem Algorithmus nur einmal auftreten kann. Bei der nächsten Überprüfung ist dies nicht der Fall, da Sie nicht mehr als einmal drücken können, bevor Sie erneut drücken können.