diff --git a/engine/system/physics.ts b/engine/system/physics.ts index 3bde81f..f038177 100644 --- a/engine/system/physics.ts +++ b/engine/system/physics.ts @@ -14,8 +14,6 @@ const CIRCLE = Shape.Cirle; const RECT = Shape.Rect; const POLYGON = Shape.Polygon; -type ShapeType = Shape.Cirle | Shape.Rect | Shape.Polygon; - type CollisionBuffer = { size: number; mask: number; @@ -24,6 +22,64 @@ type CollisionBuffer = { slice: Array; }; +type Collide = (collision: Collision, cid: string) => void; + +export type Collider = { + shape: Shape; + body: Circle | Rect | Polygon; + buffer: CollisionBuffer; +}; + +export type Collision = { + cid: string; + normal: Vector; + position: Vector; + depth: 0; + angle: 0; +}; + +export function createCollider( + shape: Shape, + body: Circle | Rect | Polygon, + bufferSize: number = 8, +): Collider { + return { + shape, + body, + buffer: createCollisionBuffer(bufferSize), + }; +} + +function collideWithCirle(collision: Collision, cid: string) { + collision.cid = cid; +} + +function collideWithRect(collision: Collision, cid: string) { + collision.cid = cid; +} + +function collideWithPolygon(collision: Collision, cid: string) { + collision.cid = cid; +} + +const circleCollide: Array = [ + collideWithCirle, + collideWithRect, + collideWithPolygon, +]; + +const rectCollide: Array = [ + collideWithCirle, + collideWithRect, + collideWithPolygon, +]; + +const polygonCollide: Array = [ + collideWithCirle, + collideWithRect, + collideWithPolygon, +]; + function createCollisionBuffer(size: number): CollisionBuffer { if ((size & (size - 1)) !== 0) { throw new Error("size must be a power of two"); @@ -47,14 +103,6 @@ function next(buffer: CollisionBuffer): Collision { return buffer.pool[buffer.cursor++ & buffer.mask]; } -export type Collision = { - cid: string; - normal: Vector; - position: Vector; - depth: 0; - angle: 0; -}; - function createCollision(): Collision { return { cid: "", @@ -65,36 +113,14 @@ function createCollision(): Collision { }; } -export class Collider { - shapeType: ShapeType; - body: Circle | Rect | Polygon; - buffer: CollisionBuffer; - - constructor( - shape: ShapeType, - body: Circle | Rect | Polygon, - bufferSize: number = 8, - ) { - this.shapeType = shape; - this.body = body; - this.buffer = createCollisionBuffer(bufferSize); - } - - // FIXME: sTruCtUrEd ClOnE >.< - collideWithCircle(collision: Collision, cid: string): void { - collision.cid = cid; - } -} - export function moveAndCollide( id: string, velocity: Vector, delta: number, ): Array { const colliders = $("collider")!; - const self = colliders.get(id)!; - console.log(id, self); - const slice = self.value.buffer.slice; + const self = colliders.get(id)!.value; + const slice = self.buffer.slice; slice.length = 0; for (const [cid, collider] of colliders.entries()) { @@ -102,20 +128,23 @@ export function moveAndCollide( continue; } - const collision = next(self.value.buffer); - switch (collider.value.shapeType) { + const other = collider.value; + const collision = next(self.buffer); + switch (self.shape) { case CIRCLE: { - // FIXME: sTruCtUrEd ClOnE >.< - self.value.collideWithCircle(collision, cid); + circleCollide[other.shape](collision, cid); break; } case RECT: { + rectCollide[other.shape](collision, cid); break; } case POLYGON: { + polygonCollide[other.shape](collision, cid); break; } } + if (collision.cid.length > 0) { slice.push(collision); } diff --git a/game/entities/hero/entity.ts b/game/entities/hero/entity.ts index 905bba4..8b4fd8e 100644 --- a/game/entities/hero/entity.ts +++ b/game/entities/hero/entity.ts @@ -9,7 +9,7 @@ import { defineSpriteSheet, } from "#/engine/Sprite.ts"; import { - Collider, + createCollider, moveAndCollide, Shape, } from "#/engine/system/physics.ts"; @@ -24,7 +24,7 @@ const process = defineEntity("hero", { sprite: createSprite(idleSrc), animation: createSpriteAnimation(500, 2), velocity: createVector(), - collider: new Collider(Shape.Cirle, createCircle(createVector(), 8)), + collider: createCollider(Shape.Cirle, createCircle(createVector(), 8)), }); process((id, delta) => { @@ -48,5 +48,5 @@ process((id, delta) => { velocity.y = 0; const collisions = moveAndCollide(id, velocity, delta); - console.log(collisions); + // console.log(collisions); }); diff --git a/game/entities/portal/entity.ts b/game/entities/portal/entity.ts index d2b0bb8..2c7b0f0 100644 --- a/game/entities/portal/entity.ts +++ b/game/entities/portal/entity.ts @@ -5,7 +5,7 @@ import { createSpriteAnimation, defineSpriteSheet, } from "#/engine/Sprite.ts"; -import { Collider, Shape } from "#/engine/system/physics.ts"; +import { createCollider, Shape } from "#/engine/system/physics.ts"; import { createVector } from "#/engine/Vector.ts"; import portal from "#/game/assets/portal.png"; @@ -15,5 +15,5 @@ defineEntity("portal", { position: createVector(), sprite: createSprite(portalSrc), animation: createSpriteAnimation(400, 0), - collider: new Collider(Shape.Cirle, createCircle(createVector(), 8)), + collider: createCollider(Shape.Cirle, createCircle(createVector(), 8)), });