UNPKG

pixelstream-cn

Version:

基于虚幻引擎的像素流平台

133 lines (123 loc) 6.03 kB
let haveEvents = 'GamepadEvent' in window; let haveWebkitEvents = 'WebKitGamepadEvent' in window; let rAF = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.requestAnimationFrame; class gamepad{ controllers = {}; sendFunction=null; init(send){ this.sendFunction=send; //Gamepad events if (haveEvents) { window.addEventListener("gamepadconnected", this.gamepadConnectHandler.bind(this)); window.addEventListener("gamepaddisconnected", this.gamepadDisconnectHandler.bind(this)); } else if (haveWebkitEvents) { window.addEventListener("webkitgamepadconnected", this.gamepadConnectHandler.bind(this)); window.addEventListener("webkitgamepaddisconnected", this.gamepadDisconnectHandler.bind(this)); } } gamepadConnectHandler(e){ console.log("Gamepad connect handler"); let gamepad = e.gamepad; this.controllers[gamepad.index] = {}; this.controllers[gamepad.index].currentState = gamepad; this.controllers[gamepad.index].prevState = gamepad; console.log("gamepad: " + gamepad.id + " connected"); rAF(this.updateStatus.bind(this)); } gamepadDisconnectHandler(e) { console.log("Gamepad disconnect handler"); console.log("gamepad: " + e.gamepad.id + " disconnected"); delete this.controllers[e.gamepad.index]; } scanGamepads() { let gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []); for (let i = 0; i < gamepads.length; i++) { if (gamepads[i] && (gamepads[i].index in this.controllers)) { this.controllers[gamepads[i].index].currentState = gamepads[i]; } } } updateStatus() { this.scanGamepads(); console.log("updateStatus",this.controllers); // Iterate over multiple controllers in the case the mutiple gamepads are connected for (let j in this.controllers) { let controller = this.controllers[j]; let currentState = controller.currentState; let prevState = controller.prevState; // Iterate over buttons for (let i = 0; i < currentState.buttons.length; i++) { let currButton = currentState.buttons[i]; let prevButton = prevState.buttons[i]; // Button 6 is actually the left trigger, send it to UE as an analog axis // Button 7 is actually the right trigger, send it to UE as an analog axis // The rest are normal buttons. Treat as such if (currButton.pressed && !prevButton.pressed) { // New press if (i == 6) { this.emitControllerAxisMove(j, 5, currButton.value); } else if (i == 7) { this.emitControllerAxisMove(j, 6, currButton.value); } else { this.emitControllerButtonPressed(j, i, 0); } } else if (!currButton.pressed && prevButton.pressed) { // release if (i == 6) { this.emitControllerAxisMove(j, 5, 0); } else if (i == 7) { this.emitControllerAxisMove(j, 6, 0); } else { this.emitControllerButtonReleased(j, i); } } else if (currButton.pressed && prevButton.pressed) { // repeat press / hold if (i == 6) { this.emitControllerAxisMove(j, 5, currButton.value); } else if (i == 7) { this.emitControllerAxisMove(j, 6, currButton.value); } else { this.emitControllerButtonPressed(j, i, 1); } } // Last case is button isn't currently pressed and wasn't pressed before. This doesn't need an else block } // Iterate over gamepad axes for (let i = 0; i < currentState.axes.length; i += 2) { let x = parseFloat(currentState.axes[i].toFixed(4)); // https://w3c.github.io/gamepad/#remapping Gamepad broweser side standard mapping has positive down, negative up. This is downright disgusting. So we fix it. let y = -parseFloat(currentState.axes[i + 1].toFixed(4)); if (i === 0) { // left stick // axis 1 = left horizontal this.emitControllerAxisMove(j, 1, x); // axis 2 = left vertical this.emitControllerAxisMove(j, 2, y); } else if (i === 2) { // right stick // axis 3 = right horizontal this.emitControllerAxisMove(j, 3, x); // axis 4 = right vertical this.emitControllerAxisMove(j, 4, y); } } this.controllers[j].prevState = currentState; } rAF(this.updateStatus.bind(this)); } emitControllerAxisMove(controllerIndex, axisIndex, analogValue) { console.log("emitAxisMove"); this.emitAxisMove(controllerIndex, axisIndex, analogValue); } emitControllerButtonPressed(controllerIndex, buttonIndex, isRepeat) { console.log("emitButtonPressed"); this.emitButtonPressed(controllerIndex, buttonIndex, isRepeat); } emitControllerButtonReleased(controllerIndex, buttonIndex) { console.log("emitButtonReleased"); this.emitButtonReleased(controllerIndex, buttonIndex); } } export default gamepad;