用C / C ++滚动自己的键盘/输入系统

题:

学习如何创建自己的输入/输出系统需要什么样的资源?

我自己的理解:

我知道这是依赖于操作系统的,所以让我们分开Linux和Windows并列出两个操作系统的资源(如果可能的话)。 对于Linux,我猜测需要对X Window系统有一定的了解。 对于Windows,我猜测win32 API。 尽管如此,我猜它还有更多的东西,而不仅仅是知道这些,好像我宁愿用C ++编写输入系统。

询问理由:

我尝试阅读OIS源代码(因为这将用CC++编写),并且不喜欢它的编写方式。 因此,我自己学会了如何编写自己的键盘输入/输出系统来进行简单的乒乓游戏(用C++编写)。

更新:这是我为处理键盘输入而编写的库。 它使用FreeBSD许可证。 我甚至将其标记为v1.0 ,因此我认为它是“发布质量”。

https://github.com/depp/keycode

我最近努力工作以使游戏“恰到好处”,而我还没有完成。 我会分享我所知道的。

密码

对于游戏, 关键代码通常是您想要的。

当您按下键盘上的某个键时,操作系统会首先将按钮按下转换为键码。 密钥代码指定键盘上键的物理位置。 例如,代码4可能对应于美国键盘上标记为A的键(即使该键在法国或俄罗斯具有不同的标签)。 每个平台都有一组不同的密钥代码,或者可能有多组密钥代码。 您可以通过其他名称了解它们,例如扫描码虚拟键码

  • Windows使用虚拟密钥代码 ( MSDN文档 )。 它们在各种硬件和软件配置中都很稳定。 您可以在头文件中找到定义。 在Windows上,如果按最左侧的主行键(美国的A ,法国的Q ),则会得到代码65。

  • Mac OS X具有自80年代以来一直稳定的密钥代码。 它们在中定义。 您实际上不需要链接到Carbon来使用密钥代码,但您需要标头。 在OS X上,如果按最左侧的主行键,则会得到代码4。

  • Linux有几组不同的密钥代码。 所以在Linux上,你有几个选择。 你可以使用关键的syms(它有我将在下面解释的缺点),你可以假设用户正在使用特定的输入驱动程序(这些天Evdev是一个非常好的猜测),或者你可以以某种方式找出哪个输入驱动程序机器使用。 要获取密钥代码,您必须阅读键盘定义文件。 例如,查看/usr/share/X11/xkb/keycodes/evdev keycodes /usr/share/X11/xkb/keycodes/evdev以获取Evdev密钥代码。 使用Evdev,如果按最左侧的主行键,则会得到代码38。

当然,如果关键代码在不同平台上是相同的,那就太容易了。 您可以使用特定于平台的密钥代码,也可以将其转换为与平台无关的值。 我建议使用USB HID代码( pdf )作为与平台无关的代码,因为许多聪明人已经遇到了同意每个密钥调用的麻烦。

我上面发布的库有每个平台的表,例如WIN_NATIVE_TO_HID用于将密钥代码转换为USB HID代码。

困难的部分是向用户传达他们应该按什么按钮,但至少来自其他国家的人可以玩你的游戏。

字符代码

您不想使用字符代码,即使您居住在美国并且您的受众也居住在美国,它们更容易使用。

在将按钮翻译成键代码之后,OS然后将密钥代码翻译成字符代码 。 字符代码受当前键盘布局的影响,并且通常也受修饰键的影响。

因此,如果按键盘上的A键,您将获得键码65,4或38,具体取决于您所使用的平台。 但是你会得到字符代码'a''A'取决于shift键是否关闭,或者如果键盘布局设置为法语,你可能会得到'Q'如果键盘布局设置为'Ф'俄罗斯人 因此,如果您将WASD编码到游戏中并使用字符代码,当来自其他国家/地区的某人玩您的游戏时,输入将完全被破坏。 你必须在法国使用ZQSD,在俄罗斯使用ÖФЫВ,很快你就会头疼。

我自己使用非QWERTY布局(Dvorak),大多数游戏都被完全打破了。 在W键的位置如果你有shift键,那就变成了< ,而某些游戏不能识别为同一个键。 例如,我按向前移动,但是如果我在换档键停止时释放按钮,那么游戏会认为我已经释放了<并且认为它仍然没有停止,所以我会保持向前进。 即使我切换到美国键盘布局(我认为这是SDL中的一个小故障),大多数使用SDL的游戏都会在Mac上破坏。

LibSDL

SDL 2.0提供与平台无关的密钥代码,称为扫描代码 。 使用"SDL_scancode.h"标头。 SDL开发人员得出的结论是扫描代码应该转换回USB HID代码,因此SDL扫描代码与我上面发布的库完全兼容(参见keycode.h和SDL_scancode.h ,数值相同) )。

由于这个原因和其他原因,如果您使用的是SDL 1.2,我强烈建议您升级到2.0。