hm
This commit is contained in:
parent
7455d630fc
commit
4d3fc2cd47
84 changed files with 3429 additions and 3480 deletions
|
|
@ -130,105 +130,21 @@
|
|||
|
||||
function resolveRectBounce(item, rect, worldRef, source = null) {
|
||||
if (!rect) return;
|
||||
const bounceCircleOffRect = global.TarinaiPhysics?.bounceCircleOffRect;
|
||||
if (typeof bounceCircleOffRect !== "function") return;
|
||||
const hitRadius = (item.r || 18) + 2;
|
||||
const restitution = Number.isFinite(rect.restitution) ? rect.restitution : 0.78;
|
||||
const velocityDamp = rect.bounce ? 1.0 : 0.94;
|
||||
const minBounceSpeed = Math.max(0, Number(rect.minBounceSpeed || 0) || 0);
|
||||
if (rect.oriented && global.TarinaiPhysics.bounceCircleOffRect) {
|
||||
const bounced = global.TarinaiPhysics.bounceCircleOffRect(item, rect, hitRadius, restitution, worldRef, { minBounceSpeed });
|
||||
if (!bounced) return;
|
||||
item.vx *= velocityDamp;
|
||||
item.vy *= velocityDamp;
|
||||
emitBounce(item, worldRef, source || rect.item || rect);
|
||||
return;
|
||||
}
|
||||
const ensureMinNormalSpeed = (nx, ny) => {
|
||||
if (!(rect.bounce && minBounceSpeed > 0)) return;
|
||||
const normalSpeed = (item.vx || 0) * nx + (item.vy || 0) * ny;
|
||||
if (normalSpeed >= minBounceSpeed) return;
|
||||
const add = minBounceSpeed - normalSpeed;
|
||||
item.vx = (item.vx || 0) + nx * add;
|
||||
item.vy = (item.vy || 0) + ny * add;
|
||||
};
|
||||
const cx = clamp(item.x, rect.left, rect.right);
|
||||
const cy = clamp(item.y, rect.top, rect.bottom);
|
||||
let dx = item.x - cx;
|
||||
let dy = item.y - cy;
|
||||
let d = Math.hypot(dx, dy);
|
||||
if (d >= hitRadius) {
|
||||
const px = item.prevX;
|
||||
const py = item.prevY;
|
||||
const expanded = { left: rect.left - hitRadius, right: rect.right + hitRadius, top: rect.top - hitRadius, bottom: rect.bottom + hitRadius };
|
||||
if (!Number.isFinite(px) || !Number.isFinite(py) || !worldRef?.segmentIntersectsRect?.(px, py, item.x, item.y, expanded)) return;
|
||||
let nx = 0;
|
||||
let ny = 0;
|
||||
const vx = item.vx || 0;
|
||||
const vy = item.vy || 0;
|
||||
const candidates = [];
|
||||
const sx = item.x - px;
|
||||
const sy = item.y - py;
|
||||
if (px < expanded.left && sx > 0) candidates.push({ nx: -1, ny: 0, t: (expanded.left - px) / Math.max(sx, 0.001) });
|
||||
if (px > expanded.right && sx < 0) candidates.push({ nx: 1, ny: 0, t: (px - expanded.right) / Math.max(-sx, 0.001) });
|
||||
if (py < expanded.top && sy > 0) candidates.push({ nx: 0, ny: -1, t: (expanded.top - py) / Math.max(sy, 0.001) });
|
||||
if (py > expanded.bottom && sy < 0) candidates.push({ nx: 0, ny: 1, t: (py - expanded.bottom) / Math.max(-sy, 0.001) });
|
||||
if (candidates.length) {
|
||||
candidates.sort((a, b) => a.t - b.t);
|
||||
nx = candidates[0].nx;
|
||||
ny = candidates[0].ny;
|
||||
} else if (Math.abs(vx) >= Math.abs(vy)) {
|
||||
nx = vx >= 0 ? -1 : 1;
|
||||
} else {
|
||||
ny = vy >= 0 ? -1 : 1;
|
||||
}
|
||||
const toward = vx * nx + vy * ny;
|
||||
if (nx < 0) item.x = expanded.left - 0.5;
|
||||
else if (nx > 0) item.x = expanded.right + 0.5;
|
||||
if (ny < 0) item.y = expanded.top - 0.5;
|
||||
else if (ny > 0) item.y = expanded.bottom + 0.5;
|
||||
if (nx) item.y = clamp(item.y, expanded.top, expanded.bottom);
|
||||
if (ny) item.x = clamp(item.x, expanded.left, expanded.right);
|
||||
if (toward < 0) {
|
||||
item.vx = vx - (1 + restitution) * toward * nx;
|
||||
item.vy = vy - (1 + restitution) * toward * ny;
|
||||
} else {
|
||||
item.vx = vx + nx * 18;
|
||||
item.vy = vy + ny * 18;
|
||||
}
|
||||
ensureMinNormalSpeed(nx, ny);
|
||||
item.vx *= velocityDamp;
|
||||
item.vy *= velocityDamp;
|
||||
item.spinVelocity = clamp((item.spinVelocity || 0) + (nx >= 0 ? -1 : 1) * 6.2, -38, 38);
|
||||
emitBounce(item, worldRef, source || rect.item || rect);
|
||||
return;
|
||||
}
|
||||
if (d < 0.001) {
|
||||
const left = Math.abs(item.x - rect.left);
|
||||
const right = Math.abs(rect.right - item.x);
|
||||
const top = Math.abs(item.y - rect.top);
|
||||
const bottom = Math.abs(rect.bottom - item.y);
|
||||
const m = Math.min(left, right, top, bottom);
|
||||
if (m === left) { dx = -1; dy = 0; }
|
||||
else if (m === right) { dx = 1; dy = 0; }
|
||||
else if (m === top) { dx = 0; dy = -1; }
|
||||
else { dx = 0; dy = 1; }
|
||||
d = 1;
|
||||
}
|
||||
const nx = dx / d;
|
||||
const ny = dy / d;
|
||||
const toward = (item.vx || 0) * nx + (item.vy || 0) * ny;
|
||||
item.x = cx + nx * (hitRadius + 0.5);
|
||||
item.y = cy + ny * (hitRadius + 0.5);
|
||||
if (toward < 0) {
|
||||
item.vx = (item.vx || 0) - (1 + restitution) * toward * nx;
|
||||
item.vy = (item.vy || 0) - (1 + restitution) * toward * ny;
|
||||
} else {
|
||||
item.vx = (item.vx || 0) + nx * 18;
|
||||
item.vy = (item.vy || 0) + ny * 18;
|
||||
}
|
||||
ensureMinNormalSpeed(nx, ny);
|
||||
const bounced = bounceCircleOffRect(item, rect, hitRadius, restitution, worldRef, {
|
||||
minBounceSpeed: rect.bounce ? minBounceSpeed : 0,
|
||||
fallbackImpulse: 18,
|
||||
spinKick: 6.2,
|
||||
spinLimit: 38,
|
||||
});
|
||||
if (!bounced) return;
|
||||
item.vx *= velocityDamp;
|
||||
item.vy *= velocityDamp;
|
||||
item.spinVelocity = clamp((item.spinVelocity || 0) + (nx >= 0 ? -1 : 1) * 6.2, -38, 38);
|
||||
emitBounce(item, worldRef, source || rect.item || rect);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue