(() => { const { Bodies } = Matter; const scenes = (window.PhysilinksSceneDefs = window.PhysilinksSceneDefs || []); scenes.push({ id: "relax", name: "Relax drift", config: { gravity: 0.08, spawnIntervalMs: 850, spawnBatchMin: 3, spawnBatchMax: 5, spawnFrom: "bottom", autoSpawn: true, minChain: 2, palette: ["#38bdf8", "#f472b6", "#fbbf24", "#22c55e", "#a855f7"], ballRadius: 20, blobBalls: true, noGameOver: true, winCondition: { type: "timer", durationSec: 120, onWin: { setGravity: -0.4, swirlBalls: true }, }, link: { stiffness: 0.6, lengthScale: 1.1, damping: 0.1, lineWidth: 3, rope: true, renderType: "line", maxLengthMultiplier: 3.8, }, }, createBodies: (w, h) => { const wallThickness = Math.max(30, w * 0.04); const wallHeight = h + wallThickness * 2; const floorHeight = Math.max(40, h * 0.08); const bumperRadius = Math.max(30, Math.min(w, h) * 0.04); return [ Bodies.rectangle( w / 2, h + floorHeight / 2, w + wallThickness * 2, floorHeight, { isStatic: true, restitution: 0.8, render: { fillStyle: "#0ea5e9", strokeStyle: "#0ea5e9" }, }, ), Bodies.rectangle( w / 2, -wallThickness / 2, w + wallThickness * 2, wallThickness, { isStatic: true, render: { fillStyle: "#0ea5e9", strokeStyle: "#0ea5e9" }, }, ), Bodies.rectangle(-wallThickness / 2, h / 2, wallThickness, wallHeight, { isStatic: true, render: { fillStyle: "#7c3aed", strokeStyle: "#7c3aed" }, }), Bodies.rectangle( w + wallThickness / 2, h / 2, wallThickness, wallHeight, { isStatic: true, render: { fillStyle: "#7c3aed", strokeStyle: "#7c3aed" }, }, ), Bodies.circle(w * 0.35, h * 0.35, bumperRadius, { isStatic: true, restitution: 1.05, render: { fillStyle: "#fbbf24", strokeStyle: "#fbbf24" }, }), Bodies.circle(w * 0.65, h * 0.55, bumperRadius * 0.9, { isStatic: true, restitution: 1.05, render: { fillStyle: "#22c55e", strokeStyle: "#22c55e" }, }), ]; }, }); })();