Tighten rope links and expose render type per scene

This commit is contained in:
Daddy32
2025-12-12 18:25:12 +01:00
parent 294282c830
commit fb56db605f

61
main.js
View File

@@ -17,7 +17,14 @@
minChain: 3, minChain: 3,
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"], palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
ballRadius: 18, ballRadius: 18,
link: { stiffness: 0.6, lengthScale: 0.5, damping: 0.08, lineWidth: 3 }, link: {
stiffness: 0.85,
lengthScale: 1.05, // max stretch factor; slack below this
damping: 0.08,
lineWidth: 3,
rope: true,
renderType: "line",
},
}; };
const scenes = [ const scenes = [
@@ -30,7 +37,14 @@
minChain: 3, minChain: 3,
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"], palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"],
ballRadius: 38, ballRadius: 38,
link: { stiffness: 0.6, lengthScale: 0.5, damping: 0.08, lineWidth: 3 }, link: {
stiffness: 0.85,
lengthScale: 1.05,
damping: 0.08,
lineWidth: 3,
rope: true,
renderType: "line",
},
}, },
createBodies: (w, h) => [ createBodies: (w, h) => [
Bodies.rectangle(w / 2, h + 40, w, 80, { Bodies.rectangle(w / 2, h + 40, w, 80, {
@@ -58,7 +72,14 @@
minChain: 3, minChain: 3,
palette: ["#fb7185", "#fbbf24", "#34d399", "#38bdf8"], palette: ["#fb7185", "#fbbf24", "#34d399", "#38bdf8"],
ballRadius: 22, ballRadius: 22,
link: { stiffness: 0.6, lengthScale: 1.2, damping: 0.01, lineWidth: 4 }, link: {
stiffness: 0.6,
lengthScale: 1,
damping: 0.01,
lineWidth: 4,
rope: false,
renderType: "spring",
},
}, },
createBodies: (w, h) => [ createBodies: (w, h) => [
Bodies.rectangle(w / 2, h + 50, w, 100, { Bodies.rectangle(w / 2, h + 50, w, 100, {
@@ -90,7 +111,14 @@
minChain: 3, minChain: 3,
palette: ["#e879f9", "#38bdf8", "#f97316", "#22c55e"], palette: ["#e879f9", "#38bdf8", "#f97316", "#22c55e"],
ballRadius: 16, ballRadius: 16,
link: { stiffness: 1, lengthScale: 0.85, damping: 0.15, lineWidth: 3 }, link: {
stiffness: 1,
lengthScale: 0.85,
damping: 0.15,
lineWidth: 3,
rope: false,
renderType: "line",
},
}, },
createBodies: (w, h) => { createBodies: (w, h) => {
const bodies = [ const bodies = [
@@ -368,8 +396,15 @@
render: { render: {
strokeStyle: chain.color, strokeStyle: chain.color,
lineWidth: linkCfg.lineWidth ?? 3, lineWidth: linkCfg.lineWidth ?? 3,
type: linkCfg.renderType || "line",
}, },
}); });
constraint.plugin = {
restLength: dist * (linkCfg.lengthScale ?? 1),
rope: linkCfg.rope ?? false,
baseStiffness: linkCfg.stiffness ?? 0.9,
maxLength: dist * (linkCfg.lengthScale ?? 1),
};
chain.constraints.push(constraint); chain.constraints.push(constraint);
chain.bodies.push(body); chain.bodies.push(body);
setHighlight(body, true); setHighlight(body, true);
@@ -565,6 +600,24 @@
}); });
}); });
Events.on(engine, "beforeUpdate", () => {
// Rope-like constraint handling: allow shortening without push-back, tension when stretched.
chain.constraints.forEach((c) => {
if (!c.plugin || !c.plugin.rope) return;
const current = Vector.magnitude(
Vector.sub(c.bodyA.position, c.bodyB.position),
);
const maxLen = c.plugin.maxLength ?? c.length;
if (current <= maxLen) {
c.length = current;
c.stiffness = 0;
} else {
c.length = maxLen;
c.stiffness = c.plugin.baseStiffness ?? c.stiffness;
}
});
});
Events.on(render, "afterRender", () => { Events.on(render, "afterRender", () => {
if (!chain.active || !chain.pointer || chain.bodies.length === 0) return; if (!chain.active || !chain.pointer || chain.bodies.length === 0) return;
const last = chain.bodies[chain.bodies.length - 1]; const last = chain.bodies[chain.bodies.length - 1];