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 = {
position: Vector;
@@ -24,9 +24,9 @@ export function updateAxes({ points, axes }: Polygon): void {
for (let i = 0; i < cap; i++) {
const pj = points[i + 1];
setEdgeNormal(axes[i], pi, pj);
setUnitNormal(axes[i], 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;
}
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 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) {
normal.x = dx / distance;
normal.y = dy / distance;
}
unit.x = dx * inv;
unit.y = dy * inv;
}
export function setEdgeNormal(normal: Vector, a: Vector, b: Vector): void {
const nx = -(b.y - a.y);
export function setUnitNormal(unit: Vector, a: Vector, b: Vector): void {
const nx = a.y - b.y;
const ny = b.x - a.x;
const inv = 1.0 / Math.sqrt(nx * nx + ny * ny);
normal.x = nx * inv;
normal.y = ny * inv;
unit.x = nx * inv;
unit.y = ny * inv;
}
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 {
const magnitude = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
if (magnitude > 0) {
const scalar = 1 / magnitude;
vector.x *= scalar;
vector.y *= scalar;
}
const inv = 1.0 / Math.sqrt(vector.x * vector.x + vector.y * vector.y);
vector.x *= inv;
vector.y *= inv;
}
export function isZero(vector: Vector): boolean {
+2 -2
View File
@@ -12,7 +12,7 @@ import {
createVector,
getDistance,
scale,
setDistanceNormal,
setUnit,
type Vector,
} from "#/engine/Vector.ts";
@@ -104,7 +104,7 @@ function hookEdge<T extends PhysicsPartial>([a, b]: Edge<T>): void {
const stiffness = 0.05;
const direction = createVector();
setDistanceNormal(direction, a.position, b.position);
setUnit(direction, a.position, b.position);
const distance = getDistance(a.position, b.position);
const magnitude = (distance - restLength) * stiffness + Number.EPSILON;
+37 -9
View File
@@ -1,4 +1,7 @@
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 type { Vector } from "#/engine/Vector.ts";
@@ -8,26 +11,51 @@ const POLYGON = 2;
type Shape = 0 | 1 | 2;
export type Collider<T> = {
export type Collider = {
shape: Shape;
body: T;
};
export type Collision = {};
export type Collision = {
id: string;
};
export function moveAndCollide<T>(
collider: Collider<T>,
const collisions = new Map<string, Collision>();
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,
delta: number,
): Collision {
return {};
): Collision | undefined {
return collisions.get(id);
}
export function processPhysics(
ctx: CanvasRenderingContext2D,
delta: number,
): void {
for (const [id, collider] of $<Collider<unknown>>("collider")!.entries()) {
const position = $<Vector>("position")!.get(id);
const colliders = $<Collider>("collider")!;
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) => {
const position = $<Vector>("position").get(id)!.value;
const velocity = $<Vector>("velocity").get(id)!.value;
const collider = $<Collider>("collider").get(id)!.value;
if (pointer.isDown) {
position.x = pointer.position.x;
@@ -47,6 +46,6 @@ process((id, delta) => {
velocity.x = 0;
velocity.y = 0;
const collision = moveAndCollide(collider, velocity, delta);
console.log(collision);
const collision = moveAndCollide(id, velocity, delta);
// console.log(collision);
});
+2
View File
@@ -1,3 +1,4 @@
import { createCircle } from "#/engine/Circle.ts";
import { defineEntity } from "#/engine/Entity.ts";
import {
createSprite,
@@ -13,4 +14,5 @@ defineEntity("portal", {
position: createVector(),
sprite: createSprite(portalSrc),
animation: createSpriteAnimation(400, 0),
collider: createCircle(createVector(), 8),
});