首页 > 解决方案 > 如何在c中轮询键盘输入?

问题描述

我正在尝试为 unix 终端制作一个简单的游戏,用 c 编写。我一直在寻找一种方法来轮询键盘,但没有任何运气。

目前我正在使用 ncurses getch() 函数。它工作正常,但如果用户按住一个键,键盘重复将需要一段时间才能开始 - 如果按下任何其他键,它也会停止。这会在玩游戏时引起问题(特别是在两个游戏都由单个输入线程控制的两个玩家模式下)。

例如,如果玩家 1 按住“a”而玩家 2 按住“b”,我需要轮询键盘并处理如下输入流:

    abababababababab

再举一个例子,如果玩家 1 按住“a”键并按下“b”键,我需要像这样处理输入:

    aaaaaaabaaaaaaaa

这样,同时按下的按键就不会互相打断。所以我基本上需要按设定的时间间隔轮询键盘上的键,并创建我自己的按键中继器实现。

在 c 中(有或没有 ncurses)有没有办法在一个时间间隔内简单地轮询键盘并读取当前正在按下的所有键?从那里我可以设计键盘输入线程来手动管理重复操作。基本上类似于 kbhit,所以我可以检查给定密钥的状态。但这也会让我轮询箭头键。

标签: cncurses

解决方案


它不是这样工作的:

基本上类似于kbhit,所以我可以检查给定键的状态。但这也会让我轮询箭头键。

在任何不允许直接访问硬件的系统中(MS-DOS 是您可能遇到的唯一示例,其他示例包括嵌入式系统),您只能读取一系列字符(而不是) 在终端应用程序中。GUI 应用程序依赖于一个服务器,它直接访问一些硬件(更多),但转换数据。

在终端(例如由 ncurses 使用)中,您只能检查传入的字符是否包含与您感兴趣的键盘键对应的字符。箭头键发送一系列字符:使用 ncurses,您可以阅读序列中的单个字符,或者依靠 ncurses 将序列与终端描述中的已知键匹配。

即使使用特定于系统的东西(例如 Linux 控制台),您也不会发现对整个键盘的读取有太多支持:只有字符事件。阅读kbd_modeconsole_ioctl查看可用的内容,记住后者的古老警告:

警告:不要将此手册页视为 Linux 控制台 ioctls 的文档。这仅提供给好奇的人,作为阅读源代码的替代方法。Ioctl 是未记录的 Linux 内部结构,可能会在没有警告的情况下进行更改。(实际上,这个页面或多或少地描述了内核版本 1.1.94的情况;与早期版本有许多细微的和不那么细微的差异。)

建议的链接Receiving key press and key release events in Linux terminal applications?提供一些有用的信息。但如前所述,问题(除了提到的最后一点)是重复的。


推荐阅读