Character Controls
// Character Controls "clean version" with Trails...// dynamically handle keys instead of explicitly// checking each oneconst keys = {}
document.addEventListener('keydown', e => {
e.preventDefault();
// store a boolean on the `keys` object// to keep track of whick keys are downkeys[e.key] = true;
});
document.addEventListener('keyup', e => {
e.preventDefault();
keys[e.key] = false;
});
// setup motionlet x = 100;
let y = 300;
let vx = 4;
let vy = -10;
// put gravity in a variableconst GRAVITY = 1;
// replace "magic numbers" with constantsconst FLOOR_BOUNCE = -.33;
const JUMP_POWER = 15;
const ARROW_VEL = 3;
const VX_DECAY = .8;
const TRAIL_NUM = 10;
const chars = [];
// store the size of the characterconst charWidth = 50;
const charHeight = 80;
for (let i = 0; i < TRAIL_NUM; i++) {
// create the characterconst char = document.createElement('div');
chars.push({ char, x, y });
Object.assign(char.style, {
position: 'absolute',
width: `${charWidth}px`,
height: `${charHeight}px`,
background: 'black',
// add border radius for no reasonborderTopLeftRadius: '20px',
borderTopRightRadius: '20px',
opacity: i === 0 ? 1 : .25 - (.25 / TRAIL_NUM) * i
});
document.body.appendChild(char);
}const char = chars[0].char
function setLocs({ x, y }) {
for (let i = 0; i < TRAIL_NUM; i++) {
const char = chars[i];
if (x != null) char.x = x;
if (y != null) char.y = y;
}}// some bounds variables for the screenlet floor;
let screenRight;
let screenLeft;
// main loopfunction loop() {
// we want to recalculate these// so things work when the screen resizesfloor = innerHeight - 80;
screenRight = innerWidth + 50;
screenLeft = -charWidth;
// update the characters velocityx += vx;
y += vy;
// handle floor and screen sidesif (y > floor) {
vy *= FLOOR_BOUNCE;
y = floor;
// @TODO set char xs}if (x > screenRight) {
x = screenLeftsetLocs({ x })
}if (x < screenLeft) {
x = screenRight;
setLocs({ x })
}// update the characters velocity with arrow keysif (keys['ArrowRight']) {
vx += ARROW_VEL;
}if (keys['ArrowLeft']) {
vx -= ARROW_VEL;
}// character can only jump up when it is on the floorif (keys['ArrowUp'] && y >= floor) {
vy -= JUMP_POWER;
}if (keys['ArrowDown']) {
vy += ARROW_VEL;
}vy += GRAVITY;
vx *= VX_DECAY// update the characters stylesObject.assign(
char.style, {
// use template string instead of x + 'px'left: `${x}px`,
top: `${y}px`
});
// update trails stuffchars[0].x = x;
chars[0].y = y;
for (let i = 1; i < TRAIL_NUM; i++) {
const char = chars[i]
char.x += (chars[i - 1].x - char.x) / 4;
char.y += (chars[i - 1].y - char.y) / 4;
Object.assign(
chars[i].char.style, {
// use template string instead of x + 'px'left: `${char.x}px`,
top: `${char.y}px`
});
}requestAnimationFrame(loop);
}loop();
Click once on the preview area to give keyboard focus – then use arrow keys to move the character. I recently created a tutorial about this over on dev.to… check it out…