gamecontroller.js icon indicating copy to clipboard operation
gamecontroller.js copied to clipboard

[Feature Request] Pausing a gamepad

Open vdegenne opened this issue 2 years ago • 0 comments

Would be nice to have a way to pause a gamepad, e.g.

gamepad.on('button0', doSomething())

window.addEventListener('blur', () => {
  // the window lost focus
  gamepad.pause()
})

window.addEventListener('focus' () => {
  // the window focused back
  gamepad.resume()
})

I run into a problem where a webapp (that uses the controller) continues to react to gamepad controller when it is minimized (and when I use the controller in another app or game). It would be useful in that scenario.
But think about this another use-case also during a cutscene you want to "shut down" your gamepad.

This is a temporary "hack" I am using:

let _gamepad, buttonActions, axesActions;

// Creating maps with ghost functions
const silentButtonActions = {
  0: { action: () => {}, before: () => {}, after: () => {} },
  1: { action: () => {}, before: () => {}, after: () => {} },
  2: { action: () => {}, before: () => {}, after: () => {} },
  3: { action: () => {}, before: () => {}, after: () => {} },
  4: { action: () => {}, before: () => {}, after: () => {} },
  5: { action: () => {}, before: () => {}, after: () => {} },
  6: { action: () => {}, before: () => {}, after: () => {} },
  7: { action: () => {}, before: () => {}, after: () => {} },
  8: { action: () => {}, before: () => {}, after: () => {} },
  9: { action: () => {}, before: () => {}, after: () => {} },
  10: { action: () => {}, before: () => {}, after: () => {} },
  11: { action: () => {}, before: () => {}, after: () => {} },
  12: { action: () => {}, before: () => {}, after: () => {} },
  13: { action: () => {}, before: () => {}, after: () => {} },
  14: { action: () => {}, before: () => {}, after: () => {} },
  15: { action: () => {}, before: () => {}, after: () => {} },
  16: { action: () => {}, before: () => {}, after: () => {} },
}

const silentAxesActions = {
  0: {
    up: { action: () => {}, before: () => {}, after: () => {} },
    right: { action: () => {}, before: () => {}, after: () => {} },
    down: { action: () => {}, before: () => {}, after: () => {} },
    left: { action: () => {}, before: () => {}, after: () => {} },
  },
  1: {
    up: { action: () => {}, before: () => {}, after: () => {} },
    right: { action: () => {}, before: () => {}, after: () => {} },
    down: { action: () => {}, before: () => {}, after: () => {} },
    left: { action: () => {}, before: () => {}, after: () => {} },
  }
}

/* When the gamepad connects */
gameControl.on('connect', (gamepad) => {
  // get a global reference
  _gamepad = gamepad
  
  gamepad
    .on(...)
})



/* When the window loses focus, we should prevent game inputs */
window.addEventListener('blur', () => {
  pauseGamepad()
})
/* When the window gets the focus back */
window.addEventListener('focus', () => {
  resumeGamepad()
})


function pauseGamepad() {
  if (_gamepad) {
    // save for later
    buttonActions = _gamepad.buttonActions
    axesActions = _gamepad.axesActions

    // silence actions
    _gamepad.buttonActions = silentButtonActions
    _gamepad.axesActions = silentAxesActions
  }
}
function resumeGamepad() {
  if (_gamepad) {
    _gamepad.buttonActions = buttonActions
    _gamepad.axesActions = axesActions
  }
}

As you can see this is a bit nasty to implement and you have to think implementing that every time a new gamepad is detected.

Note: If you will accept the "Migrate to TypeScript" PR that was proposed to you, I may be able to check the code and propose another PR for that (worth my time).

vdegenne avatar Feb 13 '23 20:02 vdegenne