Refactor ball body creation
This commit is contained in:
286
src/spawn.js
286
src/spawn.js
@@ -117,6 +117,154 @@
|
||||
config.ballRadius = nextRadius;
|
||||
};
|
||||
|
||||
const createSoftBlob = (x, y, color, commonOpts) => {
|
||||
const cols = 3;
|
||||
const rows = 2;
|
||||
const radius = Math.max(10, config.ballRadius * 0.55);
|
||||
const soft = Composites.softBody(
|
||||
x - cols * radius * 1.2,
|
||||
y - rows * radius * 1.2,
|
||||
cols,
|
||||
rows,
|
||||
0,
|
||||
0,
|
||||
true,
|
||||
radius,
|
||||
commonOpts,
|
||||
);
|
||||
const blobId = `blob-${Date.now()}-${Math.random()
|
||||
.toString(16)
|
||||
.slice(2)}`;
|
||||
soft.bodies.forEach((b) => {
|
||||
b.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
blobId,
|
||||
};
|
||||
});
|
||||
soft.constraints.forEach((c) => {
|
||||
c.plugin = { blobId, blobConstraint: true };
|
||||
c.render = c.render || {};
|
||||
c.render.type = "line";
|
||||
});
|
||||
return { bodies: soft.bodies, constraints: soft.constraints, blobId };
|
||||
};
|
||||
|
||||
const createJaggedBall = (x, y, color, commonOpts) => {
|
||||
const points = [];
|
||||
const segments = 6;
|
||||
for (let i = 0; i < segments; i += 1) {
|
||||
const angle = Math.min((i / segments) * Math.PI * 2, Math.PI * 2);
|
||||
const variance = 0.6 + Math.random() * 0.5;
|
||||
const r = config.ballRadius * variance;
|
||||
points.push({
|
||||
x: x + Math.cos(angle) * r,
|
||||
y: y + Math.sin(angle) * r,
|
||||
});
|
||||
}
|
||||
const body = Bodies.fromVertices(x, y, [points], commonOpts, true);
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "jagged",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
};
|
||||
|
||||
const createGiftBall = (x, y, color, commonOpts, scene, debugSpawn) => {
|
||||
const size = config.ballRadius * 2;
|
||||
const ribbonSize = Math.max(4, config.ballRadius * 0.35);
|
||||
const ribbonColor = scene?.config?.giftRibbonColor || "#f8fafc";
|
||||
if (debugSpawn) {
|
||||
console.log("Spawn gift", {
|
||||
sceneId: scene?.id,
|
||||
x,
|
||||
y,
|
||||
color,
|
||||
size,
|
||||
});
|
||||
}
|
||||
const base = Bodies.rectangle(x, y, size, size, {
|
||||
...commonOpts,
|
||||
chamfer: { radius: Math.max(2, config.ballRadius * 0.18) },
|
||||
});
|
||||
const ribbonRender = {
|
||||
fillStyle: ribbonColor,
|
||||
strokeStyle: "#0b1222",
|
||||
lineWidth: 2,
|
||||
};
|
||||
const verticalRibbon = Bodies.rectangle(x, y, ribbonSize, size * 1.02, {
|
||||
render: ribbonRender,
|
||||
});
|
||||
const horizontalRibbon = Bodies.rectangle(
|
||||
x,
|
||||
y,
|
||||
size * 1.02,
|
||||
ribbonSize,
|
||||
{
|
||||
render: ribbonRender,
|
||||
},
|
||||
);
|
||||
const bow = Bodies.rectangle(
|
||||
x,
|
||||
y - size * 0.34,
|
||||
ribbonSize * 1.4,
|
||||
ribbonSize * 0.8,
|
||||
{
|
||||
render: ribbonRender,
|
||||
},
|
||||
);
|
||||
const body = Body.create({
|
||||
parts: [base, verticalRibbon, horizontalRibbon, bow],
|
||||
});
|
||||
Body.setPosition(body, { x, y });
|
||||
body.restitution = commonOpts.restitution;
|
||||
body.friction = commonOpts.friction;
|
||||
body.frictionAir = commonOpts.frictionAir;
|
||||
body.frictionStatic = commonOpts.frictionStatic;
|
||||
body.density = commonOpts.density;
|
||||
body.render = {
|
||||
...body.render,
|
||||
...commonOpts.render,
|
||||
visible: true,
|
||||
};
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "gift",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
};
|
||||
|
||||
const createRectBall = (x, y, color, commonOpts) => {
|
||||
const side = config.ballRadius * 2;
|
||||
const body = Bodies.rectangle(x, y, side, side, {
|
||||
...commonOpts,
|
||||
chamfer: 0,
|
||||
});
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "rect",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
};
|
||||
|
||||
const createCircleBall = (x, y, color, commonOpts) => {
|
||||
const body = Bodies.circle(x, y, config.ballRadius, commonOpts);
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "circle",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
};
|
||||
|
||||
const createBallBodies = (x, y, color) => {
|
||||
const scene = getCurrentScene();
|
||||
const ballPhysics = scene?.config?.ballPhysics || {};
|
||||
@@ -134,146 +282,18 @@
|
||||
},
|
||||
};
|
||||
if (scene?.config?.blobBalls === "soft") {
|
||||
const cols = 3;
|
||||
const rows = 2;
|
||||
const radius = Math.max(10, config.ballRadius * 0.55);
|
||||
const soft = Composites.softBody(
|
||||
x - cols * radius * 1.2,
|
||||
y - rows * radius * 1.2,
|
||||
cols,
|
||||
rows,
|
||||
0,
|
||||
0,
|
||||
true,
|
||||
radius,
|
||||
commonOpts,
|
||||
);
|
||||
const blobId = `blob-${Date.now()}-${Math.random()
|
||||
.toString(16)
|
||||
.slice(2)}`;
|
||||
soft.bodies.forEach((b) => {
|
||||
b.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
blobId,
|
||||
};
|
||||
});
|
||||
soft.constraints.forEach((c) => {
|
||||
c.plugin = { blobId, blobConstraint: true };
|
||||
c.render = c.render || {};
|
||||
c.render.type = "line";
|
||||
});
|
||||
return { bodies: soft.bodies, constraints: soft.constraints, blobId };
|
||||
return createSoftBlob(x, y, color, commonOpts);
|
||||
}
|
||||
if (scene?.config?.blobBalls === "jagged") {
|
||||
const points = [];
|
||||
const segments = 6;
|
||||
for (let i = 0; i < segments; i += 1) {
|
||||
const angle = Math.min((i / segments) * Math.PI * 2, Math.PI * 2);
|
||||
const variance = 0.6 + Math.random() * 0.5;
|
||||
const r = config.ballRadius * variance;
|
||||
points.push({
|
||||
x: x + Math.cos(angle) * r,
|
||||
y: y + Math.sin(angle) * r,
|
||||
});
|
||||
}
|
||||
const body = Bodies.fromVertices(x, y, [points], commonOpts, true);
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "jagged",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
return createJaggedBall(x, y, color, commonOpts);
|
||||
}
|
||||
if (scene?.config?.ballShape === "gift") {
|
||||
const size = config.ballRadius * 2;
|
||||
const ribbonSize = Math.max(4, config.ballRadius * 0.35);
|
||||
const ribbonColor = scene?.config?.giftRibbonColor || "#f8fafc";
|
||||
if (debugSpawn) {
|
||||
console.log("Spawn gift", {
|
||||
sceneId: scene?.id,
|
||||
x,
|
||||
y,
|
||||
color,
|
||||
size,
|
||||
});
|
||||
}
|
||||
const base = Bodies.rectangle(x, y, size, size, {
|
||||
...commonOpts,
|
||||
chamfer: { radius: Math.max(2, config.ballRadius * 0.18) },
|
||||
});
|
||||
const ribbonRender = {
|
||||
fillStyle: ribbonColor,
|
||||
strokeStyle: "#0b1222",
|
||||
lineWidth: 2,
|
||||
};
|
||||
const verticalRibbon = Bodies.rectangle(x, y, ribbonSize, size * 1.02, {
|
||||
render: ribbonRender,
|
||||
});
|
||||
const horizontalRibbon = Bodies.rectangle(
|
||||
x,
|
||||
y,
|
||||
size * 1.02,
|
||||
ribbonSize,
|
||||
{
|
||||
render: ribbonRender,
|
||||
},
|
||||
);
|
||||
const bow = Bodies.rectangle(
|
||||
x,
|
||||
y - size * 0.34,
|
||||
ribbonSize * 1.4,
|
||||
ribbonSize * 0.8,
|
||||
{
|
||||
render: ribbonRender,
|
||||
},
|
||||
);
|
||||
const body = Body.create({
|
||||
parts: [base, verticalRibbon, horizontalRibbon, bow],
|
||||
});
|
||||
Body.setPosition(body, { x, y });
|
||||
body.restitution = commonOpts.restitution;
|
||||
body.friction = commonOpts.friction;
|
||||
body.frictionAir = commonOpts.frictionAir;
|
||||
body.frictionStatic = commonOpts.frictionStatic;
|
||||
body.density = commonOpts.density;
|
||||
body.render = {
|
||||
...body.render,
|
||||
...commonOpts.render,
|
||||
visible: true,
|
||||
};
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "gift",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
return createGiftBall(x, y, color, commonOpts, scene, debugSpawn);
|
||||
}
|
||||
if (scene?.config?.ballShape === "rect") {
|
||||
const side = config.ballRadius * 2;
|
||||
const body = Bodies.rectangle(x, y, side, side, {
|
||||
...commonOpts,
|
||||
chamfer: 0,
|
||||
});
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "rect",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
return createRectBall(x, y, color, commonOpts);
|
||||
}
|
||||
const body = Bodies.circle(x, y, config.ballRadius, commonOpts);
|
||||
body.plugin = {
|
||||
color,
|
||||
hasEntered: false,
|
||||
entryCheckId: null,
|
||||
shape: "circle",
|
||||
};
|
||||
return { bodies: [body], constraints: [], blobId: null };
|
||||
return createCircleBall(x, y, color, commonOpts);
|
||||
};
|
||||
|
||||
const spawnBall = () => {
|
||||
|
||||
Reference in New Issue
Block a user