Я боролся в течение нескольких часов с ошибкой из-за поведения SDL2 из которых я ничего не знал.
В частности, я не знал, что на мобильном телефоне каждый раз, когда пользователь касается экрана, отправляются два события:
То же самое относится и к событиям «палец вверх» и «кнопка мыши»
Из-за них, внутренняя команда была брошена дважды, причиняя мне головную боль.
Цель состоит в том, чтобы поддерживать как мобильную, так и настольную среду по причинам, которые выходят за рамки вопроса.
Также я могу догадаться SDL2 работает так, чтобы поддерживать плавную миграцию уже существующей кодовой базы.
Во всяком случае, есть (позвольте мне сказать) SDL2-полосная запретить связанные с мышью события на мобильном телефоне?
Честно говоря, они не имеют большого смысла с моей точки зрения, и я хотел бы избавиться от них, если только программное обеспечение не выполняется в среде рабочего стола.
Кроме того, я не хочу ни использовать параметры времени компиляции, ни иметь выделенные части кода, целью которых является подавление этих событий на мобильных устройствах.
Код довольно прост. Ниже (возможно) значимый, сокращенный пример:
SDL_Event ev;
while(SDL_PollEvent(&ev)) {
switch(event.type) {
case SDL_FINGERDOWN:
// read it and throw an internal event E
break;
case SDL_MOUSEBUTTONDOWN:
// read it and throw an internal event E
break;
}
}
К сожалению, оба события выше читаются, когда пользователь касается экрана, как объяснено.
* РЕДАКТИРОВАТЬ *
Я не упомянул, что тестировал свое приложение на устройстве Android, и я уверен, что такая же проблема возникает на iOS.
Смотрите ответ ниже. Похоже, что вопрос (что до сих пор я понял, что это не совсем проблема) в основном из-за того, как SDL2 по умолчанию обрабатывает события finger на Android.
К сожалению, такого параметра деактивации для конкретной платформы нет.
Следовательно, самым чистым способом сделать это было бы в коде инициализации запросить платформу с помощью SDL_GetPlatform () и, если он мобильный, установить фильтр событий с помощью SDL_SetEventFilter (), который предотвращает постановку событий мыши в очередь.
Это не совсем ответ, который вы ожидаете, но я не вижу другой альтернативы SDL.
Более простой подход, если вы управляете кодом вашего цикла событий, состоит в том, чтобы установить флаг вместо фильтра событий, а если этот флаг установлен, ничего не делать с событием мыши. Этот второй подход, однако, не так чист, поскольку вы должны позаботиться о поведении платформы для всего своего кода, тогда как в первом варианте он гораздо более изолирован.
Хотя мне действительно нравится идея Кристофа добавить фильтр событий, я обнаружил, что SDL2 уже дает поддержку этой проблемы с точки зрения подсказки на андроид.
В частности, существует подсказка SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH.
Это можно установить с помощью функции SDL_SetHint
, Увидеть Вот для дальнейших деталей.
Это так просто, как:
SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
Начиная с документации подсказки, по умолчанию это установлено в 0
и это означает, что:
события мыши будут обрабатываться как события касания, а касание вызовет ложные события мыши
Это правда, это была моя проблема, но установив его 1
мы можем получить следующее:
события мыши будут обрабатываться отдельно от событий чистого касания
Таким образом, больше не фальшивые события мыши на устройствах Android.
Причина, по которой стоит значение по умолчанию, мне не так понятна, но этот действительно звучит как правильный способ его достижения.
РЕДАКТИРОВАТЬ (более подробно)
Это изменение кажется недавним.
Вот это ссылка на форум libsdl, где обсуждались проблемы, возникшие в результате патча, который вводил такое поведение.
У кого-то была такая же проблема, как и у меня, а некоторые пытались объяснить, почему патч был принят.
РЕДАКТИРОВАТЬ: альтернативное решение
Намек SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH доступно с SDL v2.0.4, так что кажется, что единственное жизнеспособное решение для более низких версий SDL2 это использовать фильтр событий.
Во всяком случае, я не рекомендую запрашивать платформу с помощью SDL_GetPlatform
для того, чтобы решить, следует ли устанавливать или не устанавливать фильтр событий.
Вместо этого, как из документации обоих SDL_MouseMotionEvent
а также SDL_MouseButtonEvent
, существует which
параметр, который:
[…] может быть SDL_TOUCH_MOUSEID для событий, которые были созданы устройством сенсорного ввода, а не реальной мышью. Возможно, вы захотите игнорировать такие события, если ваше приложение уже обрабатывает SDL_TouchFingerEvent.
В связи с этим я предлагаю установить фильтр событий независимо от того, что является базовой платформой, чтобы ставить в очередь события или фильтровать их при необходимости.