JUEGS EN HTML5

JavaScript 2D Platformer Physics — Jump Arc, Gravity & Coyote Time

The jump is the heart of every platformer. This demo shows a complete 2D platformer physics loop in vanilla JavaScript and Canvas — gravity, variable jump height, coyote time so platform edges feel forgiving, horizontal acceleration, friction, and solid AABB collision. The character moves automatically when idle, but keyboard input instantly takes control.

```
What you will build

A Canvas character that runs across platforms, jumps with a variable-height arc (hold longer = jump higher), and gets 80ms of coyote time after leaving a platform. Collision is resolved separately on the X and Y axes for predictable floor, wall, and ceiling detection.

```
```
LIVE GAME DEMO

2D Platformer Physics — JavaScript Canvas

Arrow keys or A/D to move, Space / W / ↑ to jump
```

How 2D platformer physics works in JavaScript

A simple platformer does not need a full physics engine. Each frame, the game updates horizontal velocity, applies gravity to vertical velocity, moves the character, checks for collisions, and corrects any overlap with the platforms.

The important part is resolving horizontal and vertical movement separately. First the player moves on the X axis and wall collisions are resolved. Then the player moves on the Y axis and floor or ceiling collisions are resolved. This approach keeps collision behavior predictable and avoids many common corner-sticking problems found in beginner platformer code.

```
platformer.js KEY IDEA
// Gravity
```

player.vy += GRAVITY * dt;

// Horizontal movement
player.x += player.vx * dt;
resolveCollisionsX(player, platforms);

// Vertical movement
player.y += player.vy * dt;
resolveCollisionsY(player, platforms);

// Jump
if (jumpPressed && player.coyote > 0) {
player.vy = JUMP_FORCE;
player.coyote = 0;
}

Separating horizontal and vertical collision resolution makes floor, wall, and ceiling detection easier to control and debug.

Variable jump height — tap or hold

Good platformer jumps are usually not fixed. A quick tap should create a short jump, while holding the jump button should allow the character to travel higher.

This demo implements variable jump height by watching for the moment the jump button is released. If the player is still moving upward, the game immediately reduces the upward velocity.

```
jump-cut.js VARIABLE HEIGHT
const jumpReleased =
```

!jump && player.jumpHeld;

if (jumpReleased && player.vy < 0) {
player.vy *= JUMP_CUT;
}

The result is simple: tap the button for a low jump or hold it for a higher arc. This small change gives the player much more control over landing precision.

Coyote time — why platformers feel more forgiving

Coyote time gives the player a tiny window to jump after walking off the edge of a platform. Without it, pressing jump one frame too late can feel unresponsive. With coyote time, the controls tolerate a small amount of human timing error.

This demo uses an 80ms coyote-time window. Whenever the player is standing on a platform, the timer resets. After leaving the platform, the timer counts down toward zero. A jump is still allowed while that timer remains active.

```
coyote-time.js 80 MS WINDOW
if (player.onGround) {
```

player.coyote = COYOTE_TIME;
} else {
player.coyote =
Math.max(0, player.coyote - delta);
}

if (jumpPressed && player.coyote > 0) {
player.vy = JUMP_FORCE;
player.coyote = 0;
}

Automatic demo without fighting the player

Interactive examples embedded inside articles have one useful problem: if the character starts completely still, some readers may never realize the Canvas is playable.

This demo therefore moves automatically while idle. However, automatic input must never compete with real keyboard input. The moment the reader presses a movement or jump key, automatic movement is disabled and manual controls receive full priority.

```
input.js PLAYER PRIORITY
const manualMode =
```

now < manualUntil;

const left =
manualMode ? manualLeft : auto.left;

const right =
manualMode ? manualRight : auto.right;

const jump =
manualMode ? manualJump : auto.jump;

After a short period without keyboard input, the automatic demo resumes. This keeps the example visually active while still making the controls feel immediate when the reader interacts with it.

Why the original input logic could fail

A common mistake is combining automatic and manual movement in the same condition:

```
wrong.js INPUT BUG
if (rightKey || autoRight) {
```

player.vx += acceleration;
} else if (leftKey) {
player.vx -= acceleration;
}

If autoRight is true, the first condition wins even when the player is pressing left. The automatic demo effectively fights the keyboard.

The corrected version keeps automatic and manual input separate and explicitly selects which input source controls the character.

Axis-separated AABB collision

The platforms and player are rectangles, so collision detection uses axis-aligned bounding boxes, usually called AABB collision.

An overlap exists when the player's rectangle intersects a platform on both the horizontal and vertical axes. Once an overlap is found, the game compares the penetration depth and pushes the character out along the appropriate axis.

```
aabb.js COLLISION
function aabb(a, b) {
```

return (
a.x < b.x + b.w &&
a.x + a.w > b.x &&
a.y < b.y + b.h &&
a.y + a.h > b.y
);
}

Delta time keeps movement more consistent

Browser animation is usually close to 60 frames per second, but it is not guaranteed to run at exactly the same speed on every frame. That is why this version calculates a small delta-time multiplier.

Movement and gravity are multiplied by that value, which reduces visible speed differences when frames are slightly delayed. The delta value is also capped so switching browser tabs does not cause a huge physics update when the tab becomes active again.

``` Add this physics loop to your HTML5 game

This structure can be used as the foundation of a larger Canvas platformer. Replace the rectangle with a sprite, add animation states, move platforms into level data, and introduce a camera for scrolling worlds. The same player state can also be extended with wall detection, dash mechanics, one-way platforms, enemies, checkpoints, and collectibles.

```

Next steps: make it a real game

Once the base movement feels good, add features one at a time. One-way platforms can ignore upward collisions and only catch the player while falling. Wall jumps can detect horizontal contact and apply a vertical impulse. Moving platforms can update their own position before player collision is resolved.

For a side-scrolling level, add a camera offset instead of moving the entire world manually. Draw platforms and the player relative to the camera position, while keeping physics coordinates in world space.

From there, the most important improvement is not adding more physics — it is tuning the values you already have. Experiment with GRAVITY, JUMP_FORCE, FRICTION, JUMP_CUT, and COYOTE_TIME until movement feels responsive. In platformers, small timing changes can completely change how the game feels.

ADVERTISEMENT
ADVERTISEMENT

No hay comentarios:

Publicar un comentario

Buscar en el blog

Archivo del blog

Últimas en inglés