In realtà ho riscontrato questo dilemma con l'input del controller Xbox. Anche se non ESATTAMENTE lo stesso è abbastanza dannatamente simile. È possibile modificare il codice nel mio esempio in base alle proprie esigenze.
Modifica: la tua situazione userebbe questo ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
E puoi imparare come creare una classe di input non elaborata tramite ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Ma .. ora sull'algoritmo super fantastico ... non proprio, ma ehi .. è piuttosto bello :)
* Quindi ... possiamo memorizzare gli stati di ogni pulsante e quali sono premuti, rilasciati e tenuti giù !!! Possiamo anche controllare il tempo di attesa, ma ciò richiede una singola istruzione if e può controllare qualsiasi numero di pulsanti, ma ci sono alcune regole vedi sotto per queste informazioni.
Ovviamente se vogliamo controllare se qualcosa viene premuto, rilasciato, ecc. Dovresti fare "If (This) {}", ma questo sta mostrando come possiamo ottenere lo stato della stampa e quindi spegnerlo al prossimo frame in modo che il tuo " ismousepressed "sarà effettivamente falso al prossimo controllo.
Codice completo qui:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Come funziona..
Quindi non sono sicuro dei valori che ricevi quando descrivi se un pulsante viene premuto o meno, ma fondamentalmente quando carico in XInput ottengo un valore di 16 bit tra 0 e 65535, questo ha 15 bit possibili stati per "Pressato".
Il problema era ogni volta che lo controllavo. Mi avrebbe semplicemente fornito lo stato attuale delle informazioni. Avevo bisogno di un modo per convertire lo stato corrente in Pressed, Release e Hold Values.
Quindi quello che ho fatto è il seguente.
Per prima cosa creiamo una variabile "CORRENTE". Ogni volta che controlliamo questi dati impostiamo "CORRENTE" su una variabile "PRECEDENTE" e quindi memorizziamo i nuovi dati su "Corrente" come mostrato qui ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Con queste informazioni ecco dove diventa eccitante !!
Ora possiamo capire se un pulsante viene TENUTO IN BASSO!
BUTTONS_HOLD = LAST & CURRENT;
Ciò che fa è fondamentalmente confronta i due valori e qualsiasi pressione dei pulsanti mostrati in entrambi rimarrà 1 e tutto il resto impostato su 0.
Vale a dire (1 | 2 | 4) & (2 | 4 | 8) produrrà (2 | 4).
Ora che abbiamo quali pulsanti sono "HELD" verso il basso. Possiamo ottenere il resto.
Premuto è semplice .. prendiamo il nostro stato "CORRENTE" e rimuoviamo qualsiasi pulsante premuto.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Rilasciato è lo stesso solo se lo confrontiamo con il nostro ULTIMO stato.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Quindi guardando la situazione Pressed. Se diciamo che attualmente abbiamo avuto 2 | 4 | 8 premuto. Abbiamo trovato che 2 | 4 dove tenuto. Quando rimuoviamo gli Held Bits ci rimangono solo 8. Questo è il bit appena premuto per questo ciclo.
Lo stesso può essere applicato per Rilasciato. In questo scenario "ULTIMO" è stato impostato su 1 | 2 | 4. Quindi quando rimuoviamo il 2 | 4 bit. Siamo rimasti con 1. Quindi il pulsante 1 è stato rilasciato dall'ultimo fotogramma.
Questo scenario di cui sopra è probabilmente la situazione più ideale che puoi offrire per il confronto dei bit e fornisce 3 livelli di dati senza istruzioni if o per i loop con soli 3 calcoli di bit rapidi.
Volevo anche documentare i dati di conservazione, quindi anche se la mia situazione non è perfetta ... ciò che fa è fondamentalmente impostare le posizioni di attesa che vogliamo verificare.
Quindi ogni volta che impostiamo i nostri dati Stampa / Rilascio / Attesa controlliamo se i dati di attesa sono ancora uguali all'attuale controllo dei bit di attesa. In caso contrario, ripristiniamo l'ora corrente. Nel mio caso lo sto impostando su frame frame, quindi so per quanti frame è stato tenuto premuto.
L'aspetto negativo di questo approccio è che non riesco a ottenere singoli tempi di attesa, ma puoi controllare più bit contemporaneamente. Vale a dire se imposto il bit di mantenimento su 1 | 16 se 1 o 16 non vengono mantenuti, ciò fallirebbe. Quindi richiede che TUTTI quei pulsanti siano tenuti premuti per continuare a spuntare.
Quindi, se guardi nel codice, vedrai tutte le chiamate alle funzioni ordinate.
Quindi il tuo esempio verrebbe ridotto al semplice controllo della pressione di un pulsante e la pressione di un pulsante può avvenire una sola volta con questo algoritmo. Al prossimo controllo per premere non esisterà poiché non è possibile premere più di una volta che si dovrebbe rilasciare prima di poter premere di nuovo.