Last active
December 13, 2020 20:37
-
-
Save Kos/531a5646333bf5eac2eb3db051df35a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://w3c.github.io/gamepad/#dfn-standard-gamepad-layout | |
const Dpad = { | |
UP: 12, | |
LEFT: 14, | |
RIGHT: 15, | |
DOWN: 13, | |
}; | |
const Buttons = { | |
A: 0, | |
B: 1, | |
X: 2, | |
Y: 3, | |
R1: 5, | |
R2: 7, | |
L1: 6, | |
L2: 8, | |
}; | |
const gamepad = { | |
isUp: function () { | |
return buttonPressed(Dpad.UP) || axisIs("up"); | |
}, | |
isLeft: function () { | |
return buttonPressed(Dpad.LEFT) || axisIs("left"); | |
}, | |
isRight: function () { | |
return buttonPressed(Dpad.RIGHT) || axisIs("right"); | |
}, | |
isDown: function () { | |
return buttonPressed(Dpad.DOWN) || axisIs("down"); | |
}, | |
isSpace: function () { | |
// A or right shoulder or right trigger | |
return ( | |
buttonPressed(Buttons.A) || | |
buttonPressed(Buttons.R1) || | |
buttonPressed(Buttons.R2) | |
); | |
}, | |
}; | |
function buttonPressed(index) { | |
if (typeof navigator.getGamepads !== 'function') { | |
return false; | |
} | |
return [...navigator.getGamepads()] | |
.filter( | |
(gamepad) => | |
gamepad && gamepad.buttons[index] && gamepad.buttons[index].pressed | |
) | |
.length > 0; | |
} | |
function axisIs(direction) { | |
if (typeof navigator.getGamepads !== 'function') { | |
return false; | |
} | |
return [...navigator.getGamepads()] | |
.filter( | |
(gamepad) => | |
gamepad && | |
gamepad.axes.length >= 2 && | |
checkAxis(direction, gamepad.axes[0], gamepad.axes[1]) | |
) | |
.length > 0; | |
} | |
function checkAxis(direction, bx, by) { | |
// Given expected direction (as string) and a vector, return true if cardinal direction matches the vector. | |
const DEADZONE = 0.8; | |
const DEADZONE_SQUARED = DEADZONE * DEADZONE; | |
if (bx * bx + by * by < DEADZONE_SQUARED) { | |
return false; | |
} | |
const v = Math.atan2(bx, by); | |
if (direction == "down") { | |
return v > -Math.PI / 4 && v < Math.PI / 4; | |
} else if (direction == "left") { | |
return v > (-3 * Math.PI) / 4 && v < -Math.PI / 4; | |
} else if (direction == "right") { | |
return v > Math.PI / 4 && v < (3 * Math.PI) / 4; | |
} else if (direction == "up") { | |
return v > (3 * Math.PI) / 4 || v < (-3 * Math.PI) / 4; | |
} | |
} | |
// Demo | |
function display() { | |
requestAnimationFrame(display); | |
gamepad.isUp(); | |
document.body.innerText = [ | |
"Status:", | |
gamepad.isSpace() ? "SPACE" : "", | |
gamepad.isUp() ? "Up" : "", | |
gamepad.isDown() ? "Down" : "", | |
gamepad.isLeft() ? "Left" : "", | |
gamepad.isRight() ? "Right" : "", | |
].join(" "); | |
} | |
requestAnimationFrame(display); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment