Basic

Movement, gravity, and collision that does not tunnel

A fast object can pass through a wall between frames. The fix is to move in steps and test the path, or to test the swept box rather than the point. Either way, the collision test belongs to the movement, not to the drawing.

What you will see

A corner catch that is the same every run. Resolving both axes at once makes that result order-dependent.

About 1 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Stop a fast object inside a wall

1

Show the tunnel

node -e 'let x=0; const wall=50; for (let i=0;i<3;i++){ x+=40; if (x===wall) console.log("hit"); } console.log("x="+x)'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
x=120 and no hit. The object jumped past the wall because the step was bigger than the gap.
2

Use the swept test

printf 'function hit(from, to, wall) { return from < wall && to >= wall; } ' | tee game/phys.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
True when the path crosses the wall, whatever the step size.
3

Clamp to the contact

printf 'function move(w, dx) { const to = w.x + dx; if (hit(w.x, to, 50)) { w.x = 50; w.vx = 0; } else w.x = to; } ' | tee -a game/phys.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The object rests at 50 rather than passing through it.
4

Resolve one axis

call move for x, then for y, in that order, and print the final box

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A corner catch that is the same every run. Resolving both axes at once makes that result order-dependent.
Do not test only the new position. A step larger than the thinnest wall tunnels, and the bug appears only at high speed.

Data Flow

Proposed move to a contact
1 Propose the new position
↓
2 Test the swept box from old to new
↓
3 Clamp to the first contact
↓
4 Apply the clamped position
Why this works
The order of a move

Propose the new position, test the swept path, clamp to the contact, apply. Clamping after the test is what makes the object rest on the surface.

Where the step is too big

If the step exceeds the thinnest wall, the point test tunnels. Either cap the step or use the swept test, and pick one and keep it.

Examples

Test the box, not the point

A point test at the new position misses a wall the object crossed on the way. A box from old to new catches it.

Resolve one axis at a time

Move on one axis, resolve the collision, then the other axis. Resolving both at once produces a corner catch that depends on order.

Gravity is a force, not a jump

Accumulate velocity and clamp at the ground. Setting the velocity to zero at the ground each frame is the same result and hides the intent.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Input that does not repeat or drop
Previous Lesson
Input that does not repeat or drop
Next Lesson
Rules that read state and change state only
Rules that read state and change state only →