Add pop clear animation for cleared chains
This commit is contained in:
@@ -94,6 +94,71 @@
|
||||
chain.constraints.forEach((c) => World.remove(world, c));
|
||||
};
|
||||
|
||||
const collectClearTargets = () => {
|
||||
const targets = [];
|
||||
const seen = new Set();
|
||||
const blobIds = new Set();
|
||||
|
||||
const addBall = (ball) => {
|
||||
if (!ball || seen.has(ball.id)) return;
|
||||
seen.add(ball.id);
|
||||
const radius =
|
||||
typeof ball.circleRadius === "number"
|
||||
? ball.circleRadius
|
||||
: Math.max(
|
||||
Math.abs(ball.bounds.max.x - ball.bounds.min.x),
|
||||
Math.abs(ball.bounds.max.y - ball.bounds.min.y),
|
||||
) / 2 || config.ballRadius;
|
||||
targets.push({
|
||||
x: ball.position.x,
|
||||
y: ball.position.y,
|
||||
color: ball.plugin?.color || ball.render?.fillStyle,
|
||||
radius,
|
||||
shape: ball.plugin?.shape || "circle",
|
||||
});
|
||||
};
|
||||
|
||||
chain.bodies.forEach((body) => {
|
||||
if (body.plugin?.blobId) {
|
||||
blobIds.add(body.plugin.blobId);
|
||||
}
|
||||
addBall(body);
|
||||
});
|
||||
|
||||
blobIds.forEach((id) => {
|
||||
state.balls
|
||||
.filter((b) => b.plugin?.blobId === id)
|
||||
.forEach((b) => addBall(b));
|
||||
});
|
||||
|
||||
return targets;
|
||||
};
|
||||
|
||||
const runClearAnimation = (targets) => {
|
||||
if (!targets.length || !ui?.spawnClearEffects) return;
|
||||
const linkCfg = config.link || {};
|
||||
const clearCfg = linkCfg.clearAnimation || {};
|
||||
const { render: renderOverride, ...animCfg } = clearCfg;
|
||||
const currentScene = getCurrentScene();
|
||||
let handled = false;
|
||||
if (typeof renderOverride === "function") {
|
||||
try {
|
||||
const result = renderOverride({
|
||||
targets,
|
||||
config: animCfg,
|
||||
scene: currentScene,
|
||||
ui,
|
||||
});
|
||||
handled = result !== false;
|
||||
} catch (err) {
|
||||
console.error("clearAnimation render failed", err);
|
||||
}
|
||||
}
|
||||
if (!handled) {
|
||||
ui.spawnClearEffects(targets, { type: clearCfg.type, ...animCfg });
|
||||
}
|
||||
};
|
||||
|
||||
const removeChainBodies = () => {
|
||||
const blobIds = new Set();
|
||||
chain.bodies.forEach((body) => {
|
||||
@@ -178,6 +243,7 @@
|
||||
updateLongestChain(chainLength);
|
||||
const { gain, isNegativeProgress } = getChainScoreState();
|
||||
state.score += gain;
|
||||
const clearTargets = collectClearTargets();
|
||||
state.clearedCount += chainLength;
|
||||
if (state.score > state.highScore) {
|
||||
state.highScore = state.score;
|
||||
@@ -185,6 +251,7 @@
|
||||
}
|
||||
ui.spawnScorePopup(releasePoint || chain.pointer, gain, chain.color);
|
||||
removeChainConstraints();
|
||||
runClearAnimation(clearTargets);
|
||||
removeChainBodies();
|
||||
if (isNegativeProgress) {
|
||||
applyNegativeProgressPenalty(chainLength);
|
||||
|
||||
Reference in New Issue
Block a user