Created
February 7, 2018 12:34
-
-
Save jahredhope/26b41deab3485cbe743d36ede97c3644 to your computer and use it in GitHub Desktop.
Gamepad API muckaround
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style> | |
body { | |
padding: 0; | |
margin: 0; | |
background-color: hsl(0, 0%, 5%); | |
color: hsl(0, 0%, 95%); | |
} | |
</style> | |
<h1>Game on</h1> | |
<div id="players"></div> | |
<canvas id="canvas" width="800" height="500" style="width: 100%"/> | |
<script src="/index.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('load game'); | |
let framesSlipped = 0; | |
let framesJumped = 0; | |
let framesPrinted = 0; | |
let fractionTotal = 0; | |
const secondsToReport = 10; | |
function showFPS() { | |
console.log('fps', framesPrinted / secondsToReport); | |
if (fractionTotal / framesPrinted > 1.05) { | |
console.log('fraction average', fractionTotal / framesPrinted); | |
} | |
if (framesSlipped !== 0) { | |
console.warn('framesSlipped', framesSlipped); | |
framesSlipped = 0; | |
} | |
if (framesJumped !== 0) { | |
console.warn('framesJumped', framesJumped); | |
framesJumped = 0; | |
} | |
framesPrinted = 0; | |
fractionTotal = 0; | |
} | |
setInterval(showFPS, 1000 * secondsToReport); | |
const colors = ['magenta', 'cyan', 'yellow', 'red']; | |
const speedConstant = 3; | |
const turnConstant = 0.03; | |
let lastTimeRendered = performance.now(); | |
const playersContainer = document.getElementById('players'); | |
const canvas = document.getElementById('canvas'); | |
var ctx = canvas.getContext('2d', { alpha: false }); | |
let controllers = {}; | |
function gameLoop(highResTime) { | |
ctx.fillStyle = 'hsl(0, 0%, 15%)'; | |
ctx.fillRect(0, 0, canvas.width, canvas.height); | |
const fractionOfFrame = (highResTime - lastTimeRendered) / 16; | |
fractionTotal += fractionOfFrame; | |
if (fractionOfFrame < 0.97) { | |
framesJumped++; | |
} | |
if (fractionOfFrame > 1.06) { | |
framesSlipped++; | |
} | |
Object.values(controllers).forEach(controller => | |
move(controller, fractionOfFrame) | |
); | |
lastTimeRendered = highResTime; | |
framesPrinted++; | |
window.requestAnimationFrame(gameLoop); | |
} | |
function buttonPressed(b) { | |
if (typeof b == 'object') { | |
return b.pressed; | |
} | |
return b == 1.0; | |
} | |
function logButtonsPressed() { | |
var gamepads = navigator.getGamepads | |
? navigator.getGamepads() | |
: navigator.webkitGetGamepads ? navigator.webkitGetGamepads : []; | |
Object.values(gamepads) | |
.filter(Boolean) | |
.forEach(controller => { | |
controller.buttons.forEach((button, index) => { | |
if (buttonPressed(button)) { | |
console.log('button pressed', index, button); | |
} | |
}); | |
}); | |
} | |
function move(controller, fractionOfFrame) { | |
var gamepads = navigator.getGamepads | |
? navigator.getGamepads() | |
: navigator.webkitGetGamepads ? navigator.webkitGetGamepads : []; | |
const turning = gamepads[controller.index].axes[0]; | |
let drive = gamepads[controller.index].buttons[7].pressed | |
? gamepads[controller.index].buttons[7].value | |
: -gamepads[controller.index].buttons[6].value; | |
const desiredSpeed = speedConstant * drive; | |
const speedChange = desiredSpeed - controller.speed; | |
const amountCanSteer = Math.pow(Math.abs(controller.speed), 1 / 4); | |
controller.direction += | |
Math.sign(controller.speed) * | |
amountCanSteer * | |
turning * | |
turnConstant * | |
fractionOfFrame; | |
controller.speed += speedChange / (5 * fractionOfFrame); | |
const toMove = [ | |
fractionOfFrame * | |
(controller.speed * Math.cos(controller.direction * Math.PI / 2)), | |
fractionOfFrame * | |
(controller.speed * Math.sin(controller.direction * Math.PI / 2)) | |
]; | |
const newLocation = [ | |
Math.max(Math.min(controller.location[0] + toMove[0], canvas.width), 0), | |
Math.max(Math.min(controller.location[1] + toMove[1], canvas.height), 0) | |
]; | |
ctx.beginPath(); | |
controller.location = newLocation; | |
drawPeace(controller.color, controller.location, controller.direction); | |
} | |
const tailDistance = 10; | |
const headDistance = 3; | |
function drawPeace(color, location, direction) { | |
ctx.beginPath(); | |
const head = [ | |
headDistance * Math.cos(direction * Math.PI / 2), | |
headDistance * Math.sin(direction * Math.PI / 2) | |
]; | |
const arrowSpread = 0.07; | |
const leftSideDirection = direction - arrowSpread * Math.PI; | |
const rightSideDirection = direction + arrowSpread * Math.PI; | |
const leftTail = [ | |
tailDistance * Math.cos(leftSideDirection * Math.PI / 2), | |
tailDistance * Math.sin(leftSideDirection * Math.PI / 2) | |
]; | |
const rightTail = [ | |
tailDistance * Math.cos(rightSideDirection * Math.PI / 2), | |
tailDistance * Math.sin(rightSideDirection * Math.PI / 2) | |
]; | |
ctx.moveTo(location[0] + head[0], location[1] + head[1]); | |
ctx.lineTo(location[0] - leftTail[0], location[1] - leftTail[1]); | |
ctx.moveTo(location[0] + head[0], location[1] + head[1]); | |
ctx.lineTo(location[0] - rightTail[0], location[1] - rightTail[1]); | |
// ctx.closePath(); | |
ctx.strokeStyle = color; | |
// ctx.fillStyle = color; | |
ctx.lineWidth = 3; | |
ctx.stroke(); | |
// ctx.fill(); | |
} | |
function addPlayer(index) { | |
const player = document.createElement('h2'); | |
player.appendChild(document.createTextNode(`Player ${index}`)); | |
player.style = `color: ${colors[index - 1]}`; | |
playersContainer.appendChild(player); | |
} | |
function addController(gamepad) { | |
controllers[gamepad.index] = { | |
location: [canvas.width / 2, canvas.height / 2], | |
direction: 1, | |
index: gamepad.index, | |
speed: 0, | |
color: colors[gamepad.index] | |
}; | |
addPlayer(gamepad.index + 1); | |
} | |
window.addEventListener('gamepadconnected', e => { | |
addController(e.gamepad); | |
}); | |
window.addEventListener('gamepaddisconnected', e => { | |
console.log( | |
'Gamepad disconnected from index %d: %s', | |
e.gamepad.index, | |
e.gamepad.id | |
); | |
}); | |
// function runLoop() { | |
// gameLoop(performance.now()) | |
// } | |
// | |
// setInterval(runLoop, 30); | |
window.requestAnimationFrame(gameLoop); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment