Aslında Xbox Controller Input ile bu ikilemle karşılaştım. TAM olarak aynı olmasa da oldukça benzer. Örneğimdeki kodu ihtiyaçlarınıza göre değiştirebilirsiniz.
Düzenleme: Durumunuz bunu kullanır ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
Ham giriş sınıfının nasıl oluşturulacağını ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Ama .. şimdi süper müthiş algoritmaya ... gerçekten değil, ama hey .. çok güzel :)
* Yani ... her düğmenin durumlarını kaydedebiliriz ve Basılan, Serbest Bırakılan ve Tutulan !!! Bekleme Süresini de kontrol edebiliriz, ancak bu tek bir if ifadesi gerektirir ve herhangi bir sayıda düğmeyi kontrol edebilir, ancak bu bilgi için aşağıda bazı kurallar vardır.
Açıkçası, eğer bir şeye basıldığını, serbest bırakıldığını vb. Kontrol etmek istiyorsak, "If (This) {}" yaparsınız, ancak bu, basın durumunu nasıl alıp bir sonraki kareyi nasıl kapatacağımızı gösteriyor. bir dahaki sefere kontrol ettiğinizde aslında yanlış olacaktır.
Tam Kodu Burada:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Nasıl çalışır..
Bu nedenle, bir düğmeye basıldığını veya basmadığını tasvir ettiğinizde aldığınız değerlerden emin değilim, ancak temel olarak XInput'a yüklediğimde, 0 ile 65535 arasında 16 bitlik bir değer elde ediyorum, bu "Basılı" için 15 bit olası durumlara sahip.
Sorun bunu her kontrol ettiğimde sadece bana bilginin mevcut durumunu verecekti. Mevcut durumu Preslenmiş, Serbest Bırakılan ve Tutulan Değerlere dönüştürmek için bir yola ihtiyacım vardı.
Yani yaptığım şey şu.
Önce bir "CURRENT" değişkeni yaratırız. Bu verileri her kontrol ettiğimizde, "AKIM" i "ÖNCEKİ" bir değişkene ayarlıyoruz ve ardından yeni verileri burada görüldüğü gibi "Güncel" olarak saklıyoruz ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Bu bilgi ile burada heyecan verici olsun !!
Şimdi bir Düğme AŞAĞIYI YAPILIR MIYORUZ!
BUTTONS_HOLD = LAST & CURRENT;
Bunun temelde iki değeri karşılaştırmasıdır ve her ikisinde de gösterilen herhangi bir düğmeye basıldığında 1 kalır ve diğer her şey 0'a ayarlanır.
Yani (1 | 2 | 4) & (2 | 4 | 8) (2 | 4) verimini verecektir.
Şimdi hangi düğmelerin "HELD" (aşağı). Gerisini biz alabiliriz.
Basılı basittir ... "AKIM" durumumuzu alır ve basılı düğmeleri kaldırırız.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Sadece LAST durumumuzla karşılaştırdığımızda aynı çıktı.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Preslenmiş duruma bakalım. Eğer diyelim Şu anda 2 | 4 | 8 basıldı. Biz buldum 2 | 4 nerede tutulur. Tutulan Bitleri kaldırdığımızda sadece 8 kaldı. Bu, bu döngü için yeni basılan bit.
Aynısı Released için de uygulanabilir. Bu senaryoda "SON" 1 | 2 | 4. Yani 2'yi kaldırdığımızda | 4 bit. 1 ile kaldık. Düğme 1 son kareden beri serbest bırakıldı.
Yukarıdaki senaryo, muhtemelen bit karşılaştırması için sunabileceğiniz en ideal durumdur ve if ifadeleri olmadan 3 seviye veri veya döngüler için sadece 3 hızlı bit hesaplaması sağlar.
Bekletme verilerini de belgelemek istedim, bu yüzden durumum mükemmel olmasa da ... temelde kontrol etmek istediğimiz bekletmeleri ayarladık.
Bu nedenle, Basın / Bırak / Beklet verilerimizi her ayarladığımızda, bekletme verilerinin halen geçerli bekletme bit kontrolüne eşit olup olmadığını kontrol ederiz. Eğer yapmazsak, zamanı şimdiki zamana sıfırlıyoruz. Benim durumumda kare dizinleri için ayarlıyorum, bu yüzden kaç kare tutulduğunu biliyorum.
Bu yaklaşımın dezavantajı, bireysel tutma süreleri alamıyorum, ancak aynı anda birden fazla biti kontrol edebilirsiniz. Yani tutma biti 1 | 16 1 veya 16 tutulmazsa bu başarısız olur. Bu yüzden TÜM bu düğmelerin işaretlemeye devam etmesini gerektirir.
Eğer koda bakarsanız, tüm düzgün fonksiyon çağrılarını göreceksiniz.
Böylece, örneğiniz basitçe bir tuşa basmanın gerçekleşip gerçekleşmediğini ve bir tuşa basmanın bu algoritma ile yalnızca bir kez gerçekleşip gerçekleşmeyeceğini kontrol etmek için azaltılacaktır. Bir sonraki basışınızda, tekrar basmadan önce bırakmanız gerekenden daha sonra basamayacağınız için mevcut olmayacaktır.