pixelstream-cn
Version:
基于虚幻引擎的像素流平台
133 lines (123 loc) • 6.03 kB
JavaScript
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;