【问题标题】:SDL2 events on mobile移动设备上的 SDL2 事件
【发布时间】:2016-03-31 15:49:41
【问题描述】:

由于 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在Android上默认处理手指事件的方式。

【问题讨论】:

  • 我认为我们可能会从更多细节中受益。有什么要显示的代码吗?
  • 好吧,我会试着安排一个有意义的sn-p。
  • 你说的一件事让我很困惑 - ... support both mobile and desktop environments for reasons that are beyond the purpose of the question. -> 你想在同一代码中同时支持 移动和桌面?
  • 我使用的是虚拟大小,但我想在开发阶段也可以在桌面环境(当然是高度信箱)上执行该代码。区别主要在于这些事件......
  • 你能在两个平台上只使用鼠标事件而忽略手指事件吗?

标签: c++ mobile sdl sdl-2 mobile-application


【解决方案1】:

很遗憾,没有此类特定于平台的停用参数。

因此,最简洁的方法是在初始化代码中使用 SDL_GetPlatform() 查询平台,如果是移动设备,则使用 SDL_SetEventFilter() 设置事件过滤器,以防止鼠标事件排队。 这并不完全是您期望的答案,但我没有看到其他 sdl 替代方案。

如果您控制事件循环的代码,一种更简单的方法是设置标志而不是事件过滤器,如果设置了标志,则对鼠标事件不执行任何操作。然而,第二种方法并不那么干净,因为您必须在所有代码中处理特定于平台的行为,而第一种方法则更加孤立。

【讨论】:

  • 很好的提示,但我发现了一个似乎是为了解决问题的 SDL2 提示参数。无论如何,谢谢你,赞成这个好建议。
【解决方案2】:

尽管我非常喜欢 Christophe 添加事件过滤器的想法,但我发现 SDL2 已经在 Android 上 gives support for this problem in terms of an hint

特别是存在提示SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH
可以通过SDL_SetHint 功能进行设置。有关详细信息,请参阅here

很简单:

SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");

根据提示的文档,默认设置为0,这意味着:

鼠标事件将作为触摸事件处理,触摸会引发假鼠标事件

没错,这是我的问题,但通过将其设置为1,我们可以得到以下内容:

鼠标事件将与纯触摸事件分开处理

因此,不再在 Android 设备上伪造鼠标事件。

默认值背后的原因对我来说不是很清楚,但这听起来确实是实现它的正确方法。

编辑(更多细节)

此更改似乎是最近才发生的。
Here 是 libsdl 论坛的链接,他们在此讨论由于引入此行为的补丁而出现的问题。
有人遇到了和我一样的问题,还有一些人也在试图解释为什么这个补丁被接受了。

编辑:替代解决方案

提示 SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCHSDL v2.0.4 起可用,因此对于较低版本的 SDL2 似乎唯一可行的解​​决方案是使用事件过滤器。

无论如何,我不鼓励使用SDL_GetPlatform 查询平台以确定是否设置事件过滤器。
相反,从SDL_MouseMotionEventSDL_MouseButtonEvent 的文档来看,存在which 参数:

[...] 可能是 SDL_TOUCH_MOUSEID,用于由触摸输入设备生成的事件,而不是真正的鼠标。如果您的应用程序已经处理 SDL_TouchFingerEvent,您可能希望忽略此类事件。

因此,无论底层平台是什么,我都建议设置一个事件过滤器,以便对事件进行排队或在需要时对其进行过滤。

【讨论】:

  • SDL_TOUCH_MOUSEID 是一种非常好的消除重复项的方法。鼠标和触摸事件仍然可以处理,并且避免了烦人的双重处理。
猜你喜欢
  • 2016-09-30
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
相关资源
最近更新 更多