Workshop › Angry Birds-style Slingshot › Step 25 of 47
collide(a, b) is where boxes meet. First part: if two boxes overlap, push them apart along the axis where they
overlap least. The lighter one moves more, so we need each body's mass.
```js
const mass = (b) => (b.w * b.h * MATERIALS[b.kind].density) / 400
// Two overlapping boxes: push them apart along the axis where they overlap least, then bounce their velocities
// along that axis like a collision between two masses, with a little friction along the other axis.
function collide(a, b) {
const ox = Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x)
const oy = Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y)
if (ox <= 0 || oy <= 0) return
const ia = 1 / mass(a)
const ib = 1 / mass(b)
let nx = 0
let ny = 0
let depth
if (ox < oy) [nx, depth] = [a.x + a.w / 2 < b.x + b.w / 2 ? 1 : -1, ox]
else [ny, depth] = [a.y + a.h / 2 < b.y + b.h / 2 ? 1 : -1, oy]
const push = depth / (ia + ib)
a.x -= nx * push * ia
a.y -= ny * push * ia
b.x += nx * push * ib
b.y += ny * push * ib
}
```mass is area × density / 400, so a 20×20 wood box weighs 1.ox and oy are how much the boxes overlap sideways and up-down; if either is 0 or less they do not touch.ia and ib are the inverse masses (1 / mass): big for light bodies.(nx, ny) is the normal, the direction from a to b along the axis of least overlap; depth is that overlap.depth: push * ia for a, push * ib for b; the two shares add up to
depth.body helper write mass.function step() { write the comment and collide.Skills: Collision detection
← A level as data Bounce by mass →