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;
console.error("this navigator has no gamepad support!")
}
else {
this.available = true;
}
this.connected = false;
}
setup() {
if (!this._setupDone) {
//all gamepads
this.gamepads = {};
//the most recently connected gamepad index
this.currentGamepadIndex = undefined;
super.setup();
}
}
on() {
window.addEventListener("gamepadconnected", (event) => this.gamepadConnectedHandler(event));
window.addEventListener("gamepaddisconnected", (event) => this.gamepadDisconnectedHandler(event));
}
off() {
window.removeEventListener("gamepadconnected", (event) => this.gamepadConnectedHandler(event));
window.removeEventListener("gamepaddisconnected", (event) => this.gamepadDisconnectedHandler(event));
}
/**
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]);
this.connected = true;
//send connected event
this.events.trigger("connected", incomingGamepad);
}
/**
Gamepad disconnection handler
@param {Event} event
*/
gamepadDisconnectedHandler(event) {
const incomingGamepad = event.gamepad;
delete this.gamepads[incomingGamepad.index];
this.connected = false;
//send disconnected event
this.events.trigger("disconnected", incomingGamepad);
}
/**
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];
}
}
}
}
getGamePadFromIndex(index){
this.updateGamePads();
return this.gamepads[index];
}
/**
Method to get a gamepad joysticks axes values
@param index the gamapad's index to get axes from.
@returns {Array} the axes array according to the capacities of the gamepad
*/
getAllAxes(index) {
if (this.available) {
this.updateGamePads();
if (!index) {
index = this.currentGamepadIndex;
}
const gamepad = this.gamepads[index];
const axes = gamepad.axes;
return axes;
}
return null;
}
/**
Method to get a specific axes's deltas
@param {Number} axeIndex
@param {Number} gamepadIndex
*/
getAxes(axesIndex, gamepadIndex) {
if (this.available) {
const axes = this.getAllAxes(gamepadIndex);
return axes[axesIndex];
}
return null;
}
/**
Method to get all the buttons of this gamepad
@param {Number} index
@returns {Object} all buttons object in their original format
*/
getAllButtons(index) {
if (this.available) {
this.updateGamePads();
if (!index) {
index = this.currentGamepadIndex;
}
const gamepad = this.gamepads[index];
let buttons = {}
if (gamepad) {
buttons = gamepad.buttons;
}
return buttons;
}
return null;
}
/**
Method to get a specific button's state
@param {Number} buttonIndex
@param {Number} gamepadIndex
*/
getButton(buttonIndex, gamepadIndex) {
if (this.available) {
const buttons = this.getAllButtons(gamepadIndex);
return buttons[buttonIndex];
}
return null;
}
}