未检测到 SDL2 iOS 多点触控第二个手指向下

Posted

技术标签:

【中文标题】未检测到 SDL2 iOS 多点触控第二个手指向下【英文标题】:SDL2 iOS multitouch second finger down not detected 【发布时间】:2019-02-16 02:36:35 【问题描述】:

我正在开发一个已移植到 ios 的 SDL2 项目。 我在注册 2 次触摸以用作游戏控件时遇到问题。

控件的工作方式如下:

iOS Device
+---------------+
|   F   |   |   |
|-------| L | R |
|   B   |   |   |
+---------------+

F - 前进

B - 向后移动

L - 左转

R - 右转

玩家应该能够同时向前移动和转动——这意味着我必须同时处理两个单独的触摸,而不是多点触控手势。

这是在我的项目中执行此操作的代码示例。

while (SDL_PollEvent(&event)) 
    printf("event %#010x\n", event.type);
    switch (event.type) 
        case SDL_FINGERDOWN:
        //case SDL_FINGERMOTION:
            if (event.tfinger.x < 0.5)  
                lastMoveFinger = event.tfinger.fingerId;
                isMoving = true;
                if (event.tfinger.y < 0.5)  
                    mvForward = true;
                 else  
                    mvForward = false;
                
             else  
                lastTurnFinger = event.tfinger.fingerId;
                isTurning = true;
                if (event.tfinger.x < 0.75)  
                    turnRight = false;
                 else  
                    turnRight = true;
                
            
            break;
        case SDL_FINGERUP:
            if (event.tfinger.x < 0.5 || event.tfinger.fingerId == lastMoveFinger) 
                lastMoveFinger = -1;
                isMoving = false;
             else 
                lastTurnFinger = -1;
                isTurning = false;
            
            break;
    

会发生什么:

    将第一根手指放在屏幕上(按住不放) 注册第一个触摸事件 将第二根手指放在屏幕上。 没有注册第二次触摸,但触发了多点触控手势事件(我使用printf 捕获了这些事件)。

我发现一个有趣的事情是,如果我处理 SDL_FINGERMOTION 两个触摸都注册在正确的位置 - 但这不起作用,因为它不会检测到单次点击,而是仅在手指移动时起作用。所以看起来多点触控正在工作,但也许我没有正确处理它。

这里是来自SDL_events.h的触摸事件供参考

/* Touch events */
SDL_FINGERDOWN      = 0x700,
SDL_FINGERUP,
SDL_FINGERMOTION,

这是事件流的示例。我放下一根手指,然后放下第二根手指,然后举起第一根,然后举起第二根。

event 0x00000401
event 0x00000700 // Finger down
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000802
event 0x00000702
event 0x00000802
event 0x00000402
event 0x00000701 // Finger up

请注意,有很多手指运动 - 但只有 1 个手指向上和向下事件。如果稍后有时间,我将使用屏幕上当前手指数的打印输出来更新它,以说明第二个手指向下事件永远不会触发。

【问题讨论】:

据我所知,SDL 多点触控/手势是根据之前的手指向下/移动/向上事件处理的,因此您不太可能获得多点触控事件但没有第二次手指向下。会不会是您的问题实际上出在您对所述事件的反应方式上?你能打印f-dump full tfinger state on fingerdown event 和 mgesture state on multitouch event,并将结果附加到问题吗? 我在问题中添加了一个示例事件流。我做了进一步的测试。我发现如果我在事件轮询循环中调用SDL_GetTouchFinger - 我可以独立检测到两个手指。如果我无法让手指向上/向下事件起作用,我将改用这种方法。 您是否尝试过从最新源构建?这确实感觉像是一个错误,特别是考虑到您确实得到了SDL_FINGERMOTION。如果您有触摸板,您也可以尝试使用 Mac 进行测试。或者可能是 android 设备? 【参考方案1】:

查看source code,我发现应该为发送到SDL_uikitview::touchesBegan 处理程序(UIView 的SDL 子类)的每个手指(NSEvent)调用SDL_SendTouch()。我对 UIKit 的记忆不够,无法在这里评论预期的行为,但您可以附加一个调试器并亲自查看它是否获得了预期的 NSEvents 数量。

如果NSEvents 的数量和类型与您的预期不符,那么 SDL 似乎无能为力。如果它们与您预期的一样,则表明 SDL 中存在错误。

具体来说,查看the source for SDL_SendTouch 作为另一个放置断点的地方。在某些情况下,该函数可以退出:

   228 SDL_Touch* touch = SDL_GetTouch(id);
   229     if (!touch) 
   230         return -1;
   231     
   232 
   233     finger = SDL_GetFinger(touch, fingerid);
   234     if (down) 
   235         if (finger) 
   236             /* This finger is already down */
   237             return 0;
   238         
   239 
   240         if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) 
   241             return 0;
   242         

【讨论】:

以上是关于未检测到 SDL2 iOS 多点触控第二个手指向下的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UIPageViewController 上禁用多点触控?

iOS 数据结构维护多点触控痕迹?

防止多点触控的 UIButton 触摸事件

didSelectRowAt 仅在多点触控时调用

使用 PointerEvents 在同一目标上检测两个手指触摸

使用声音池的android多点触控