Skip to content

Instantly share code, notes, and snippets.

@jahredhope
Created February 7, 2018 12:34
Show Gist options
  • Save jahredhope/26b41deab3485cbe743d36ede97c3644 to your computer and use it in GitHub Desktop.
Save jahredhope/26b41deab3485cbe743d36ede97c3644 to your computer and use it in GitHub Desktop.
Gamepad API muckaround
<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>
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