diff --git a/engine/system/physics.ts b/engine/system/physics.ts index b42a0cc..4dc41eb 100644 --- a/engine/system/physics.ts +++ b/engine/system/physics.ts @@ -260,9 +260,9 @@ function circleOnRect( if (hitY >= top && hitY <= bottom) { return; } + const dx = ax - (hitX < left ? left : right); const dy = ay - (hitY < top ? top : bottom); - const time = castOnCircle(dx, dy, vx, vy, radius); if (time === null) { collision.cid = ""; @@ -291,17 +291,44 @@ function rectOnCircle( colliderB: Collider, positionB: Vector, delta: number, -) {} +) { + const cWidth = (colliderA.body as Rect).width / 2; + const cHeight = (colliderA.body as Rect).height / 2; + const radius = (colliderB.body as Circle).radius; -function rectOnRect( - collision: Collision, - colliderA: Collider, - positionA: Vector, - velocityA: Vector, - colliderB: Collider, - positionB: Vector, - delta: number, -) {} + const ax = positionA.x + colliderB.offset.x + cWidth; + const ay = positionA.y + colliderB.offset.y + cHeight; + const bx = positionB.x + colliderA.offset.x + radius; + const by = positionB.y + colliderA.offset.y + radius; + + const vx = velocityA.x * delta; + const vy = velocityA.y * delta; + + const left = bx - cWidth; + const right = bx + cWidth; + const hitX = ax + vx * collision.time; + if (hitX >= left && hitX <= right) { + return; + } + + const top = by - cHeight; + const bottom = by + cHeight; + const hitY = ay + vy * collision.time; + if (hitY >= top && hitY <= bottom) { + return; + } + + const dx = ax - (hitX < left ? left : right); + const dy = ay - (hitY < top ? top : bottom); + const time = castOnCircle(dx, dy, vx, vy, radius); + if (time === null) { + collision.cid = ""; + return; + } + + collision.time = time; + invScale(collision.normal, dx + vx * time, dy + vy * time); +} function rectOnPolygon( collision: Collision, @@ -349,7 +376,7 @@ const circleCollide: Array = [ circleOnPolygon, ]; -const rectCollide: Array = [rectOnCircle, rectOnRect, rectOnPolygon]; +const rectCollide: Array = [rectOnCircle, () => {}, rectOnPolygon]; const polygonCollide: Array = [ polygonOnCircle, diff --git a/game/entities/hero/entity.ts b/game/entities/hero/entity.ts index ace5849..4e58adb 100644 --- a/game/entities/hero/entity.ts +++ b/game/entities/hero/entity.ts @@ -1,8 +1,8 @@ -import { createCircle } from "#/engine/Circle.ts"; import { defineEntity } from "#/engine/Entity.ts"; import { keyboardInput } from "#/engine/Keyboard.ts"; import { createEffect, createSignal } from "#/engine/lib/Signal.ts"; import { pointer } from "#/engine/Pointer.ts"; +import { createRect } from "#/engine/Rect.ts"; import $ from "#/engine/Scene.ts"; import { createSprite, @@ -30,7 +30,7 @@ const process = defineEntity("hero", { sprite: createSprite(idleSrc, createVector(-8, -8)), animation: createSpriteAnimation(500, 2), velocity: createVector(), - collider: createCollider(Shape.Circle, createCircle(8)), + collider: createCollider(Shape.Rect, createRect(16, 16)), }); createEffect(() => { diff --git a/game/entities/portal/entity.ts b/game/entities/portal/entity.ts index f7af10e..f526f6b 100644 --- a/game/entities/portal/entity.ts +++ b/game/entities/portal/entity.ts @@ -1,5 +1,5 @@ +import { createCircle } from "#/engine/Circle.ts"; import { defineEntity } from "#/engine/Entity.ts"; -import { createRect } from "#/engine/Rect.ts"; import { createSprite, createSpriteAnimation, @@ -16,5 +16,5 @@ defineEntity("portal", { position, sprite: createSprite(portalSrc, createVector(-8, -8)), animation: createSpriteAnimation(400, 0), - collider: createCollider(Shape.Rect, createRect(16, 16)), + collider: createCollider(Shape.Circle, createCircle(8)), });