This commit is contained in:
Schluffe
2026-03-20 11:48:52 +01:00
parent cf8831c88d
commit fb5928dca7
3 changed files with 72 additions and 43 deletions
+67 -38
View File
@@ -14,8 +14,6 @@ const CIRCLE = Shape.Cirle;
const RECT = Shape.Rect; const RECT = Shape.Rect;
const POLYGON = Shape.Polygon; const POLYGON = Shape.Polygon;
type ShapeType = Shape.Cirle | Shape.Rect | Shape.Polygon;
type CollisionBuffer = { type CollisionBuffer = {
size: number; size: number;
mask: number; mask: number;
@@ -24,6 +22,64 @@ type CollisionBuffer = {
slice: Array<Collision>; slice: Array<Collision>;
}; };
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<Collide> = [
collideWithCirle,
collideWithRect,
collideWithPolygon,
];
const rectCollide: Array<Collide> = [
collideWithCirle,
collideWithRect,
collideWithPolygon,
];
const polygonCollide: Array<Collide> = [
collideWithCirle,
collideWithRect,
collideWithPolygon,
];
function createCollisionBuffer(size: number): CollisionBuffer { function createCollisionBuffer(size: number): CollisionBuffer {
if ((size & (size - 1)) !== 0) { if ((size & (size - 1)) !== 0) {
throw new Error("size must be a power of two"); 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]; return buffer.pool[buffer.cursor++ & buffer.mask];
} }
export type Collision = {
cid: string;
normal: Vector;
position: Vector;
depth: 0;
angle: 0;
};
function createCollision(): Collision { function createCollision(): Collision {
return { return {
cid: "", 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( export function moveAndCollide(
id: string, id: string,
velocity: Vector, velocity: Vector,
delta: number, delta: number,
): Array<Collision> { ): Array<Collision> {
const colliders = $<Collider>("collider")!; const colliders = $<Collider>("collider")!;
const self = colliders.get(id)!; const self = colliders.get(id)!.value;
console.log(id, self); const slice = self.buffer.slice;
const slice = self.value.buffer.slice;
slice.length = 0; slice.length = 0;
for (const [cid, collider] of colliders.entries()) { for (const [cid, collider] of colliders.entries()) {
@@ -102,20 +128,23 @@ export function moveAndCollide(
continue; continue;
} }
const collision = next(self.value.buffer); const other = collider.value;
switch (collider.value.shapeType) { const collision = next(self.buffer);
switch (self.shape) {
case CIRCLE: { case CIRCLE: {
// FIXME: sTruCtUrEd ClOnE >.< circleCollide[other.shape](collision, cid);
self.value.collideWithCircle(collision, cid);
break; break;
} }
case RECT: { case RECT: {
rectCollide[other.shape](collision, cid);
break; break;
} }
case POLYGON: { case POLYGON: {
polygonCollide[other.shape](collision, cid);
break; break;
} }
} }
if (collision.cid.length > 0) { if (collision.cid.length > 0) {
slice.push(collision); slice.push(collision);
} }
+3 -3
View File
@@ -9,7 +9,7 @@ import {
defineSpriteSheet, defineSpriteSheet,
} from "#/engine/Sprite.ts"; } from "#/engine/Sprite.ts";
import { import {
Collider, createCollider,
moveAndCollide, moveAndCollide,
Shape, Shape,
} from "#/engine/system/physics.ts"; } from "#/engine/system/physics.ts";
@@ -24,7 +24,7 @@ const process = defineEntity("hero", {
sprite: createSprite(idleSrc), sprite: createSprite(idleSrc),
animation: createSpriteAnimation(500, 2), animation: createSpriteAnimation(500, 2),
velocity: createVector(), velocity: createVector(),
collider: new Collider(Shape.Cirle, createCircle(createVector(), 8)), collider: createCollider(Shape.Cirle, createCircle(createVector(), 8)),
}); });
process((id, delta) => { process((id, delta) => {
@@ -48,5 +48,5 @@ process((id, delta) => {
velocity.y = 0; velocity.y = 0;
const collisions = moveAndCollide(id, velocity, delta); const collisions = moveAndCollide(id, velocity, delta);
console.log(collisions); // console.log(collisions);
}); });
+2 -2
View File
@@ -5,7 +5,7 @@ import {
createSpriteAnimation, createSpriteAnimation,
defineSpriteSheet, defineSpriteSheet,
} from "#/engine/Sprite.ts"; } 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 { createVector } from "#/engine/Vector.ts";
import portal from "#/game/assets/portal.png"; import portal from "#/game/assets/portal.png";
@@ -15,5 +15,5 @@ defineEntity("portal", {
position: createVector(), position: createVector(),
sprite: createSprite(portalSrc), sprite: createSprite(portalSrc),
animation: createSpriteAnimation(400, 0), animation: createSpriteAnimation(400, 0),
collider: new Collider(Shape.Cirle, createCircle(createVector(), 8)), collider: createCollider(Shape.Cirle, createCircle(createVector(), 8)),
}); });