How to detect joy-con input/motion controls in HTML5 JavaScript
Asked Answered
F

1

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

Floatstone answered 21/2, 2019 at 18:48 Comment(9)
This question is being discussed on metaCortisone
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.Foreknow
You'll probably need something like this: github.com/mfosse/JoyCon-DriverKesselring
@Kesselring Thanks for the suggestion, however I don't think that is JavaScript, so it doesn't really help.Floatstone
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.Kesselring
@Kesselring Ok, but can I not just link it with bluetooth?Floatstone
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.Kesselring
@Kesselring I see now. It doesn't answer my question, but it gives me a good place to start. Thank you.Floatstone
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.Floatstone
A
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.

Anchovy answered 12/12, 2019 at 10:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.