我正在使用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上。
答案 0 :(得分:8)
我也遇到了这个问题(在Ubuntu 10.04上使用Chrome 21.0.1163.0 dev)。我在a thread on chromium-discussions:
中遇到了这个问题请注意,您需要在数据前按下游戏手柄上的面部按钮 将有空。这是由于指纹问题引起的。
如果在刷新页面时按住控制器按钮,我写了一个quick test page似乎有效。我正在使用带有xboxdrv驱动程序的Gamestop品牌的Xbox 360有线控制器。
另外,还有一点需要注意 - Chrome会将这些Gamepad对象视为控制器状态的快照。因此,如果您传递实际的Gamepad对象,您将永远不会获得更新信息。 Chrome似乎只在您调用navigator.webkitGamepads[x]
getter时轮询控制器(请参阅我的测试页中的第23行)。
答案 1 :(得分:1)
特别说明:Firefox和谷歌浏览器以两种完全不同的方式处理GamePad API。因此,您需要包含代码来测试您的浏览器身份,并相应地处理这些案例。
当调用navigator.getGamePads()方法时,会返回一个对象数组,这些对象包含有关游戏手柄/游戏杆身份以及其轴/按钮状态的信息。
问题在于:在Firefox上,该方法将数组交给您的调用代码,然后您可以重复检查该数组,以在您自己的代码中查找轴/按钮状态的更改。 Firefox以预期的方式运行,并在新的轴/按钮数据可用时更新您收到的对象。
另一方面,谷歌浏览器以完全不同的方式处理数组 。 Chrome会将阵列视为游戏手柄/游戏杆状态的一次性快照,如果您想要获取新数据,则必须执行另一个导航器调用.getGamePads(),用于获取新快照,丢弃旧快照。因此,您需要这样的代码才能使您的代码在两个浏览器上都能正常工作(假设变量' gp'是您先前在第一次调用导航器时存储返回值的变量.getGamePads()...)
var ua = navigator.userAgent;
if (ua.toLowerCase().indexOf("chrome") != -1)
gp = navigator.getGamePads();
为什么这两个浏览器的行为如此不同,是另一个主题的主题,但我怀疑它与GamePad API仍然有点实验的事实有很大关系,并且适用于它的标准的细节还没有已经敲定。
在我的情况下,在Windows 7 64位上运行Chrome(但32位版本,出于我的计算机制造商最熟悉的一些奇怪的原因,以这种方式安装它),返回的数组navigator.getGamePads()目前只包含与插入我的计算机的实际游戏手柄/操纵杆一样多的条目。如果您在Linux下在Chrome上遇到不同的内容,那么您还需要考虑这一点,通过测试来查看数组中是否有任何空值。
要考虑的另一个因素是,在选择游戏手柄/操纵杆时,标准就是要引用GamePad对象的 index 属性,然后用它来索引到阵列。本文档中详细介绍了其原因:
W3C page : Editor's Draft on the GamePad interface
然而,虽然我在Google Chrome的版本中实现了此功能,但您可能必须通过实验检查您的版本,看它是否与我的版本相同。如果没有,则相应地调整您的代码,直到标准最终确定为止,并在所有现代浏览器及其所有操作系统版本中强制执行适当的符合。
因此,当您选择要使用的特定游戏手柄/操纵杆时,代码将看起来像这样(使用变量' 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操纵杆,我的电脑上这个设备的映射非常奇怪,即:
是的,没错,模拟轴9被分配给帽子开关,并且返回了非常奇怪的值,即:
在您尝试使用GamePad API时,您应该警惕这样的怪癖。更糟糕的是,一个所谓的"标准" GamePad(在我上面链接的文档中定义)可以在某些浏览器上作为标准报告,但在其他浏览器上不作为标准报告,或者更糟糕的是,在Windows中的浏览器X上作为标准报告,但在Linux中不在同一浏览器X上报告!虽然当你试图通过这个类似于bramble丛林的软件来对抗你的方式时会引起很大的挫败感,但是在整个过程中被一些荆棘严重划伤,你至少可以对浏览器开发人员 努力尝试改善这一点,但它需要时间,因为其他事情优先(例如确保您的浏览器不会成为勒索软件劫持的轻松目标,这将是毁掉你的一天非常如果它发生了。)
答案 2 :(得分:0)
这对我不起作用但也许对你有帮助吗?拉from here。
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 Joystick Plug-in(demo here),但我认为这不适用于Linux。