Ten dylemat spotkałem z wejściem kontrolera Xbox. Chociaż nie dokładnie tak samo, jest cholernie podobny. Możesz zmienić kod w moim przykładzie, aby dostosować go do swoich potrzeb.
Edycja: Twoja sytuacja wykorzystałaby to ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
I możesz dowiedzieć się, jak utworzyć surową klasę wejściową za pomocą ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Ale ... teraz na super niesamowity algorytm ... nie bardzo, ale hej .. to całkiem fajne :)
* Więc ... możemy przechowywać stany każdego przycisku, które są wciśnięte, zwolnione i wstrzymane !!! Możemy również sprawdzić czas wstrzymania, ale wymaga to pojedynczego wyciągu if i możemy sprawdzić dowolną liczbę przycisków, ale dla niektórych informacji można znaleźć poniższe zasady.
Oczywiście, jeśli chcemy sprawdzić, czy coś jest wciśnięte, zwolnione itp., Zrobilibyśmy „If (This) {}”, ale pokazuje to, w jaki sposób możemy uzyskać stan prasy, a następnie wyłączyć następną klatkę, aby… ismousepressed ”będzie faktycznie fałszywy przy następnym sprawdzeniu.
Pełny kod tutaj:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Jak to działa..
Więc nie jestem pewien, jakie wartości otrzymujesz, gdy obrazujesz, czy przycisk jest wciśnięty, czy nie, ale w zasadzie, gdy ładuję w XInput, otrzymuję 16-bitową wartość między 0 a 65535, to ma 15 bitów możliwych stanów dla „wciśniętego”.
Problem występował za każdym razem, gdy to sprawdzałem. Po prostu dawał mi aktualny stan informacji. Potrzebowałem sposobu, aby przekonwertować bieżący stan na wartości wyciskane, zwolnione i wstrzymane.
Więc to, co zrobiłem, jest następujące.
Najpierw tworzymy zmienną „CURRENT”. Za każdym razem, gdy sprawdzamy te dane, ustawiamy „CURRENT” na zmienną „PREVIOUS”, a następnie przechowujemy nowe dane na „Current”, jak pokazano tutaj ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Dzięki tym informacjom jest to ekscytujące !!
Możemy teraz dowiedzieć się, czy przycisk jest ODŁĄCZONY!
BUTTONS_HOLD = LAST & CURRENT;
To robi w zasadzie porównuje dwie wartości i wszystkie naciśnięcia przycisków, które są pokazane w obu pozostaną 1, a wszystko inne ustawione na 0.
Tj. (1 | 2 | 4) i (2 | 4 | 8) da (2 | 4).
Teraz, kiedy już mamy, które przyciski są „HELD” w dół. Możemy zdobyć resztę.
Naciśnięcie jest proste. Przyjmujemy stan „AKTUALNY” i usuwamy wszystkie przytrzymane przyciski.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Wydany jest taki sam, tylko porównujemy go do naszego OSTATNEGO stanu.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Patrząc na sytuację z tłoczeniem. Jeśli powiedzmy, że obecnie mieliśmy 2 | 4 | 8 wciśnięty. Okazało się, że 2 | 4, gdzie odbyła się. Po usunięciu bitów trzymanych zostaje nam tylko 8. To nowo wciśnięty bit dla tego cyklu.
To samo można zastosować do wydania. W tym scenariuszu „OSTATNI” został ustawiony na 1 | 2 | 4. Więc kiedy usuniemy 2 | 4 bity. Pozostaje nam 1. Więc przycisk 1 został zwolniony od ostatniej klatki.
Powyższy scenariusz jest prawdopodobnie najbardziej idealną sytuacją, jaką możesz zaoferować do porównania bitów i zapewnia 3 poziomy danych bez instrukcji if lub pętli tylko 3 szybkie obliczenia bitów.
Chciałem również udokumentować dane wstrzymania, więc chociaż moja sytuacja nie jest idealna ... to w zasadzie ustawiamy ograniczenia, które chcemy sprawdzić.
Dlatego za każdym razem, gdy ustawiamy nasze dane Press / Release / Hold, sprawdzamy, czy dane hold nadal odpowiadają bieżącemu testowi bitów hold. Jeśli nie, resetujemy czas do aktualnego czasu. W moim przypadku ustawiam go na indeksy klatek, więc wiem, dla ilu klatek zostało wstrzymane.
Minusem tego podejścia jest to, że nie mogę uzyskać indywidualnych czasów wstrzymania, ale możesz sprawdzić wiele bitów jednocześnie. To znaczy, jeśli ustawię bit wstrzymania na 1 | 16, jeśli 1 lub 16 nie zostaną utrzymane, to się nie powiedzie. Wymaga to przytrzymania WSZYSTKICH tych przycisków, aby kontynuować tykanie.
Następnie, jeśli spojrzysz na kod, zobaczysz wszystkie fajne wywołania funkcji.
Twój przykład sprowadza się zatem do sprawdzenia, czy naciśnięcie przycisku miało miejsce, a naciśnięcie przycisku może wystąpić tylko raz przy użyciu tego algorytmu. Przy następnym sprawdzeniu, aby nacisnąć, nie będzie istnieć, ponieważ nie można nacisnąć więcej niż raz, aby zwolnić, zanim będzie można nacisnąć ponownie.