js/Mobilizing/input/Gamepad.js
import Component from '../core/Component';
export default class Gamepad extends Component {
/**
Gamepad class is a simple layer on top of the official Gamepad API : https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API
@param {Object} params
*/
constructor() {
super(...arguments);
/**
True is the Gamepad API is supported
@type {Boolean}
*/
this.available = false;
if (navigator.getGamepads || navigator.webkitGetGamepads) {
//this.getGamepads = navigator.getGamepads;
this.available = true;
}
else {
console.error("this navigator has no gamepad support!")
}
}
setup() {
if (!this._setupDone) {
//all gamepads
this.gamepads = {};
//the most recently connected gamepad index
this.currentGamepadIndex = undefined;
super.setup();
}
}
on() {
window.addEventListener("gamepadconnected", this.gamepadConnectedHandler.bind(this));
window.addEventListener("gamepaddisconnected", this.gamepadDisconnectedHandler.bind(this));
}
off() {
window.removeEventListener("gamepadconnected", this.gamepadConnectedHandler.bind(this));
window.removeEventListener("gamepaddisconnected", this.gamepadDisconnectedHandler.bind(this));
}
/**
Gamepad connection handler
@param {Event} event
*/
gamepadConnectedHandler(event) {
const incomingGamepad = event.gamepad;
this.gamepads[incomingGamepad.index] = incomingGamepad;
this.currentGamepadIndex = incomingGamepad.index;
console.log(this.currentGamepadIndex, this.gamepads[incomingGamepad.index]);
}
/**
Gamepad disconnection handler
@param {Event} event
*/
gamepadDisconnectedHandler(event) {
const incomingGamepad = event.gamepad;
delete this.gamepads[incomingGamepad.index];
}
/**
Updates the gamepads state, according to the API
@private
*/
updateGamePads() {
if (this.available) {
//list from navigator service
const gamepads = navigator.getGamepads();
for (let i = 0; i < gamepads.length; i++) {
if (gamepads[i]) {
const index = gamepads[i].index;
this.gamepads[index] = gamepads[i];
}
}
}
}
/**
Method to get a gamepad joysticks axes values
@param index the gamapad's index to get axes from.
@returns {Object} the axes as {0 : {x,y}, 1 : {x,y}, ...} according to the capacities of the gamepad
*/
getAllAxes(index) {
this.updateGamePads();
if (!index) {
index = this.currentGamepadIndex;
}
const gamepad = this.gamepads[index];
const axes = {}
if (gamepad) {
//generates an object to organize all axis coordinates
for (let axeIndex = 0, coordIndex = 0; axeIndex < gamepad.axes.length; axeIndex += 2, coordIndex++) {
axes[coordIndex] = {};
axes[coordIndex].x = gamepad.axes[axeIndex];
axes[coordIndex].y = gamepad.axes[axeIndex + 1];
}
}
return axes;
}
/**
Method to get a specific axes's deltas
@param {Number} axeIndex
@param {Number} gamepadIndex
*/
getAxes(axesIndex, gamepadIndex) {
const axes = this.getAllAxes(gamepadIndex);
return axes[axesIndex];
}
/**
Method to get all the buttons of this gamepad
@param {Number} index
@returns {Object} all buttons object in their original format
*/
getAllButtons(index) {
this.updateGamePads();
if (!index) {
index = this.currentGamepadIndex;
}
const gamepad = this.gamepads[index];
let buttons = {}
if (gamepad) {
buttons = gamepad.buttons;
}
return buttons;
}
/**
Method to get a specific button's state
@param {Number} buttonIndex
@param {Number} gamepadIndex
*/
getButton(buttonIndex, gamepadIndex) {
const buttons = this.getAllButtons(gamepadIndex);
return buttons[buttonIndex];
}
}