Tôi thực sự đã gặp phải vấn đề nan giải này với Đầu vào bộ điều khiển Xbox. Mặc dù không chính xác giống nhau nhưng nó khá giống nhau. Bạn có thể thay đổi mã trong ví dụ của tôi để phù hợp với nhu cầu của bạn.
Chỉnh sửa: Tình huống của bạn sẽ sử dụng điều này ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
Và bạn có thể tìm hiểu cách tạo một lớp đầu vào thô thông qua ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Nhưng .. bây giờ vào thuật toán siêu tuyệt vời ... không thực sự, nhưng hey .. nó khá tuyệt :)
* Vì vậy, ... chúng ta có thể lưu trữ trạng thái của mọi nút và được nhấn, phát hành và giữ xuống !!! Chúng tôi cũng có thể kiểm tra Thời gian giữ, nhưng điều đó yêu cầu một câu lệnh if duy nhất và có thể kiểm tra bất kỳ số lượng nút nào, nhưng có một số quy tắc xem bên dưới để biết thông tin này.
Rõ ràng nếu chúng tôi muốn kiểm tra xem có thứ gì được nhấn, phát hành hay không, v.v. bạn sẽ làm "Nếu (Cái này) {}", nhưng điều này cho thấy cách chúng tôi có thể lấy trạng thái báo chí và sau đó tắt khung hình tiếp theo để " ismousepressed "sẽ thực sự sai trong lần kiểm tra tiếp theo.
Mã đầy đủ ở đây:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Làm thế nào nó hoạt động..
Vì vậy, tôi không chắc chắn các giá trị bạn nhận được khi bạn mô tả nếu nhấn nút hay không, nhưng về cơ bản khi tôi tải trong XInput, tôi nhận được giá trị 16 bit trong khoảng từ 0 đến 65535, điều này có 15 bit trạng thái có thể cho "Đã nhấn".
Vấn đề là mỗi khi tôi kiểm tra điều này Nó sẽ chỉ cho tôi trạng thái hiện tại của thông tin. Tôi cần một cách để chuyển đổi trạng thái hiện tại thành các giá trị bị ép, phát hành và giữ.
Vì vậy, những gì tôi đã làm là sau đây.
Đầu tiên chúng ta tạo một biến "HIỆN TẠI". Mỗi lần kiểm tra dữ liệu này, chúng tôi đặt "HIỆN TẠI" thành biến "TRƯỚC" và sau đó lưu trữ dữ liệu mới thành "Hiện tại" như được thấy ở đây ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
Với thông tin này, đây là nơi thú vị !!
Bây giờ chúng ta có thể tìm ra nếu một Nút đang được H HEL TRỢ XUỐNG!
BUTTONS_HOLD = LAST & CURRENT;
Những gì nó làm về cơ bản là so sánh hai giá trị và bất kỳ lần nhấn nút nào được hiển thị trong cả hai sẽ giữ nguyên 1 và mọi thứ khác được đặt thành 0.
Tức là (1 | 2 | 4) & (2 | 4 | 8) sẽ mang lại (2 | 4).
Bây giờ chúng ta có các nút "H HEL TRỢ" xuống. Chúng ta có thể nhận phần còn lại.
Nhấn là đơn giản .. chúng tôi lấy trạng thái "HIỆN TẠI" và loại bỏ bất kỳ nút nhấn nào.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Thay vào đó, chúng tôi chỉ so sánh nó với trạng thái LAST của chúng tôi.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Vì vậy, nhìn vào tình hình Pressed. Nếu chúng ta nói Hiện tại chúng ta đã có 2 | 4 | 8 ép. Chúng tôi thấy rằng 2 | 4 nơi tổ chức. Khi chúng ta loại bỏ Held Bits, chúng ta chỉ còn lại 8. Đây là bit mới được nhấn cho chu trình này.
Điều tương tự có thể được áp dụng cho Phát hành. Trong kịch bản này, "LAST" đã được đặt thành 1 | 2 | 4. Vì vậy, khi chúng tôi loại bỏ 2 | 4 bit. Chúng tôi chỉ còn lại 1. Vì vậy, nút 1 đã được phát hành kể từ khung cuối cùng.
Kịch bản trên có lẽ là tình huống lý tưởng nhất mà bạn có thể đưa ra để so sánh bit và nó cung cấp 3 cấp độ dữ liệu mà không có câu lệnh if hoặc cho các vòng lặp chỉ bằng 3 phép tính bit nhanh.
Tôi cũng muốn ghi lại dữ liệu giữ vì vậy mặc dù tình huống của tôi không hoàn hảo ... về cơ bản, chúng tôi sẽ thiết lập các khoản giữ mà chúng tôi muốn kiểm tra.
Vì vậy, mỗi khi chúng tôi đặt dữ liệu Báo chí / Phát hành / Giữ, chúng tôi sẽ kiểm tra xem dữ liệu giữ có bằng với kiểm tra bit giữ hiện tại không. Nếu không, chúng tôi sẽ đặt lại thời gian hiện tại. Trong trường hợp của tôi, tôi đang đặt nó thành các chỉ mục khung để tôi biết nó được giữ bao nhiêu khung.
Nhược điểm của phương pháp này là tôi không thể có thời gian giữ riêng lẻ, nhưng bạn có thể kiểm tra nhiều bit cùng một lúc. Tức là nếu tôi đặt bit giữ thành 1 | 16 nếu 1 hoặc 16 không được giữ thì điều này sẽ thất bại. Vì vậy, nó yêu cầu TẤT CẢ các nút đó được giữ để tiếp tục đánh dấu.
Sau đó, nếu bạn nhìn vào mã, bạn sẽ thấy tất cả các lệnh gọi hàm gọn gàng.
Vì vậy, ví dụ của bạn sẽ được giảm xuống chỉ đơn giản là kiểm tra xem có xảy ra nhấn nút hay không và chỉ nhấn nút một lần với thuật toán này. Ở lần kiểm tra tiếp theo, nhấn nó sẽ không tồn tại vì bạn không thể nhấn nhiều hơn sau đó một khi bạn phải phát hành trước khi bạn có thể nhấn lại.