This commit is contained in:
Schluffe
2026-03-17 21:09:17 +01:00
parent a2af7b9940
commit 3242e8cbbb
6 changed files with 57 additions and 34 deletions
+3 -3
View File
@@ -1,4 +1,4 @@
import { createVector, setEdgeNormal, type Vector } from "#/engine/Vector.ts"; import { createVector, setUnitNormal, type Vector } from "#/engine/Vector.ts";
export type Polygon = { export type Polygon = {
position: Vector; position: Vector;
@@ -24,9 +24,9 @@ export function updateAxes({ points, axes }: Polygon): void {
for (let i = 0; i < cap; i++) { for (let i = 0; i < cap; i++) {
const pj = points[i + 1]; const pj = points[i + 1];
setEdgeNormal(axes[i], pi, pj); setUnitNormal(axes[i], pi, pj);
pi = pj; pi = pj;
} }
setEdgeNormal(axes[cap], pi, p0); setUnitNormal(axes[cap], pi, p0);
} }
+11 -17
View File
@@ -47,24 +47,22 @@ export function getSquared(vector: Vector): number {
return vector.x * vector.x + vector.y * vector.y; return vector.x * vector.x + vector.y * vector.y;
} }
export function setDistanceNormal(normal: Vector, a: Vector, b: Vector): void { export function setUnit(unit: Vector, a: Vector, b: Vector): void {
const dx = a.x - b.x; const dx = a.x - b.x;
const dy = a.y - b.y; const dy = a.y - b.y;
const distance = Math.sqrt(dx * dx + dy * dy); const inv = 1.0 / Math.sqrt(dx * dx + dy * dy);
if (distance > 0) { unit.x = dx * inv;
normal.x = dx / distance; unit.y = dy * inv;
normal.y = dy / distance;
}
} }
export function setEdgeNormal(normal: Vector, a: Vector, b: Vector): void { export function setUnitNormal(unit: Vector, a: Vector, b: Vector): void {
const nx = -(b.y - a.y); const nx = a.y - b.y;
const ny = b.x - a.x; const ny = b.x - a.x;
const inv = 1.0 / Math.sqrt(nx * nx + ny * ny); const inv = 1.0 / Math.sqrt(nx * nx + ny * ny);
normal.x = nx * inv; unit.x = nx * inv;
normal.y = ny * inv; unit.y = ny * inv;
} }
export function getDotProduct(a: Vector, b: Vector): number { export function getDotProduct(a: Vector, b: Vector): number {
@@ -81,13 +79,9 @@ export function scale(vector: Vector, scalar: number): void {
} }
export function normalize(vector: Vector): void { export function normalize(vector: Vector): void {
const magnitude = Math.sqrt(vector.x * vector.x + vector.y * vector.y); const inv = 1.0 / Math.sqrt(vector.x * vector.x + vector.y * vector.y);
vector.x *= inv;
if (magnitude > 0) { vector.y *= inv;
const scalar = 1 / magnitude;
vector.x *= scalar;
vector.y *= scalar;
}
} }
export function isZero(vector: Vector): boolean { export function isZero(vector: Vector): boolean {
+2 -2
View File
@@ -12,7 +12,7 @@ import {
createVector, createVector,
getDistance, getDistance,
scale, scale,
setDistanceNormal, setUnit,
type Vector, type Vector,
} from "#/engine/Vector.ts"; } from "#/engine/Vector.ts";
@@ -104,7 +104,7 @@ function hookEdge<T extends PhysicsPartial>([a, b]: Edge<T>): void {
const stiffness = 0.05; const stiffness = 0.05;
const direction = createVector(); const direction = createVector();
setDistanceNormal(direction, a.position, b.position); setUnit(direction, a.position, b.position);
const distance = getDistance(a.position, b.position); const distance = getDistance(a.position, b.position);
const magnitude = (distance - restLength) * stiffness + Number.EPSILON; const magnitude = (distance - restLength) * stiffness + Number.EPSILON;
+37 -9
View File
@@ -1,4 +1,7 @@
import type { Circle } from "#/engine/Circle.ts"; import type { Circle } from "#/engine/Circle.ts";
import type MapProxy from "#/engine/lib/MapProxy.ts";
import type { Polygon } from "#/engine/Polygon.ts";
import type { Rect } from "#/engine/Rect.ts";
import $ from "#/engine/Scene.ts"; import $ from "#/engine/Scene.ts";
import type { Vector } from "#/engine/Vector.ts"; import type { Vector } from "#/engine/Vector.ts";
@@ -8,26 +11,51 @@ const POLYGON = 2;
type Shape = 0 | 1 | 2; type Shape = 0 | 1 | 2;
export type Collider<T> = { export type Collider = {
shape: Shape; shape: Shape;
body: T;
}; };
export type Collision = {}; export type Collision = {
id: string;
};
export function moveAndCollide<T>( const collisions = new Map<string, Collision>();
collider: Collider<T>,
function check(
id: string,
collider: Collider,
position: Vector,
colliders: MapProxy<string, Collider>,
): string | undefined {
for (const [oid, other] of colliders.entries()) {
if (oid !== id && other) {
return oid;
}
}
}
export function moveAndCollide(
id: string,
velocity: Vector, velocity: Vector,
delta: number, delta: number,
): Collision { ): Collision | undefined {
return {}; return collisions.get(id);
} }
export function processPhysics( export function processPhysics(
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
delta: number, delta: number,
): void { ): void {
for (const [id, collider] of $<Collider<unknown>>("collider")!.entries()) { const colliders = $<Collider>("collider")!;
const position = $<Vector>("position")!.get(id); const positions = $<Vector>("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);
}
} }
} }
+2 -3
View File
@@ -29,7 +29,6 @@ const process = defineEntity("hero", {
process((id, delta) => { process((id, delta) => {
const position = $<Vector>("position").get(id)!.value; const position = $<Vector>("position").get(id)!.value;
const velocity = $<Vector>("velocity").get(id)!.value; const velocity = $<Vector>("velocity").get(id)!.value;
const collider = $<Collider>("collider").get(id)!.value;
if (pointer.isDown) { if (pointer.isDown) {
position.x = pointer.position.x; position.x = pointer.position.x;
@@ -47,6 +46,6 @@ process((id, delta) => {
velocity.x = 0; velocity.x = 0;
velocity.y = 0; velocity.y = 0;
const collision = moveAndCollide(collider, velocity, delta); const collision = moveAndCollide(id, velocity, delta);
console.log(collision); // console.log(collision);
}); });
+2
View File
@@ -1,3 +1,4 @@
import { createCircle } from "#/engine/Circle.ts";
import { defineEntity } from "#/engine/Entity.ts"; import { defineEntity } from "#/engine/Entity.ts";
import { import {
createSprite, createSprite,
@@ -13,4 +14,5 @@ defineEntity("portal", {
position: createVector(), position: createVector(),
sprite: createSprite(portalSrc), sprite: createSprite(portalSrc),
animation: createSpriteAnimation(400, 0), animation: createSpriteAnimation(400, 0),
collider: createCircle(createVector(), 8),
}); });