更新:这是我编写的用于处理键盘输入的库。它使用 FreeBSD 许可证。我什至把它标记为v1.0,所以我认为它是“发布质量”。
https://github.com/depp/keycode
我最近非常努力地让这款游戏“恰到好处”,但我还没有完成。我会分享我所知道的。
键码
对于游戏,键码通常是你想要的。
当您按下键盘上的某个键时,操作系统首先将按下的按钮转换为键码。键码指定键盘上键的物理位置。例如,代码 4 可能对应于美国键盘上标记为 A 的键(即使该键在法国或俄罗斯具有不同的标签)。每个平台都有一组不同的密钥代码,或者可能有多组。您可能通过不同的名称来认识它们,例如扫描码或虚拟键码。
Windows 使用虚拟键代码 (MSDN documentation)。它们在各种硬件和软件配置中都很稳定。您可以在 <Winuser.h> 头文件中找到定义。在 Windows 上,如果您按最左侧的主行键(美国为 A,法国为 Q),您将获得代码 65。
Mac OS X 的键码自 80 年代以来就一直稳定。它们在<Carbon/Events.h> 中定义。您实际上不需要链接到 Carbon 来使用密钥代码,但您需要标题。在 OS X 上,如果你按下最左边的 home 行键,你会得到代码 4。
Linux 有几组不同的关键代码。所以在 Linux 上,你有几个选择。您可以使用 key syms(我将在下面解释它的缺点),您可以假设用户正在使用特定的输入驱动程序(如今 Evdev 是一个非常的好猜测),或者你可以以某种方式找出机器使用的输入驱动程序。为了获得键码,您必须阅读键盘定义文件。例如,查看 /usr/share/X11/xkb/keycodes/evdev 获取 Evdev 密钥代码。使用 Evdev,如果您按最左边的 home 行键,您会得到代码 38。
当然,如果跨平台的关键代码相同,那就太容易了。您可以使用特定于平台的密钥代码或将其转换为与平台无关的值。我建议使用 USB HID 代码 (pdf) 作为独立于平台的代码,因为许多聪明人已经就每个键的调用方式达成了一致。
我在上面发布的库有每个平台的表格,例如WIN_NATIVE_TO_HID,用于将密钥代码转换为 USB HID 代码。
困难的部分是告诉用户他们应该按下哪个按钮,但至少其他国家的人可以玩你的游戏。
字符代码
您不想使用字符代码,即使如果您居住在美国并且您的受众也居住在美国,它们更容易使用。
在将按键转换为按键代码后,操作系统将按键代码转换为字符代码。字符代码受当前键盘布局的影响,通常也受修饰键的影响。
因此,如果您按键盘上的 A,您将获得 65、4 或 38 键码,具体取决于您使用的平台。但是你会得到字符代码'a'或'A',这取决于shift键是否按下,或者如果键盘布局设置为法语,你可能会得到'Q',或者如果键盘布局设置为'Ф'到俄语。因此,如果您将 WASD 编码到您的游戏中并使用字符代码,那么当来自另一个国家的人玩您的游戏时,输入将完全被破坏。你必须在法国使用 ZQSD,在俄罗斯使用 ЦФЫВ,很快你就会头疼。
我自己使用非 QWERTY 布局 (Dvorak),大多数游戏都被彻底破坏了。 W 键的位置是 ,,如果您按下 shift 键,则变为 ,并且某些游戏无法识别作为同一个键。例如,我会按 , 向前移动,但如果我在按下 shift 键时松开按钮,游戏会认为我已经松开了 并认为 , 仍然下降,所以我会继续前进。即使我切换到美式键盘布局,大多数使用 SDL 的游戏在 Mac 上都会损坏(我认为这是 SDL 中的一个小故障)。
LibSDL
SDL 2.0 提供独立于平台的键码,称为扫描码。使用 "SDL_scancode.h" 标头。 SDL 开发人员得出了相同的结论,即扫描码应转换回 USB HID 码,因此 SDL 扫描码与我上面发布的库完全兼容(参见keycode.h 和SDL_scancode.h,数值相同)。
出于这个和其他原因,如果您使用的是 SDL 1.2,我强烈建议您升级到 2.0。