From d3ea50b37ad728ab0efe097d96a62bf16e403b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cchrisshank=E2=80=9D?= Date: Sat, 7 Dec 2024 00:41:35 -0800 Subject: [PATCH] fix collision --- demo/shape-collision-detection.html | 8 ++++---- src/common/collision.ts | 17 ++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/demo/shape-collision-detection.html b/demo/shape-collision-detection.html index 56fd42d..1f2418d 100644 --- a/demo/shape-collision-detection.html +++ b/demo/shape-collision-detection.html @@ -52,7 +52,7 @@ import { FolkShape } from '../src/standalone/folk-shape.ts'; import { aabbHitDetection } from '../src/common/collision.ts'; - const shapes = Array.from(document.querySelectorAll('folk-shape')); + const shapes = Array.from(document.querySelectorAll('folk-shape, p')); const getBoundingBox = (el) => (el instanceof FolkShape ? el.getTransformDOMRect() : el.getBoundingClientRect()); @@ -60,13 +60,13 @@ for (const shape of shapes) { if (shape === e.target) continue; - const hit = aabbHitDetection(getBoundingBox(shape), getBoundingBox(e.target)); + const hit = aabbHitDetection(getBoundingBox(e.target), getBoundingBox(shape)); if (hit === null) continue; if (shape instanceof FolkShape) { - if (hit.delta.x !== 0) shape.x -= hit.delta.x; - if (hit.delta.y !== 0) shape.y -= hit.delta.y; + if (hit.delta.x !== 0) shape.x += hit.delta.x; + if (hit.delta.y !== 0) shape.y += hit.delta.y; } else { if (hit.delta.x !== 0) e.preventX(); if (hit.delta.y !== 0) e.preventY(); diff --git a/src/common/collision.ts b/src/common/collision.ts index 8800b4d..32effa6 100644 --- a/src/common/collision.ts +++ b/src/common/collision.ts @@ -15,39 +15,38 @@ export class Hit { } const center = (rect: DOMRectReadOnly) => ({ + width: rect.width / 2, + height: rect.height / 2, x: rect.x + rect.width / 2, y: rect.y + rect.height / 2, }); -/** Test collisions of axis-aligned bounding boxes. */ export function aabbHitDetection(rect1: DOMRectReadOnly, rect2: DOMRectReadOnly): Hit | null { const center1 = center(rect1); const center2 = center(rect2); - const dx = center1.x - center2.x; - const px = (rect2.width + rect1.width) / 2 - Math.abs(dx); + const dx = center2.x - center1.x; + const px = center2.width + center1.width - Math.abs(dx); if (px <= 0) return null; const dy = center2.y - center1.y; - const py = (rect2.height + rect1.height) / 2 - Math.abs(dy); + const py = center2.height + center1.height - Math.abs(dy); if (py <= 0) return null; const hit = new Hit(); - if (px < py) { const sx = sign(dx); hit.delta.x = px * sx; hit.normal.x = sx; - hit.pos.x = center1.x + (rect1.width / 2) * sx; + hit.pos.x = center1.x + center1.width * sx; hit.pos.y = center2.y; } else { const sy = sign(dy); hit.delta.y = py * sy; hit.normal.y = sy; - hit.pos.x = rect2.x; - hit.pos.y = center2.y + (rect1.height / 2) * sy; + hit.pos.x = center2.x; + hit.pos.y = center1.y + center1.height * sy; } - return hit; }