如何使用 Gamepad API 检测按钮按下?
How to detect a button press with Gamepad API?
我正在尝试编写一个网页,我可以在其中检测 Xbox 控制器上的按钮按下情况,并根据按下的按钮向用户显示一个布尔值。现在,我可以检测到正在连接的控制器并将其显示为字符串。文档说使用此代码来检测此处的按钮按下:
var isPressed = navigator.getGamepads()[0].pressed;
但是Chrome在使用时显示这个错误:
Uncaught TypeError: Cannot read property 'pressed' of null
错误链接到上述代码行的 .pressed
部分。 All the documentation is on the Mozilla site,所以我假设他们在编写教程时使用的是 FireFox。
我最理想的结局是:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<h id="button"></h>
<h id="gpInfo"></h>
<script>
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
});
var isPressed = navigator.getGamepads()[0].pressed;
document.getElementById("button").innerHTML = isPressed;
</script>
<!-- <script type="text/javascript" src="gamepadtest.js"></script> -->
</head>
</html>
该代码会在屏幕上打印一个布尔值,供用户在按下按钮时看到。
这是我第一次使用 JavaScript 和 HTML。如果您能让您的回答对新手友好,那就太好了! Gamepad API and for GamepadButton
的文档
在引发 gamepadconnected
事件之前,您不应该引用 Gamepad 对象。此外,您还需要一个循环来轮询按钮值。这是一些修改后的代码:
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
setInterval(function(){
isPressed = gp.buttons[0].pressed;
document.getElementById("button").innerHTML = isPressed;
}, 100)
});
我没有足够的声誉来向 添加评论,但关于 Nathan 对该答案的评论:
I have used your example to listen for 20 buttons and i can detect each button, but once i have pressed one, it will not change another result for a different button.
我在 Chrome 90 上看到了相同的行为。具体来说,一个新的 GamepadList 实例,包含新的 Gamepad 实例,似乎每次任何游戏手柄的状态发生变化时都会创建(例如,它的哪些按钮是按下)。
你可以用这个来测试它:
var gamepads = null;
function callback() {
var new_gamepads = navigator.getGamepads();
if(new_gamepads !== gamepads) {
console.log('New GamepadList!', new_gamepads);
gamepads = new_gamepads;
}
}
var interval = setInterval(callback, 100);
...对我来说,每次我 press/release 一个按钮时都会记录 'New GamepadList!'。
长话短说,您需要轮询 navigator.getGamepads()
每一帧以检测游戏手柄状态的变化。
因此,对 Caleb Denio 的回答的极简主义解决方案是:
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
setInterval(function(){
// ===> Get a fresh GamepadList! <===
var gp = navigator.getGamepads()[e.gamepad.index];
isPressed = gp.buttons[0].pressed;
document.getElementById("button").innerHTML = isPressed;
}, 100)
});
我正在尝试编写一个网页,我可以在其中检测 Xbox 控制器上的按钮按下情况,并根据按下的按钮向用户显示一个布尔值。现在,我可以检测到正在连接的控制器并将其显示为字符串。文档说使用此代码来检测此处的按钮按下:
var isPressed = navigator.getGamepads()[0].pressed;
但是Chrome在使用时显示这个错误:
Uncaught TypeError: Cannot read property 'pressed' of null
错误链接到上述代码行的 .pressed
部分。 All the documentation is on the Mozilla site,所以我假设他们在编写教程时使用的是 FireFox。
我最理想的结局是:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<h id="button"></h>
<h id="gpInfo"></h>
<script>
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
});
var isPressed = navigator.getGamepads()[0].pressed;
document.getElementById("button").innerHTML = isPressed;
</script>
<!-- <script type="text/javascript" src="gamepadtest.js"></script> -->
</head>
</html>
该代码会在屏幕上打印一个布尔值,供用户在按下按钮时看到。 这是我第一次使用 JavaScript 和 HTML。如果您能让您的回答对新手友好,那就太好了! Gamepad API and for GamepadButton
的文档在引发 gamepadconnected
事件之前,您不应该引用 Gamepad 对象。此外,您还需要一个循环来轮询按钮值。这是一些修改后的代码:
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
setInterval(function(){
isPressed = gp.buttons[0].pressed;
document.getElementById("button").innerHTML = isPressed;
}, 100)
});
我没有足够的声誉来向
I have used your example to listen for 20 buttons and i can detect each button, but once i have pressed one, it will not change another result for a different button.
我在 Chrome 90 上看到了相同的行为。具体来说,一个新的 GamepadList 实例,包含新的 Gamepad 实例,似乎每次任何游戏手柄的状态发生变化时都会创建(例如,它的哪些按钮是按下)。
你可以用这个来测试它:
var gamepads = null;
function callback() {
var new_gamepads = navigator.getGamepads();
if(new_gamepads !== gamepads) {
console.log('New GamepadList!', new_gamepads);
gamepads = new_gamepads;
}
}
var interval = setInterval(callback, 100);
...对我来说,每次我 press/release 一个按钮时都会记录 'New GamepadList!'。
长话短说,您需要轮询 navigator.getGamepads()
每一帧以检测游戏手柄状态的变化。
因此,对 Caleb Denio 的回答的极简主义解决方案是:
var i = 1;
window.addEventListener("gamepadconnected", function(e) {
var gp = navigator.getGamepads()[e.gamepad.index];
document.getElementById("gpInfo").innerHTML = ("A " + gp.id + " was successfully detected! There are a total of " + gp.buttons.length + " buttons.")
//alert("A " + gp.id + " was successfully detected!")
setInterval(function(){
// ===> Get a fresh GamepadList! <===
var gp = navigator.getGamepads()[e.gamepad.index];
isPressed = gp.buttons[0].pressed;
document.getElementById("button").innerHTML = isPressed;
}, 100)
});