19

I am trying to create an HTML5 JavaScript game that uses Nintendo Switch Joy-Cons and motion controls. The problem is, I don't know how to detect motion controls from Joy-Cons when they are connected to my PC.

I've managed to achieve button inputs with Xbox controllers, PS4, and Joy Con using Gamepad API, but is it possible to do so with Joy-Con motion controls?

Here is the code for Gamepad API if you want to see it(Again, I'm aiming for Joy-Con motion controls):

var haveEvents = 'ongamepadconnected' in window;
var controllers = {};

function connecthandler(e) {
  addgamepad(e.gamepad);
}

function addgamepad(gamepad) {
  controllers[gamepad.index] = gamepad;

  var d = document.createElement("div");
  d.setAttribute("id", "controller" + gamepad.index);

  var t = document.createElement("h1");
  t.appendChild(document.createTextNode("gamepad: " + gamepad.id));
  d.appendChild(t);

  var b = document.createElement("div");
  b.className = "buttons";
  for (var i = 0; i < gamepad.buttons.length; i++) {
    var e = document.createElement("span");
    e.className = "button";
    //e.id = "b" + i;
    e.innerHTML = i;
    b.appendChild(e);
  }

  d.appendChild(b);

  var a = document.createElement("div");
  a.className = "axes";

  for (var i = 0; i < gamepad.axes.length; i++) {
    var p = document.createElement("progress");
    p.className = "axis";
    //p.id = "a" + i;
    p.setAttribute("max", "2");
    p.setAttribute("value", "1");
    p.innerHTML = i;
    a.appendChild(p);
  }

  d.appendChild(a);

  var start = document.getElementById("start");
  if (start) {
    start.style.display = "none";
  }

  document.body.appendChild(d);
  requestAnimationFrame(updateStatus);
}

function disconnecthandler(e) {
  removegamepad(e.gamepad);
}

function removegamepad(gamepad) {
  var d = document.getElementById("controller" + gamepad.index);
  document.body.removeChild(d);
  delete controllers[gamepad.index];
}

function updateStatus() {
  if (!haveEvents) {
    scangamepads();
  }

  var i = 0;
  var j;

  for (j in controllers) {
    var controller = controllers[j];
    var d = document.getElementById("controller" + j);
    var buttons = d.getElementsByClassName("button");

    for (i = 0; i < controller.buttons.length; i++) {
      var b = buttons[i];
      var val = controller.buttons[i];
      var pressed = val == 1.0;
      if (typeof(val) == "object") {
        pressed = val.pressed;
        val = val.value;
      }

      var pct = Math.round(val * 100) + "%";
      b.style.backgroundSize = pct + " " + pct;

      if (pressed) {
        b.className = "button pressed";
        //Pressed down code here
      } else {
        b.className = "button";
        //Release button code here
      }
    }

    var axes = d.getElementsByClassName("axis");
    for (i = 0; i < controller.axes.length; i++) {
      var a = axes[i];
      a.innerHTML = i + ": " + controller.axes[i].toFixed(4);
      a.setAttribute("value", controller.axes[i] + 1);
    }
  }

  requestAnimationFrame(updateStatus);
}

function scangamepads() {
  var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
  for (var i = 0; i < gamepads.length; i++) {
    if (gamepads[i]) {
      if (gamepads[i].index in controllers) {
        controllers[gamepads[i].index] = gamepads[i];
      } else {
        addgamepad(gamepads[i]);
      }
    }
  }
}


window.addEventListener("gamepadconnected", connecthandler);
window.addEventListener("gamepaddisconnected", disconnecthandler);

if (!haveEvents) {
  setInterval(scangamepads, 500);
}

Using this link for reference

yivi
  • 42,438
  • 18
  • 116
  • 138
  • 12
    [This question is being discussed on meta](https://meta.stackoverflow.com/questions/381029/why-is-my-question-about-motion-controller-input-too-broad) – yivi Mar 08 '19 at 15:42
  • 15
    To the close voters: this question is quite clear and is definitely not too broad. The only way i can see it being unclear or overly broad is if the person evaluating the question has no experience in the target technology, in which case they should not be voting to close. –  Mar 08 '19 at 21:51
  • 2
    You'll probably need something like this: https://github.com/mfosse/JoyCon-Driver – Kaiido Mar 11 '19 at 08:29
  • 2
    @Kaiido Thanks for the suggestion, however I don't think that is JavaScript, so it doesn't really help. –  Mar 11 '19 at 15:28
  • 2
    You need a driver on your OS so that the device can talk with it correctly. From then only js will be able to listen to what the OS undrstood. – Kaiido Mar 11 '19 at 22:49
  • @Kaiido Ok, but can I not just link it with bluetooth? –  Mar 12 '19 at 00:19
  • 3
    If the OS itself doesn't map the informations sent by the device into something that softs can read, the browser (which is a soft) doesn't have access to these informations. There is a bluetooth API in Web standards, but you'd have to make the whole mapping yourself, and I don't think you'll be able to use the GamePad API simultaneously. – Kaiido Mar 12 '19 at 00:39
  • @Kaiido I see now. It doesn't answer my question, but it gives me a good place to start. Thank you. –  Mar 12 '19 at 12:11
  • Joy Cons can be used to play games(Axiom Verge, Meat Boy), and be detected by the gamepad API, but I still don't know how to code the motion controls in. –  Mar 15 '19 at 14:16

1 Answers1

2

Wei Gao explained this in a React Knowledgeable meetup last week.

You can learn how she did it through her presentation or her slides.

You can visit the talk page for more information.

Zain
  • 339
  • 2
  • 9