【发布时间】:2011-11-13 00:22:06
【问题描述】:
游戏需要对键盘输入进行低级访问。在 Windows 上,有 DirectInput。但是 Mac OS X 游戏开发者使用什么技术呢?
显然,有足够多的 Mac 游戏可以恰到好处地输入键盘,而没有常见解决方案的缺点:
解决方案 #1:Use keyUp / keyDown events
-(void)keyUp:(NSEvent*)event;
-(void)keyDown:(NSEvent*)event;
不可接受的缺点: keyDown 事件会根据“按键重复率”和“按键重复延迟”的系统偏好设置重复。这会导致一个初始 keyDown 事件,然后在它开始以系统首选项设置定义的速率重复之前暂停。此方案不能用于连续的关键事件。
我想知道是否可以禁用按键重复行为?我想您可以读取第一个 keyDown 键,然后在您的类中记住“带有 keyCode x 的键已关闭”状态,直到收到该键的 keyUp 事件,从而绕过重复延迟和重复率问题。
解决方案 #2:Use Quarts Event Taps
见Quartz Event Services Reference。它似乎足够低级。
不可接受的缺点: 需要在通用访问 - 键盘下的系统首选项中启用辅助设备。虽然这可能默认开启,但不能保证它可能会在某些系统上关闭。
我还读到 Quartz 事件点击需要应用程序以 root 身份运行,但没有找到对此的确认。
解决方案 #3:Carbon Events / IOKit HID
Carbon Event Manager Reference 被标记为旧版,不应用于新开发。
不可接受的缺点:没有人知道未来的 Mac OS 版本会继续支持 Carbon 事件多长时间。
除了 Carbon 是一个遗留框架之外,这似乎仍然是最好的解决方案。但是使用 Carbon Events 还有其他缺点吗?
问题:
Mac OS X 游戏开发人员使用哪种技术来接收低级键盘输入事件?如果他们使用上述技术之一,他们如何解决我提到的缺点?
更新:
我最终转而使用常规的 NSEvent 消息并将它们包装在 neat API for polling the keyboard states 中。
【问题讨论】:
-
为什么 keyDown: 的重复行为不可接受?在获得 keyUp 之前,您不能忽略其他事件吗?
-
我真的不知道最好的解决方案是什么,但关于解决方案 #1 的缺点 -
NSEvent有isARepeat方法来确定事件是否是自动键重复的结果.您可以简单地忽略这些并假设该键被连续按下,直到您收到相应的keyUp:事件。 -
我将此作为注释添加到解决方案 #1。我希望的是一个游戏开发者的框架,它只允许你调用像 isKeyDown:(UInt16)virtualKeyCode 这样的方法。
-
关于#2,在文档中找到了这个:新事件点击的位置。传递 Event Tap Locations 中列出的常量之一。只有以 root 用户身份运行的进程才能在 HID 事件进入窗口服务器的位置找到事件点击;对于其他用户,此函数返回 NULL。 developer.apple.com/library/mac/documentation/Carbon/Reference/…
-
关于#2,是的,我确认某些事件类型需要root权限。例如,key_down 和 key_up。我猜原因是他们不想让程序监控用户的按键输入。
标签: macos cocoa keyboard macos-carbon