// Character Controls "clean version" with Trails...
// dynamically handle keys instead of explicitly
// checking each one
const keys = {}document.addEventListener('keydown', e => { e.preventDefault();
// store a boolean on the `keys` object
// to keep track of whick keys are down
keys[e.key] = true;
});
document.addEventListener('keyup', e => { e.preventDefault();
keys[e.key] = false;
});
// setup motion
let x = 100;
let y = 300;
let vx = 4;
let vy = -10;
// put gravity in a variable
const GRAVITY = 1;
// replace "magic numbers" with constants
const 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 character
const charWidth = 50;
const charHeight = 80;
for (let i = 0; i < TRAIL_NUM; i++) { // create the character
const 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 reason
borderTopLeftRadius: '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 screen
let floor;
let screenRight;
let screenLeft;
// main loop
function loop() { // we want to recalculate these
// so things work when the screen resizes
floor = innerHeight - 80;
screenRight = innerWidth + 50;
screenLeft = -charWidth;
// update the characters velocity
x += vx;
y += vy;
// handle floor and screen sides
if (y > floor) { vy *= FLOOR_BOUNCE;
y = floor;
// @TODO set char xs
}
if (x > screenRight) { x = screenLeft
setLocs({ x }) }
if (x < screenLeft) { x = screenRight;
setLocs({ x }) }
// update the characters velocity with arrow keys
if (keys['ArrowRight']) { vx += ARROW_VEL;
}
if (keys['ArrowLeft']) { vx -= ARROW_VEL;
}
// character can only jump up when it is on the floor
if (keys['ArrowUp'] && y >= floor) { vy -= JUMP_POWER;
}
if (keys['ArrowDown']) { vy += ARROW_VEL;
}
vy += GRAVITY;
vx *= VX_DECAY
// update the characters styles
Object.assign(
char.style, { // use template string instead of x + 'px'
left: `${x}px`, top: `${y}px` }
);
// update trails stuff
chars[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();