游戏手柄可以代替键盘吗?试图用棍子编程

图片


介绍



要在键盘上打字,请坐或站不动。相比之下,游戏手柄轻巧便携。通过控制它们,您可以在房间里走动或躺在沙发上。



由于游戏手柄上的按钮数量很少,因此没有人认为它们是例如在编程中输入大量文本的一种方法。



但是,模拟摇杆(大多数游戏手柄有两个)可能提供无穷的输入选项。问题在于选择正确的手势以获得最大的效率和最小的拇指张力。



有多种输入游戏手柄文本的方法。如果您曾经玩过主机游戏,那么您可能会使用其中之一。





在《塞尔达



传说》中的屏幕上输入文本在《塞尔达传说》中,玩家必须轮流使用带箭头的D-pad选择字母,并且每次按确认按钮将一个字母添加到文本输入字段。



从那时起,开发了更有效的输入法。如果您有兴趣,请阅读有关Gamasutra文章



不幸的是,我发现的所有输入法都有两个主要缺陷,使它们不适合进行认真的工作:



  • 他们不够快
  • 他们需要视觉反馈


对速度的需求是显而易见的。视觉反馈是不可接受的,因为它占用了宝贵的屏幕空间并分散了用户的注意力,这会干扰流量并减慢速度。



但是,在没有反馈的情况下,必须记住并练习所有手势,直到您可以足够准确地输入它们为止。电子游戏不太可能使用户花费数周的时间来学习如何输入文本,但是对于一种可以在任何程序中使用的文本输入方式来说,价格是可以接受的,而且培训本身就像掌握触摸输入一样。



在这篇文章中,我将简要介绍为游戏手柄创建文本输入系统所涉及的步骤,该系统可替代体积键盘输入。



决定手势



首先,我创建了一个工具,用于基于pygamePython语言可视化模拟游戏手柄的运动。为了清楚起见,我对该工具进行了补充,以使其不仅显示棒的当前位置,而且还显示逐渐变浅的灰色阴影的先前位置,以便您可以看到棒移动的路径。



下图显示了两个模拟摇杆向内,向上,向外,向下,再次向内并返回中心的同时运动。





可视化模拟摇杆的运动模式



我注意到的第一件事是,由于游戏手柄的中立状态是在中心位置找到摇杆,因此所有输入选项都必须能够从该中立状态到达,并且所有输入选项都必须以摇杆返回中心为结束。



考虑到这些限制,我发现最简单的输入方法是将一根摇杆沿任何方向移动并回到中心位置。





左摇杆已向上移动并回到中心



,您可以盲目选择几个方向以及确切的方向?考虑以下示例。





左摇杆向上,下,中心,左,右移动以及对角线对角移动



几分钟的实验表明,可以精确地选择沿轴的方向,而在其他方向上的输入则不那么准确(如上图所示)。



发现的下一个最简单的输入法是一级和二级圆周运动。





左摇杆向上,向左和回到中心





左摇杆向上,向左,向下和返回中心,



考虑到目前为止所有已发明的手势,每个摇杆上有4 + 8 + 8 = 20个输入选项。



当然,两个摇杆都可以同时移动,从而产生组合的输入手势。





两个操纵杆同时向上和向后移动到中心,组合



手势总共可以提供20 * 20 + 20 + 20 = 440个输入选项,我认为这绰绰有余。



编码手势



我将每个摇杆的输入空间划分为4个扇区,并为每个扇区分配一个数字。



输入空间分为扇区


输入空间分为多个扇区,



然后我在中心周围设置一个阈值区域,以帮助确定操纵杆是在中间位置还是在扇区之一中。





围绕中心的圆形门槛



如您所见,门槛的半径相当大。通过实验,我确定这是提供最小误差的最佳半径。



当任何一个摇杆偏离中心时,越过阈值区域,输入序列就会开始。当两个棍子返回到阈值区域内的中心时,该序列被认为是完整的,并转换为一对描述棍子运动的元组。



输入的摇杆运动((0,),(2,3))


移动输入的摇杆((0,),(2,3))



将手势链接到动作



在这种情况下,动作只是键盘键。游戏手柄触发按钮可以绑定到Shift,Ctrl,Alt和Super键,这很方便,因为这些键组合使用(例如Ctrl-C)。



为了确定输入的手势和按键的最佳绑定,我使用了一个按键记录器来记录所有按键,并分析了每个按键在几周内的频率。



最常按的键应绑定到最简单(因此也最快)的手势。我通过添加每个控制杆的输入长度来估算手势的复杂性。例如,上面显示的输入(((0,),(2,3)))的复杂度为1 + 2 = 3。



在这种情况下,从一根棍子输入时,两根棍子的交替使用比同一根棍子的多次输入要快,因此通常将要键入的键绑定到不同的棍子上会更好。



按照这种逻辑,我首先从一个操纵杆生成了所有可能的输入选项,并按难度将它们分组。我计算了每个难度组中的输入数量,并从最频繁的按键排序列表中获取了按键数量。



我的目标是将这些键分为两组,一组用于左操纵杆输入,另一组用于右操纵杆。为了找到理想的组,我创建了一个图,其中的节点是键,加权的边是键组合的频率。



我周期性地删除了权重最小的边缘,直到该图变成二分图。如果图形断开连接,我将分区算法递归地应用于连接的组件,最后将这些组组合成独立的集合。



考虑以下示例。第一组复杂度由复杂度为1的所有输入组成((0,), ()), ((1,), ()), ((2,), ()), ((3,), ()), ((), (0,)), ((), (1,)), ((), (2,)), ((), (3,))



该组中有8个输入,因此我们从排序列表中获取8个最频繁的键。这是'e', 'o', 't', 'a', 'i', 's', 'j', 'r'创建一个以这些键为节点的图形,并根据每个键组合的频率为这些节点之间的边缘分配权重。



e和r键通常是组合在一起的,因此必须将它们附加到不同的摇杆上,



当从图形中删除弱边时,它迟早会变成未链接的。

密钥j频繁但隔离。


j键是通用的,但是是孤立的。



您可能想知道为什么键j是8个最频繁的键之一,但是与其余频繁键之间的链接如此薄弱。原因是j在使用VIM plus时积极使用,在我的系统上,这是在窗口之间切换的热键组合的一部分。因此,它比文本中更经常单独使用。



由于图形已断开连接,因此我继续将算法应用于连接的组件。仅由一个节点组成的子图j已经是二部(j+空集)。我将算法递归地应用于另一个组件。

去除最弱的边缘后,组件是两部分的


除去最弱的边缘后,组件将变成两



部分,然后可以轻松地将组件分为两组,而组中节点之间没有边缘。

组件的二分图


二分组成方案



最后,我将二分组合。

前8个键的最终分组


前8个键获得的分组



如您所见,最强的链接(最常用的键盘快捷键)位于不同侧的节点之间,这正是我想要的。



我对其他难度组重复此过程(仅单杆输入),然后生成所有可能的组合输入,再按难度对它们进行分组,然后将其余键分配给这些输入选项。由于组合输入需要使用两个摇杆,因此这里不会出现将按键分为两组的问题。



我使用pyautoguiPython在触发操作时生成键盘事件。



实践



我使用了ktouch差不多二十年前已经教过的打字机。为此,我开设了专门的课程。



在ktouch中练习游戏手柄触摸打字


在KTouch中在游戏手柄上练习模拟输入



观察结果



  • 尽管运行此输入系统的Python进程通常消耗不超过10%的CPU资源,但是如果必须在后台持续运行,那么我将重新实现它并以较低级的语言对其进行优化,以便处理器可以执行更多操作昂贵的任务。
  • 购买DualShock4游戏手柄后,我意识到我可以非常准确地进行对角线输入。对角输入的集成将减少更复杂的输入选项的数量,从而提高速度。
  • , . , . , , , .
  • , . , , .
  • . .




在短短几天内,我为游戏手柄创建了一个高效的输入系统。可以进行许多增强,但是对概念的检查表明可以进行有效的游戏手柄键入。项目代码发布在github上



All Articles