From 31ae9d94d528d05cbb52794082918ef12c733e09 Mon Sep 17 00:00:00 2001 From: Schluffe Date: Tue, 17 Mar 2026 23:26:16 +0100 Subject: [PATCH] WIP --- engine/lib/RingBuffer.ts | 25 +++++++++++++++++ engine/system/processPhysics.ts | 48 +++++++++++++-------------------- game/entities/hero/entity.ts | 8 +++--- game/entities/portal/entity.ts | 3 ++- main.ts | 3 --- 5 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 engine/lib/RingBuffer.ts diff --git a/engine/lib/RingBuffer.ts b/engine/lib/RingBuffer.ts new file mode 100644 index 0000000..9d5c95b --- /dev/null +++ b/engine/lib/RingBuffer.ts @@ -0,0 +1,25 @@ +export default class RingBuffer { + size: number; + mask: number; + cursor: number; + buffer: Array; + + constructor(size: number, blueprint: T) { + if ((size & (size - 1)) !== 0) { + throw new Error("size must be a power of two"); + } + + this.size = size; + this.mask = size - 1; + this.cursor = 0; + this.buffer = []; + + for (let i = 0; i < size; i++) { + this.buffer.push(structuredClone(blueprint)); + } + } + + next(): T { + return this.buffer[this.cursor++ & this.mask]; + } +} diff --git a/engine/system/processPhysics.ts b/engine/system/processPhysics.ts index 5a1b749..f77ea1e 100644 --- a/engine/system/processPhysics.ts +++ b/engine/system/processPhysics.ts @@ -1,9 +1,10 @@ import type { Circle } from "#/engine/Circle.ts"; import type MapProxy from "#/engine/lib/MapProxy.ts"; +import RingBuffer from "#/engine/lib/RingBuffer.ts"; import type { Polygon } from "#/engine/Polygon.ts"; import type { Rect } from "#/engine/Rect.ts"; import $ from "#/engine/Scene.ts"; -import type { Vector } from "#/engine/Vector.ts"; +import { createVector, type Vector } from "#/engine/Vector.ts"; const CIRCLE = 0; const RECT = 1; @@ -13,49 +14,38 @@ type Shape = 0 | 1 | 2; export type Collider = { shape: Shape; + collision: Collision; }; export type Collision = { id: string; }; -const collisions = new Map(); - -function check( - id: string, - collider: Collider, - position: Vector, - colliders: MapProxy, -): string | undefined { - for (const [oid, other] of colliders.entries()) { - if (oid !== id && other) { - return oid; - } - } +export function createCollider(shape: Shape): Collider { + return { + shape, + collision: { id: "" }, + }; } +const collisions = new RingBuffer(128, { + id: "", + normal: createVector(), +}); + export function moveAndCollide( id: string, velocity: Vector, delta: number, -): Collision | undefined { - return collisions.get(id); -} - -export function processPhysics( - ctx: CanvasRenderingContext2D, - delta: number, ): void { const colliders = $("collider")!; - const positions = $("position")!; - for (const [id, collider] of colliders.entries()) { - const position = positions.get(id)!; - const target = check(id, collider.value, position.value, colliders); - if (target !== undefined) { - collisions.set(id, { id: target }); - } else { - collisions.delete(id); + for (const [oid, _] of colliders.entries()) { + if (oid === id) { + continue; } + + const self = colliders.get(id)!.value; + self.collision.id = oid; } } diff --git a/game/entities/hero/entity.ts b/game/entities/hero/entity.ts index 64e8379..03aa6f0 100644 --- a/game/entities/hero/entity.ts +++ b/game/entities/hero/entity.ts @@ -10,6 +10,7 @@ import { } from "#/engine/Sprite.ts"; import { type Collider, + createCollider, moveAndCollide, } from "#/engine/system/processPhysics.ts"; import { createVector, type Vector } from "#/engine/Vector.ts"; @@ -23,12 +24,13 @@ const process = defineEntity("hero", { sprite: createSprite(idleSrc), animation: createSpriteAnimation(500, 2), velocity: createVector(), - collider: createCircle(createVector(), 8), + collider: createCollider(0), }); process((id, delta) => { const position = $("position").get(id)!.value; const velocity = $("velocity").get(id)!.value; + const collider = $("collider").get(id)!.value; if (pointer.isDown) { position.x = pointer.position.x; @@ -46,6 +48,6 @@ process((id, delta) => { velocity.x = 0; velocity.y = 0; - const collision = moveAndCollide(id, velocity, delta); - // console.log(collision); + moveAndCollide(id, velocity, delta); + console.log(collider.collision.id); }); diff --git a/game/entities/portal/entity.ts b/game/entities/portal/entity.ts index 83f6feb..2524113 100644 --- a/game/entities/portal/entity.ts +++ b/game/entities/portal/entity.ts @@ -5,6 +5,7 @@ import { createSpriteAnimation, defineSpriteSheet, } from "#/engine/Sprite.ts"; +import { createCollider } from "#/engine/system/processPhysics.ts"; import { createVector } from "#/engine/Vector.ts"; import portal from "#/game/assets/portal.png"; @@ -14,5 +15,5 @@ defineEntity("portal", { position: createVector(), sprite: createSprite(portalSrc), animation: createSpriteAnimation(400, 0), - collider: createCircle(createVector(), 8), + collider: createCollider(0), }); diff --git a/main.ts b/main.ts index a072b7c..964e0b9 100644 --- a/main.ts +++ b/main.ts @@ -3,7 +3,6 @@ import { listenPointer } from "#/engine/Pointer.ts"; import { currentScene, setScene } from "#/engine/Scene.ts"; import { animateSprites } from "#/engine/system/animateSprites.ts"; import { drawSprites } from "#/engine/system/drawSprites.ts"; -import { processPhysics } from "#/engine/system/processPhysics.ts"; import { initViewport, resetCtx, @@ -20,8 +19,6 @@ function animate(timestamp: number): void { resetCtx(); currentScene.process(viewport.ctx, delta); - processPhysics(viewport.ctx, delta); - animateSprites(delta); drawSprites(viewport.ctx);