Length and direction
A vector can also tell you how fast something moves regardless of direction, its length (a.k.a. magnitude). In 2D it's the Pythagorean theorem:
class Vec2 {
length() {
return Math.hypot(this.x, this.y); // sqrt(x*x + y*y)
}
}
const vel = new Vec2(300, 400);
console.log(vel.length()); // 500
Math.hypot(a, b) computes √(a² + b²) directly. The game uses length() to decide whether the player is "moving fast enough right now to skip this animation," or to measure how far an obstacle is.
You can also normalize a vector (make it length 1) to get a pure direction. That's common for spawning effects in a chosen direction. But for movement, the raw x, y components are all you need.
Terminal velocity and frame independence
Two rules keep the physics believable and fair:
- Cap the fall speed (
MAX_FALL). Without it, a long frame lets gravity accumulate too much and the player bursts through the ground. - Everything scales with
dt.position += velocity * dtmeans the motion is measured in px/s, so the jump looks identical at 30 or 60 fps.
this.vy += CONFIG.GRAVITY * dt; // integrate velocity
this.vy = Math.min(this.vy, CONFIG.MAX_FALL); // cap
this.y += this.vy * dt; // integrate position
Drop the dt and the game speeds up on fast machines. Drop the MAX_FALL cap and a single slow frame can teleport the player through the floor. Both are the same idea we met in clamp and the game loop: bounds keep a game fair.