Skip to content

Instantly share code, notes, and snippets.

@jimf99
Created August 4, 2023 19:23
Show Gist options
  • Save jimf99/e99772df40f2549534c5829bd2b3fac8 to your computer and use it in GitHub Desktop.
Save jimf99/e99772df40f2549534c5829bd2b3fac8 to your computer and use it in GitHub Desktop.
Gamepad Simulator Demo

Gamepad Simulator Demo

This snippet showcases the gamepad simulator code.

The demo reads the standard values of the gamepad (using navigator.getGamepads() and reading the Gamepad interface) without needing a physical game controller connected to the computer/browser.

It uses instead a virtual gamepad generated with gamepad-simulator (more info on GitHub), which triggers the gamepad events and simulates the getGamepads navigator function.

A Pen by Alvaro Montoro on CodePen.

License.

<p>
Use the button below to connect/disconnect the virtual gamepad, then click on the buttons and axes to simulate working with the gamepad. Info messages will be displayed on screen and in the console.
</p>
<p>
<button onclick="handleButtonClick(this)">Connect</button>
<button onclick="document.querySelector('#events').innerHTML = '';">Clear log</button>
</p>
<p id="events">
</p>
function handleButtonClick(button) {
if (button.textContent === "Disconnect") {
gamepadSimulator.disconnect();
button.textContent = "Connect";
} else {
gamepadSimulator.connect();
button.textContent = "Disconnect";
}
}
/*****/
const gamepads = {};
function readValues() {
const cgs = navigator.getGamepads();
const indexes = Object.keys(gamepads);
for (let x = 0; x < indexes.length; x++) {
const buttons = cgs[indexes[x]].buttons;
const axes = cgs[indexes[x]].axes;
for (let y = 0; y < buttons.length; y++) {
if (buttons[y].pressed) {
console.log(`button ${y} pressed.`);
document.querySelector("#events")
.insertAdjacentHTML('afterbegin', `<div>Button ${y} pressed.</div>`);
}
}
for (let y = 0; y < axes.length; y++) {
if (axes[y] != 0) {
const axe = Math.floor(y / 2);
const dir = y % 2;
let move = "up"
if (dir === 0 && axes[y] == 1) {
move = "right";
} else if (dir === 0 && axes[y] == -1) {
move = "left";
} else if (dir === 1 && axes[y] == 1) {
move = "down";
}
console.log(`axe ${axe} moved ${move}.`);
document.querySelector("#events")
.insertAdjacentHTML('afterbegin', `<div>Axe ${axe} moved ${move}.</div>`);
}
}
}
if (indexes.length > 0) {
window.requestAnimationFrame(readValues);
}
}
window.addEventListener("gamepadconnected", function(e) {
console.log(`Gamepad connected: ${e.gamepad.id}`);
document.querySelector("#events")
.insertAdjacentHTML('afterbegin', '<div><b>Gamepad connected.</b></div>');
gamepads[e.gamepad.index] = true;
readValues();
});
window.addEventListener("gamepaddisconnected", function(e) {
console.log(`Gamepad disconnected: ${e.gamepad.id}`);
document.querySelector("#events")
.insertAdjacentHTML('afterbegin', '<div><b>Gamepad disconnected.</b></div>');
delete gamepads[e.gamepad.index];
});
gamepadSimulator.create();
<script src="https://codepen.io/alvaromontoro/pen/gOPEWyq.js"></script>
p, button {
max-width: 50ch;
font-family: Roboto, Arial, sans-serif;
font-size: 1.125rem;
line-height: 1.5em;
}
button {
color: white;
background: #369;
border: 0;
padding: 0.5rem 1rem;
}
button:hover {
background: #136;
}
#amdfc-controller {
position: fixed !important;
bottom: 1vmin;
right: 1vmin;
max-width: 350px;
width: 40vw;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment