diff --git a/README.md b/README.md
index 4cc40f4..6507ca9 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,7 @@ Physilinks is a browser-based physics linking game built with Matter.js. Match a
- `index.html`: Shell layout and HUD overlays; loads Matter.js plus game scripts.
- `styles.css`: Styling for canvas, HUD, overlays, and score popups.
- `scenes/`: Scene presets split per file (`scene-*.js`) plus `index.js` that registers them to `window.PhysilinksScenes` (e.g., zero-G grid, balanced, low-G, fast drop, lava drift).
+- `decomp-setup.js`: Registers `poly-decomp` with Matter to allow concave shapes (stars, blobs) built via `Bodies.fromVertices`.
- `ui.js`: DOM access, HUD updates, overlays, popups, and control/selector wiring.
- `main.js`: Physics setup, state machine, chain interaction, spawning, scene application, and pause/restart logic.
diff --git a/decomp-setup.js b/decomp-setup.js
new file mode 100644
index 0000000..d3bfd01
--- /dev/null
+++ b/decomp-setup.js
@@ -0,0 +1,5 @@
+(() => {
+ if (typeof Matter !== "undefined" && Matter.Common && window.decomp) {
+ Matter.Common.setDecomp(window.decomp);
+ }
+})();
diff --git a/index.html b/index.html
index 9b89ff3..884c8c4 100644
--- a/index.html
+++ b/index.html
@@ -92,6 +92,8 @@
+
+
diff --git a/scenes/scene-lowg.js b/scenes/scene-lowg.js
index e74ae93..0f17c41 100644
--- a/scenes/scene-lowg.js
+++ b/scenes/scene-lowg.js
@@ -1,5 +1,5 @@
(() => {
- const { Bodies, Body } = Matter;
+ const { Bodies, Body, Vertices } = Matter;
const scenes = (window.PhysilinksSceneDefs =
window.PhysilinksSceneDefs || []);
@@ -14,7 +14,7 @@
ballRadius: 22,
winCondition: {
type: "score",
- target: 50000,
+ target: 15000,
onWin: { shoveBalls: true },
},
link: {
@@ -24,7 +24,7 @@
lineWidth: 4,
rope: false,
renderType: "spring",
- maxLengthMultiplier: 4.7,
+ maxLengthMultiplier: 6,
},
},
createBodies: (w, h) => {
@@ -70,6 +70,29 @@
return gear;
};
+ const makeStar = (x, y, size, color, angle, rotSpeed) => {
+ const base = Vertices.fromPath(
+ "50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38",
+ );
+ const scale = (size || 50) / 50;
+ const pts = base.map((p) => ({
+ x: (p.x - 50) * scale,
+ y: (p.y - 50) * scale,
+ }));
+ return Bodies.fromVertices(
+ x,
+ y,
+ [pts],
+ {
+ isStatic: true,
+ angle,
+ render: { fillStyle: color, strokeStyle: color },
+ plugin: { rotSpeed },
+ },
+ true,
+ );
+ };
+
return [
Bodies.rectangle(
w / 2,
@@ -155,19 +178,16 @@
},
},
}),
- // Random polygon obstacles
- Bodies.polygon(w * 0.18, h * 0.28, 5, bumperRadius * 0.9, {
- isStatic: true,
- angle: 0.2,
- render: { fillStyle: "#22c55e", strokeStyle: "#22c55e" },
- plugin: { rotSpeed: -0.6 },
- }),
- Bodies.polygon(w * 0.86, h * 0.62, 7, bumperRadius * 0.95, {
- isStatic: true,
- angle: -0.25,
- render: { fillStyle: "#c084fc", strokeStyle: "#c084fc" },
- plugin: { rotSpeed: 0.9 },
- }),
+ // Star obstacles
+ makeStar(w * 0.18, h * 0.28, bumperRadius * 1.1, "#22c55e", 0.2, -0.6),
+ makeStar(
+ w * 0.86,
+ h * 0.62,
+ bumperRadius * 1.15,
+ "#c084fc",
+ -0.25,
+ 0.9,
+ ),
];
},
});