Back to Impossible Machine
SOURCE / PINNED RELEASE

Made of little things.

Impossible Machine

Release
841127ac75f3…
Author-recorded commit
123625b81870…
License
LICENSE
Author’s source reference
nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-47d97da9d80

Archive hash verified: db7c8101167c4b07…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/physics.ts
export type Piece = {
  id: number;
  kind: 'ramp' | 'bumper';
  x: number;
  y: number;
  angle: number;
};
export type Ball = { x: number; y: number; vx: number; vy: number };
export const radius = 10;
export function endpoints(p: Piece) {
  const dx = Math.cos(p.angle) * 70,
    dy = Math.sin(p.angle) * 70;
  return [p.x - dx, p.y - dy, p.x + dx, p.y + dy];
}
export function step(ball: Ball, pieces: Piece[], dt: number) {
  ball.vy += 480 * dt;
  ball.x += ball.vx * dt;
  ball.y += ball.vy * dt;
  for (const p of pieces) {
    let qx = p.x,
      qy = p.y,
      r = 34;
    if (p.kind === 'ramp') {
      const [ax, ay, bx, by] = endpoints(p);
      const t = Math.max(
        0,
        Math.min(
          1,
          ((ball.x - ax) * (bx - ax) + (ball.y - ay) * (by - ay)) / 19600,
        ),
      );
      qx = ax + t * (bx - ax);
      qy = ay + t * (by - ay);
      r = 16;
    }
    let dx = ball.x - qx,
      dy = ball.y - qy,
      d = Math.hypot(dx, dy);
    if (d >= r) continue;
    if (d < 0.0001) {
      dx = 0;
      dy = -1;
      d = 1;
    }
    const nx = dx / d,
      ny = dy / d;
    ball.x = qx + nx * r;
    ball.y = qy + ny * r;
    const vn = ball.vx * nx + ball.vy * ny;
    if (vn < 0) {
      const bounce = p.kind === 'bumper' ? 1.65 : 1.08;
      ball.vx -= bounce * vn * nx;
      ball.vy -= bounce * vn * ny;
      if (p.kind === 'bumper') {
        ball.vx += nx * 55;
        ball.vy += ny * 55;
      }
    }
  }
}
export function caught(ball: Ball, cup: { x: number; y: number }) {
  return (
    Math.abs(ball.x - cup.x) < 29 &&
    ball.y > cup.y - 10 &&
    ball.y < cup.y + 22 &&
    ball.vy >= 0
  );
}