Я действительно столкнулся с этой дилеммой с вводом контроллера Xbox. Хотя не совсем то же самое, это чертовски похоже. Вы можете изменить код в моем примере, чтобы удовлетворить ваши потребности.
Изменить: Ваша ситуация будет использовать это ->
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse
И вы можете узнать, как создать необработанный входной класс через ->
https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input
Но ... теперь на супер удивительный алгоритм ... не совсем, но эй .. это довольно круто :)
* Итак ... мы можем хранить состояния каждой кнопки, которые нажаты, отпущены и удержаны !!! Мы также можем проверить время удержания, но для этого требуется один оператор if и можно проверить любое количество кнопок, но некоторые правила см. Ниже для получения этой информации.
Очевидно, что если мы хотим проверить, нажалось ли что-то, отпущено и т. Д., Вы бы сделали «If (This) {}», но это показывает, как мы можем получить состояние нажатия, а затем отключить его в следующем кадре, чтобы ваш » ismousepressed "на самом деле будет ложным при следующей проверке.
Полный код здесь:
https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp
Как это устроено..
Поэтому я не уверен, что значения, которые вы получаете, когда изображаете, нажата ли кнопка или нет, но в основном, когда я загружаю в XInput, я получаю 16-битное значение в диапазоне от 0 до 65535, это имеет 15-битные возможные состояния для «Нажата».
Проблема заключалась в том, что каждый раз, когда я проверял это, он просто давал мне текущее состояние информации. Мне нужен был способ конвертировать текущее состояние в значения Pressed, Released и Hold.
Так что я сделал следующее.
Сначала мы создаем переменную "CURRENT". Каждый раз, когда мы проверяем эти данные, мы устанавливаем «CURRENT» в переменную «PREVIOUS», а затем сохраняем новые данные в «Current», как показано здесь ->
uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;
С этой информацией вот где она становится захватывающей!
Теперь мы можем выяснить, если кнопка удерживается!
BUTTONS_HOLD = LAST & CURRENT;
Это в основном сравнивает два значения, и любые нажатия кнопок, показанные на обоих, останутся равными 1, а все остальное будет установлено на 0.
Т.е. (1 | 2 | 4) & (2 | 4 | 8) даст (2 | 4).
Теперь, когда у нас есть какие кнопки "HELD" вниз. Мы можем получить отдых.
Нажать просто ... мы берем наше состояние "CURRENT" и удаляем все удерживаемые кнопки.
BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;
Выпущено то же самое, только мы сравниваем его с нашим последним состоянием.
BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;
Итак, глядя на пресс-ситуацию. Если скажем В настоящее время у нас было 2 | 4 | 8 нажат. Мы обнаружили, что 2 | 4, где проводится. Когда мы удаляем удерживаемые биты, у нас остается только 8. Это недавно нажатый бит для этого цикла.
То же самое можно применить для выпущенных. В этом сценарии «LAST» был установлен в 1 | 2 | 4. Итак, когда мы удаляем 2 | 4 бита У нас осталось 1. Итак, кнопка 1 была отпущена с момента последнего кадра.
Этот сценарий является, пожалуй, самой идеальной ситуацией, которую вы можете предложить для сравнения битов, и он предоставляет 3 уровня данных без операторов if или для циклов, всего 3 быстрых вычисления битов.
Я также хотел документировать данные о хранении, так что, хотя моя ситуация не идеальна ... что мы делаем, мы в основном устанавливаем уровни ожидания, которые мы хотим проверять.
Таким образом, каждый раз, когда мы устанавливаем наши данные Press / Release / Hold, мы проверяем, равны ли данные удержания текущей проверке бит удержания. Если это не так, мы сбрасываем время на текущее время. В моем случае я настраиваю его на индексы кадров, чтобы я знал, сколько кадров он удерживал.
Недостатком этого подхода является то, что я не могу получить индивидуальное время удержания, но вы можете проверить несколько битов одновременно. Т.е. если я установлю бит удержания на 1 | 16, если 1 или 16 не удерживаются, это потерпит неудачу. Таким образом, требуется, чтобы все эти кнопки были нажаты, чтобы продолжить тикать.
Затем, если вы посмотрите в коде, вы увидите все аккуратные вызовы функций.
Таким образом, ваш пример сводится к простой проверке того, произошло ли нажатие кнопки, и нажатие кнопки может произойти только один раз с этим алгоритмом. При следующей проверке нажать не будет, так как вы не можете нажать больше, чем один раз, когда вам нужно будет отпустить, прежде чем вы сможете нажать снова.