Tweak relax scene soft blobs and spawn batches
This commit is contained in:
60
main.js
60
main.js
@@ -202,23 +202,51 @@
|
|||||||
const y = spawnFromBottom
|
const y = spawnFromBottom
|
||||||
? height + config.ballRadius * 2
|
? height + config.ballRadius * 2
|
||||||
: -config.ballRadius * 2;
|
: -config.ballRadius * 2;
|
||||||
const ball = createBallBody(x, y, color);
|
const batchMin = currentScene?.config?.spawnBatchMin ?? 1;
|
||||||
ball.plugin = {
|
const batchMax = currentScene?.config?.spawnBatchMax ?? 1;
|
||||||
color,
|
const batchCount =
|
||||||
hasEntered: false,
|
batchMin === batchMax
|
||||||
entryCheckId: null,
|
? batchMin
|
||||||
squishX: 1,
|
: Math.max(
|
||||||
squishY: 1,
|
batchMin,
|
||||||
};
|
Math.floor(Math.random() * (batchMax - batchMin + 1)) + batchMin,
|
||||||
balls.push(ball);
|
);
|
||||||
World.add(world, ball);
|
for (let i = 0; i < batchCount; i += 1) {
|
||||||
ball.plugin.entryCheckId = setTimeout(() => {
|
const blob = createBallBodies(
|
||||||
ball.plugin.entryCheckId = null;
|
Math.min(
|
||||||
if (gameOver) return;
|
Math.max(
|
||||||
if (!ball.plugin.hasEntered && Math.abs(ball.velocity.y) < 0.2) {
|
config.ballRadius + 10,
|
||||||
triggerGameOver();
|
x + (i - batchCount / 2) * config.ballRadius * 1.5,
|
||||||
|
),
|
||||||
|
width - config.ballRadius - 10,
|
||||||
|
),
|
||||||
|
y +
|
||||||
|
i *
|
||||||
|
(spawnFromBottom
|
||||||
|
? -config.ballRadius * 0.5
|
||||||
|
: config.ballRadius * 0.5),
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
if (blob.constraints.length > 0 && blob.blobId) {
|
||||||
|
blobConstraints.set(blob.blobId, blob.constraints);
|
||||||
}
|
}
|
||||||
}, 1500);
|
blob.bodies.forEach((body) => {
|
||||||
|
balls.push(body);
|
||||||
|
World.add(world, body);
|
||||||
|
if (!currentScene?.config?.noGameOver) {
|
||||||
|
body.plugin.entryCheckId = setTimeout(() => {
|
||||||
|
body.plugin.entryCheckId = null;
|
||||||
|
if (gameOver) return;
|
||||||
|
if (!body.plugin.hasEntered && Math.abs(body.velocity.y) < 0.2) {
|
||||||
|
triggerGameOver();
|
||||||
|
}
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (blob.constraints.length > 0) {
|
||||||
|
World.add(world, blob.constraints);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const startSpawner = () => {
|
const startSpawner = () => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
(() => {
|
(() => {
|
||||||
const { Bodies } = Matter;
|
const { Bodies, Composites } = Matter;
|
||||||
const scenes = (window.PhysilinksSceneDefs =
|
const scenes = (window.PhysilinksSceneDefs =
|
||||||
window.PhysilinksSceneDefs || []);
|
window.PhysilinksSceneDefs || []);
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
minChain: 2,
|
minChain: 2,
|
||||||
palette: ["#38bdf8", "#f472b6", "#fbbf24", "#22c55e", "#a855f7"],
|
palette: ["#38bdf8", "#f472b6", "#fbbf24", "#22c55e", "#a855f7"],
|
||||||
ballRadius: 20,
|
ballRadius: 20,
|
||||||
blobBalls: true,
|
blobBalls: false,
|
||||||
noGameOver: true,
|
noGameOver: true,
|
||||||
winCondition: {
|
winCondition: {
|
||||||
type: "timer",
|
type: "timer",
|
||||||
@@ -38,6 +38,46 @@
|
|||||||
const wallHeight = h + wallThickness * 2;
|
const wallHeight = h + wallThickness * 2;
|
||||||
const floorHeight = Math.max(40, h * 0.08);
|
const floorHeight = Math.max(40, h * 0.08);
|
||||||
const bumperRadius = Math.max(30, Math.min(w, h) * 0.04);
|
const bumperRadius = Math.max(30, Math.min(w, h) * 0.04);
|
||||||
|
const makeSoft = (cx, cy, cols, rows, radius, color) => {
|
||||||
|
const particleOpts = {
|
||||||
|
friction: 0.02,
|
||||||
|
frictionStatic: 0.04,
|
||||||
|
restitution: 0.02,
|
||||||
|
render: { fillStyle: color, strokeStyle: color },
|
||||||
|
plugin: { draggable: true, nonLinkable: true },
|
||||||
|
};
|
||||||
|
const constraintOpts = {
|
||||||
|
stiffness: 0.08,
|
||||||
|
damping: 0.35,
|
||||||
|
render: { visible: false, type: "line", anchors: false },
|
||||||
|
};
|
||||||
|
const comp = Composites.softBody(
|
||||||
|
cx - cols * radius * 1.1,
|
||||||
|
cy - rows * radius * 1.1,
|
||||||
|
cols,
|
||||||
|
rows,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
radius,
|
||||||
|
particleOpts,
|
||||||
|
constraintOpts,
|
||||||
|
);
|
||||||
|
comp.bodies.forEach((b) => {
|
||||||
|
b.plugin = b.plugin || {};
|
||||||
|
b.plugin.draggable = true;
|
||||||
|
b.plugin.nonLinkable = true;
|
||||||
|
});
|
||||||
|
comp.constraints.forEach((c) => {
|
||||||
|
c.plugin = { soft: true };
|
||||||
|
});
|
||||||
|
return comp;
|
||||||
|
};
|
||||||
|
|
||||||
|
const softRadius = Math.max(18, w * 0.025);
|
||||||
|
const softA = makeSoft(w * 0.35, h * 0.4, 3, 3, softRadius, "#38bdf8");
|
||||||
|
const softB = makeSoft(w * 0.65, h * 0.55, 3, 3, softRadius, "#f472b6");
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Bodies.rectangle(
|
Bodies.rectangle(
|
||||||
w / 2,
|
w / 2,
|
||||||
@@ -84,6 +124,10 @@
|
|||||||
restitution: 1.05,
|
restitution: 1.05,
|
||||||
render: { fillStyle: "#22c55e", strokeStyle: "#22c55e" },
|
render: { fillStyle: "#22c55e", strokeStyle: "#22c55e" },
|
||||||
}),
|
}),
|
||||||
|
...softA.bodies,
|
||||||
|
...softA.constraints,
|
||||||
|
...softB.bodies,
|
||||||
|
...softB.constraints,
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user