From 8ea950db5afa54ee6d9d3d6ccb078426a9b8e5b8 Mon Sep 17 00:00:00 2001 From: Schluffe Date: Wed, 18 Feb 2026 20:35:44 +0100 Subject: [PATCH] WIP --- engine/AABB.ts | 43 ----------------------- engine/Circle.ts | 19 +++++++++- engine/Rect.ts | 63 +++++++++++++++++++++++++++++++++ engine/dev/main.tsx | 4 +++ engine/lib/geometry.ts | 64 +++++++++++++++++----------------- game/entities/hero/entity.ts | 3 +- game/scenes/testScene/scene.ts | 4 +-- 7 files changed, 120 insertions(+), 80 deletions(-) delete mode 100644 engine/AABB.ts create mode 100644 engine/Rect.ts diff --git a/engine/AABB.ts b/engine/AABB.ts deleted file mode 100644 index ea32d71..0000000 --- a/engine/AABB.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { copyVector, type Vector } from "#/engine/Vector.ts"; - -export type AABB = { - position: Vector; - width: number; - height: number; -}; - -export function createAABB( - position: Vector, - width: number, - height: number, -): AABB { - return { - position, - width, - height, - }; -} - -export function fromMinMax(min: Vector, max: Vector): AABB { - return { - position: copyVector(min), - width: max.x - min.x, - height: max.y - min.y, - }; -} - -export function drawAABB( - ctx: CanvasRenderingContext2D, - aabb: AABB, - color: string = "#fff", -): void { - ctx.save(); - ctx.strokeStyle = color; - ctx.strokeRect( - aabb.position.x - 0.5, - aabb.position.y - 0.5, - aabb.width, - aabb.height, - ); - ctx.restore(); -} diff --git a/engine/Circle.ts b/engine/Circle.ts index 57eea55..ffe16af 100644 --- a/engine/Circle.ts +++ b/engine/Circle.ts @@ -12,15 +12,32 @@ export function createCircle(position: Vector, radius: number): Circle { }; } -export function drawCircle( +export function strokeCircle( ctx: CanvasRenderingContext2D, circle: Circle, color: string = "#fff", + alpha: number = 1.0, ): void { ctx.save(); ctx.strokeStyle = color; + ctx.globalAlpha = alpha; ctx.beginPath(); ctx.arc(circle.position.x, circle.position.y, circle.radius, 0, 2 * Math.PI); ctx.stroke(); ctx.restore(); } + +export function fillCircle( + ctx: CanvasRenderingContext2D, + circle: Circle, + color: string = "#fff", + alpha: number = 1.0, +): void { + ctx.save(); + ctx.fillStyle = color; + ctx.globalAlpha = alpha; + ctx.beginPath(); + ctx.arc(circle.position.x, circle.position.y, circle.radius, 0, 2 * Math.PI); + ctx.fill(); + ctx.restore(); +} diff --git a/engine/Rect.ts b/engine/Rect.ts new file mode 100644 index 0000000..f41ecd4 --- /dev/null +++ b/engine/Rect.ts @@ -0,0 +1,63 @@ +import { copyVector, type Vector } from "#/engine/Vector.ts"; + +export type Rect = { + position: Vector; + width: number; + height: number; +}; + +export function createRect( + position: Vector, + width: number, + height: number, +): Rect { + return { + position, + width, + height, + }; +} + +export function fromMinMax(min: Vector, max: Vector): Rect { + return { + position: copyVector(min), + width: max.x - min.x, + height: max.y - min.y, + }; +} + +export function strokeRect( + ctx: CanvasRenderingContext2D, + rect: Rect, + color: string = "#fff", + alpha: number = 1.0, +): void { + ctx.save(); + ctx.strokeStyle = color; + ctx.globalAlpha = alpha; + ctx.strokeRect( + rect.position.x - 0.5, + rect.position.y - 0.5, + rect.width, + rect.height, + ); + ctx.restore(); +} + +export function fillRect( + ctx: CanvasRenderingContext2D, + rect: Rect, + color: string = "#fff", + alpha: number = 1.0, +): void { + ctx.save(); + ctx.strokeStyle = color; + ctx.globalAlpha = alpha; + ctx.fillRect( + rect.position.x - 0.5, + rect.position.y - 0.5, + rect.width, + rect.height, + ); + ctx.restore(); +} diff --git a/engine/dev/main.tsx b/engine/dev/main.tsx index eb38b06..a6c06a0 100644 --- a/engine/dev/main.tsx +++ b/engine/dev/main.tsx @@ -18,6 +18,7 @@ import { setScene, } from "#/engine/Scene.ts"; import { setScale, viewport } from "#/engine/Viewport.ts"; +import { strokeRect } from "../Rect.ts"; import { InputField } from "./controls/InputField.tsx"; import { RangeSlider } from "./controls/RangeSlider.tsx"; import { GraphBrowser } from "./GraphBrowser.tsx"; @@ -115,6 +116,7 @@ const DevTools: Component<{ gameContainer: HTMLElement }> = ({ processProxy(...args); ctx.save(); + ctx.globalAlpha = 0.75; ctx.lineWidth = 1; ctx.strokeStyle = "#6572f5"; viewport.ctx.strokeRect( @@ -131,6 +133,8 @@ const DevTools: Component<{ gameContainer: HTMLElement }> = ({ 2, 2, ); + ctx.beginPath(); + ctx.fill(); ctx.restore(); }; }; diff --git a/engine/lib/geometry.ts b/engine/lib/geometry.ts index 9de04fc..e1e6d7b 100644 --- a/engine/lib/geometry.ts +++ b/engine/lib/geometry.ts @@ -1,5 +1,5 @@ -import type { AABB } from "#/engine/AABB.ts"; import type { Circle } from "#/engine/Circle.ts"; +import type { Rect } from "#/engine/Rect"; import type { Vector } from "#/engine/Vector.ts"; export function isPointInCircle(point: Vector, circle: Circle): boolean { @@ -9,15 +9,15 @@ export function isPointInCircle(point: Vector, circle: Circle): boolean { return dx * dx + dy * dy <= circle.radius ** 2; } -export function isPointInAABB(point: Vector, aabb: AABB): boolean { - const rx = aabb.position.x; - const ry = aabb.position.y; +export function isPointInRect(point: Vector, rect: Rect): boolean { + const rx = rect.position.x; + const ry = rect.position.y; return ( point.x >= rx && - point.x <= rx + aabb.width && + point.x <= rx + rect.width && point.y >= ry && - point.y <= ry + aabb.height + point.y <= ry + rect.height ); } @@ -28,7 +28,7 @@ export function circleIntersectCircle(a: Circle, b: Circle): boolean { return dx * dx + dy * dy <= (a.radius + b.radius) ** 2; } -export function AABBIntersectAABB(a: AABB, b: AABB): boolean { +export function RectIntersectRect(a: Rect, b: Rect): boolean { const ax = a.position.x; const ay = a.position.y; const bx = b.position.x; @@ -42,14 +42,14 @@ export function AABBIntersectAABB(a: AABB, b: AABB): boolean { ); } -export function circleIntersectAABB(circle: Circle, aabb: AABB): boolean { +export function circleIntersectRect(circle: Circle, rect: Rect): boolean { const cx = circle.position.x; const cy = circle.position.y; - const rx = aabb.position.x; - const ry = aabb.position.y; + const rx = rect.position.x; + const ry = rect.position.y; - const dx = cx - Math.max(rx, Math.min(cx, rx + aabb.width)); - const dy = cy - Math.max(ry, Math.min(cy, ry + aabb.height)); + const dx = cx - Math.max(rx, Math.min(cx, rx + rect.width)); + const dy = cy - Math.max(ry, Math.min(cy, ry + rect.height)); return dx * dx + dy * dy <= circle.radius ** 2; } @@ -62,7 +62,7 @@ export function circleContainsCircle(a: Circle, b: Circle): boolean { return a.radius >= b.radius + distance; } -export function AABBContainsAABB(a: AABB, b: AABB): boolean { +export function RectContainsRect(a: Rect, b: Rect): boolean { const ax = a.position.x; const ay = a.position.y; const bx = b.position.x; @@ -76,44 +76,44 @@ export function AABBContainsAABB(a: AABB, b: AABB): boolean { ); } -export function AABBContainsCircle(aabb: AABB, circle: Circle): boolean { - const rx = aabb.position.x; - const ry = aabb.position.y; +export function RectContainsCircle(rect: Rect, circle: Circle): boolean { + const rx = rect.position.x; + const ry = rect.position.y; const cx = circle.position.x; const cy = circle.position.y; return ( rx <= cx - circle.radius && - rx + aabb.width >= cx + circle.radius && + rx + rect.width >= cx + circle.radius && ry <= cy - circle.radius && - ry + aabb.height >= cy + circle.radius + ry + rect.height >= cy + circle.radius ); } -export function circleContainsAABB(circle: Circle, aabb: AABB): boolean { - const radiusSquare = circle.radius ** 2; +export function circleContainsRect(circle: Circle, rect: Rect): boolean { + const radSquare = circle.radius ** 2; - const dax = aabb.position.x - circle.position.x; - const day = aabb.position.y - circle.position.y; - if (dax * dax + day * day > radiusSquare) { + const dax = rect.position.x - circle.position.x; + const day = rect.position.y - circle.position.y; + if (dax * dax + day * day > radSquare) { return false; } - const dbx = aabb.position.x + aabb.width - circle.position.x; - const dby = aabb.position.y - circle.position.y; - if (dbx * dbx + dby * dby > radiusSquare) { + const dbx = rect.position.x + rect.width - circle.position.x; + const dby = rect.position.y - circle.position.y; + if (dbx * dbx + dby * dby > radSquare) { return false; } - const dcx = aabb.position.x - circle.position.x; - const dcy = aabb.position.y + aabb.height - circle.position.y; - if (dcx * dcx + dcy * dcy > radiusSquare) { + const dcx = rect.position.x - circle.position.x; + const dcy = rect.position.y + rect.height - circle.position.y; + if (dcx * dcx + dcy * dcy > radSquare) { return false; } - const ddx = aabb.position.x + aabb.width - circle.position.x; - const ddy = aabb.position.y + aabb.height - circle.position.y; - if (ddx * ddx + ddy * ddy > radiusSquare) { + const ddx = rect.position.x + rect.width - circle.position.x; + const ddy = rect.position.y + rect.height - circle.position.y; + if (ddx * ddx + ddy * ddy > radSquare) { return false; } diff --git a/game/entities/hero/entity.ts b/game/entities/hero/entity.ts index 7c4b0e5..a38d2c0 100644 --- a/game/entities/hero/entity.ts +++ b/game/entities/hero/entity.ts @@ -1,5 +1,5 @@ import { createAnimation, playAnimation } from "#/engine/Animation.ts"; -import { createCircle, drawCircle } from "#/engine/Circle"; +import { createCircle } from "#/engine/Circle"; import { moveAndCollide } from "#/engine/Collision.ts"; import { defineEntity } from "#/engine/Entity.ts"; import { keyboardInput } from "#/engine/Keyboard.ts"; @@ -28,7 +28,6 @@ animate((entity, ctx, delta) => { entity.position.y, delta, ); - drawCircle(ctx, entity.body.shape, "red"); }); process((entity, delta) => { diff --git a/game/scenes/testScene/scene.ts b/game/scenes/testScene/scene.ts index e7ee122..975a743 100644 --- a/game/scenes/testScene/scene.ts +++ b/game/scenes/testScene/scene.ts @@ -1,4 +1,4 @@ -import { drawCircle } from "#/engine/Circle"; +import { strokeCircle } from "#/engine/Circle"; import { pointer } from "#/engine/Pointer.ts"; import { defineScene } from "#/engine/Scene.ts"; import data from "./data.json"; @@ -17,7 +17,7 @@ preProcess((entityInstanceMap) => { process((ctx, delta) => { if (!pointer.isDown) { - drawCircle(ctx, { + strokeCircle(ctx, { position: pointer.position, radius: 4, });