游戏中的键盘输入(针对GLUT)

4
几乎每个游戏都使用键盘作为输入设备。我已经在这个主题上搜索了两天,发现了很多相关资料。键盘有许多缺点,但我发现的主要问题是不同的布局和同时按下3个键可能会导致损坏(行列错误)。如果你不知道我在说什么,键盘是由网格制成的,它检查哪一行和哪一列已连接。但是,如果您按下E、D(第1行、第2列)和R(第1行、第4列),键盘甚至可以显示F,因为它发现F被按下(第2行、第4列都按下)。
所以我认为我们无法解决第二个问题,但如果有人有更好的解决方案,比如使用不形成L形的键,那就太好了 :)
但我的主要问题是不同的键盘布局,这真的很痛苦。我是斯洛伐克人,所以斯洛伐克数字键盘的布局如下: +ľščťžýáíé,按Shift键后是1234567890,我们也有QWERTZ,但你可以使用QWERTY。 大家都知道英语的布局是怎样的,但为了确保: 1234567890,按Shift键后是!@#$%^&*()
大部分时候我使用英文键盘,因为在编程时我已经习惯了它。但是不同的人使用不同的布局。当你制作依赖于按键的游戏,例如经典的WASD模式,你不能在法语布局下使用AZERTY布局,这会很奇怪。在动作游戏中使用数字选择枪支也是一样的道理。正如您所看到的,斯洛伐克人必须按shift才能使其正常工作。
我还使用OpeGL。当映射按下的键时存在问题。例如,广泛使用的解决方案是为每个字符制作256个bools的地图,但会受到SHIFT的影响。你按下a、SHIFT并释放a,你得到:a down、A up。因此,我考虑绑定一些键在一起,例如A和a,1和!,但后来我意识到我只是改变了布局,而一切都错了。
那么解决办法是什么呢?我认为有人在游戏行业或制作游戏时不得不解决这个问题。我唯一想到的解决办法是强制在UI中使用英文布局(在聊天中选择布局)。

在接下来的搜索中,我找到了需要的内容,但我需要跨平台的: 虚拟键码

接下来的搜索揭示了SDL键

结果:如果你要制作游戏,千万不要使用GLUT,使用SFML或SDL

感谢大家的帮助,这个问题还涉及到按键绑定/映射、SDL等方面,每一个都给了我很大的帮助。

5个回答

2
如果每次用户按键时都会出现一个“字符”,那么您的键盘程序不适用于游戏输入,只适用于文本输入。
您需要使用完全忽略键盘布局切换并操作某种原始键码的输入程序(因此当用户按下Shift+A时,您将知道已按下Shift并且已按下“A”键,但不会得到“A”字符)。此外,这些程序应该允许您查询某个键是否被按下。
对于Windows来说,这是DirectInput或XInput。对于跨平台来说,这是libsdlSDL_GetKeyState。您还需要为用户提供键映射选项。Glut可能不适合您的任务。

是的,你在我正在了解SDLK(或SDL Key,VK的跨平台等效物)的时候发布了。看起来SDL是前进的道路,而GLUT适用于处理窗口内容(创建、调整大小)和下一个NURBS之类的东西,但不适合输入。我有MS Reclusa键盘,所以我怀疑我的键盘是错误的。错的是GLUT接收键盘输入的方式(例如,它立即将shift+a混合到A中,使我没有自由)。我认为这个问题已经解决了,即使我没有工作示例,我也查看了SDL,并且我认为会有方法使用它进行良好的跨平台输入。谢谢! - Raven

1

通常的方法似乎是忽略这个问题。在早期阶段,更糟即更好。

不幸的是,我正在使用 svorak 键盘布局,所以对我来说确实行不通。

我一直在通过绑定键盘上的多个键来解决同样的问题。因此,玩家可以从 xj 两个键中跳跃。这在不是射击跳跃类型的游戏中效果并不好。

如果您能找到与键盘接口相近的行/列或某些驱动程序接口,那就太好了。

一些自动键盘配置软件会很不错,但我还没有见过类似的东西。也许我们应该编写一个呢?


嗯...如果我们想要行列操作,那应该转到汇编级别。但是如果我找到了以后在C++项目中连接的方法,就不应该太难了。我曾经帮助我的朋友用Pascal制作游戏,那时候除了汇编没有其他选择,但是我忘记了那个。我会尝试一下,但我不确定它是否跨平台。好的,到目前为止是最好的答案 ;) - Raven
这不仅仅是PC键盘的问题。这是PC人机接口设备通用问题,而Linux内核HID的松散实现并不能使其变得更容易。这个平台对于输入来说比任何单一文化的游戏主机都要具有挑战性得多。 - Cheery
有没有办法获取原始键盘数据?这只是关于Windows将这些数据转换为布局定义的特定字符,但即使Windows输入Č,T键仍应该是T键。 - Raven
我不太了解Windows相关的东西。虽然我见过一些SDL应用程序完全忽略我的键盘布局。 - Cheery
你还能联系到他们吗?感谢指出SDL。我打算尝试一下。我已经尝试过GLFW,但似乎无法与GLUT配合使用。 - Raven

1
首先,将按键和文本输入分开。当你按下带有Shift的键时,你不应该关心哪个字母或数字会出现 - 操作系统应该处理这个并生成一个事件,你可以在需要文本时使用它。通常,你只需要查找按键和任何Shift按键,并对其进行操作。
其次,从数据文件中加载按键到命令的绑定,而不是硬编码。为QWERTY和默认布局分配默认绑定。如果数据格式非常简单,那么人们不会介意自定义它以适应他们的键盘和偏好。你还可以稍后添加一个游戏内按键编辑器。
这与OpenGL无关,因为默认情况下它不关心按键。也许你正在使用一个附加库或扩展来处理按键 - 确保你使用的任何东西都可以独立地给出单个键值和Shift / Alt / Ctrl的状态,并且它还通过独立系统提供文本输入。

实际上,标题应该是关于GLUT的。如果你了解GLUT,你就会知道从键盘函数中得到的是按键和鼠标在那个时间的X、Y值。但问题是,它返回的按键是与布局相关的,因此同一个按键在斯洛伐克语中会产生š,在英语中则是3。那么我该如何寻找按键按下,或者更好的说,寻找哪个按键按下了?一个解决方案是让用户将š作为绑定键,但我仍然会遇到“你按下a,按下SHIFT并释放a,你得到:a down,A up”的问题。所以a仍然被按下了。这些都是两个问题,但解决一个问题会导致另一个问题。需要类似常量按键ID的东西。 - Raven

0

允许用户为每个操作定义要使用的键...

或者使用箭头键...这应该是相当通用的 :)


我考虑过将键映射到操作,但拦截Shift键会很困难...例如,您想在Counter-Strike中使用Shift来减速,并按1更换武器。您需要做的是反转Shift的效果,以便获得正常的键。而这种反转在不同的布局中会很困难。(如果您想走路并想要更换武器,则会生成Shift + 1 =!而!不会映射到任何操作) - Raven

0
将键盘输入转换为元数据,这样您就可以允许用户根据自己的意愿进行配置,同时根据配置文件中使用的键盘布局提供不同的键盘快捷方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接