9

我正在使用 Chrome(版本 19.0.1084.46)。我在 chrome://flags 中启用了 Gamepad API。我插入了一些游戏手柄,但navigator.webkitGamepads始终是一个长度为 4 的数组,只包含未定义的数组。

navigator.webkitGamepads
GamepadList
  0: undefined
  1: undefined
  2: undefined
  3: undefined
  length: 4
  __proto__: GamepadList

我需要做什么才能使用游戏手柄进行测试?如果这很重要,我在 Ubuntu Linux 上。

4

3 回答 3

9

我也遇到了这个问题(在带有 Chrome 21.0.1163.0 dev 的 Ubuntu 10.04 上)。我从chromium-discussions 的一个线程中遇到了这个问题:

请注意,您需要先按下游戏手柄上的面部按钮,然后才能使用数据。这是由于指纹问题。

我写了一个快速测试页面,如果在刷新页面时按住控制器按钮,它似乎可以工作。我正在使用带有 xboxdrv 驱动程序的 Gamestop 品牌 Xbox 360 有线控制器。

另外,需要注意的另一件重要事情 - Chrome 将这些 Gamepad 对象视为控制器状态的快照。因此,如果您传递实际的 Gamepad 对象,您将永远不会获得更新的信息。Chrome 似乎只在您调用navigator.webkitGamepads[x]getter 时轮询控制器(请参阅我的测试页面中的第 23 行)。

于 2012-06-07T21:36:00.420 回答
3

特别注意: Firefox 和 Google Chrome 以两种完全不同的方式处理 GamePad API 。因此,您需要包含代码来测试浏览器的身份,并相应地处理这些案例。

当调用 navigator.getGamePads() 方法时,会返回一个对象数组,这些对象包含有关游戏手柄/操纵杆的身份以及轴/按钮状态的信息。

这就是问题所在:在 Firefox 上,该方法将数组传递给您的调用代码,然后您可以反复检查该数组,以在您自己的代码中查找轴/按钮状态的变化。Firefox 以预期的方式运行,并在可用时使用新的轴/按钮数据更新您收到的对象。

另一方面,谷歌浏览器对数组的处理方式完全不同。Chrome 将数组视为您的游戏手柄/操纵杆状态的一次性快照,如果您想获取新数据,您必须再次调用 navigator.getGamePads(),以获取新快照,丢弃旧的一。

因此,您需要这样的东西来使您的代码在两个浏览器上都工作(假设变量 'gp' 是您先前存储第一次调用 navigator.getGamePads() 的返回值的变量......)

var ua = navigator.userAgent;
if (ua.toLowerCase().indexOf("chrome") != -1)
    gp = navigator.getGamePads();

为什么这两个浏览器的行为如此不同,这是另一个线程的主题,但我怀疑这与 GamePad API 仍处于试验阶段的事实有很大关系,适用于其的标准的细节尚未最终确定。

就我而言,在 Windows 7 64 位(但 32 位版本,由于某种奇怪的原因,我的计算机制造商以这种方式安装它最为人所知)上运行 Chrome 时,navigator.getGamePads() 返回的数组当前包含只有与插入我的计算机的实际游戏手柄/操纵杆一样多的条目。如果您在 Linux 下的 Chrome 上遇到不同的情况,那么您还需要考虑这一点,通过测试查看数组中是否有任何空值。

另一个需要考虑的因素是,在选择游戏手柄/操纵杆时,现有标准要求引用 GamePad 对象的index属性,然后用于索引到数组中。本文档更详细地介绍了其原因:

W3C 页面:GamePad 界面上的编辑草稿

然而,虽然这个实现在我的谷歌浏览器的化身中记录在上面,你可能必须通过实验检查你的版本,看看它的行为是否与我的相同。如果没有,请相应地调整您的代码,直到标准最终确定,并且在所有现代浏览器及其所有操作系统化身中强制执行适当的符合标准。

因此,当您选择要使用的特定游戏手柄/操纵杆时,代码将如下所示(使用变量 'gid' 作为索引选择器):

var gLen = this.gamePads.length;
done = false;
idx = 0;

while (!done)
{
    if (this.gamePads[idx] !== null)
    {
        if (gid == this.gamePads[idx].index)
        {
        //Here, choose this GamePad as the selected GamePad, based upon the index number as per the W3C recommendation ...

            selectedGamePadIndex = gid;
            selectedGamePad = this.gamePads[idx];
            done = true;

        //End if
        }

    //End if
    }

    //Update counter in case we haven't selected one of the available GamePads above ...

    idx++;

    if (idx >= gLen)
        done = true;    //Exit loop altogether if we've exhausted the list of available GamePads

//End while
}

我实际上将上面的代码(以及最后的一些整理)实现为自定义对象的方法,但无论实现细节如何,原理都是一样的。(此时我要承认,我有编写自己的短库来处理此类任务的习惯!)

另一个需要注意的问题是游戏手柄 API 将游戏手柄/操纵杆的物理数据源映射到 GamePad 对象的轴/按钮元素以及其中包含的值的方式。我有一个 Microsoft Sidewinder Pro USB 游戏杆,我电脑上这个设备的映射非常奇怪,即:

  • 轴 0/1:操纵杆手柄(如预期的那样)
  • 轴 2/3:未分配
  • 轴 4/5:4 个未分配,5 个分配给扭转握把
  • 轴 6/7:6 个分配给圆形滑块,7 个未分配
  • 轴 8/9:8 未分配,9 分配给帽子开关(呃,什么???)

是的,没错,模拟轴 9 分配给了帽子开关,并返回了严重的奇数值,即:

  • 帽子开关居中:+1.2
  • 帽子切换:-1.0
  • 帽子切换:+0.1
  • 帽子开关左:+0.7
  • 帽子开关右:-0.42

当您尝试使用 GamePad API 时,您应该警惕此类怪癖。更糟糕的是,所谓的“标准”游戏手柄(在我上面链接到的那个文档中定义)可能在某些浏览器上报告为标准,但在其他浏览器上不报告,或者更糟糕的是,在 Windows 中的浏览器 X 上报告为标准,但不是Linux 中的同一个浏览器 X!当你试图通过这个相当于荆棘丛的软件时,这会引起很多令人毛骨悚然的挫败感,一路上被一些荆棘严重刮伤,但你至少可以对浏览器开发人员正在工作的事实感到安慰尝试改善这一点,但这需要时间,因为其他事情优先考虑(例如确保您的浏览器不会成为勒索软件劫持的容易目标,如果发生这种情况,将非常严重)。

于 2017-07-27T04:29:58.107 回答
0

这对我不起作用,但也许对你有帮助?从这里拉出来的。

function updateStatus() {
    window.webkitRequestAnimationFrame(updateStatus);

    var gamepads = navigator.webkitGamepads;

    var data = '';
    for (var padindex = 0; padindex < gamepads.length; ++padindex)
    {
        var pad = gamepads[padindex];
        if (!pad) continue;
        data += '<pre>' + pad.index + ": " + pad.id + "<br/>";
        for (var i = 0; i < pad.buttons.length; ++i)
            data += "button" + i + ": " + pad.buttons[i] + "<br/>";
        for (var i = 0; i < pad.axes.length; ++i)
            data += "axis" + i + ": " + pad.axes[i] + "<br/>";
    }
    document.body.innerHTML = data;
}

window.webkitRequestAnimationFrame(updateStatus);

或者作为一个艰难的替代方案,有Javascript 操纵杆插件这里是演示),但我认为这在 Linux 中不起作用。

于 2012-06-01T03:31:24.153 回答