slop game oder so

This commit is contained in:
2026-09-24 17:57:54 +02:00
commit 4c997eee21
166 changed files with 14976 additions and 0 deletions
+137
View File
@@ -0,0 +1,137 @@
/**
* Kleine Vektor- und Zahlenhelfer ohne Phaser-Abhängigkeit.
* Vektoren sind einfache Objekte `{x, y}`; die Funktionen verändern ihre Eingaben nie.
* @module logic/math
*/
/** @typedef {{x: number, y: number}} Vec2 */
/**
* Begrenzt `value` auf das Intervall [min, max].
* @param {number} value
* @param {number} min
* @param {number} max
* @returns {number}
*/
export function clamp(value, min, max) {
return Math.min(max, Math.max(min, value));
}
/**
* Lineare Interpolation zwischen `a` und `b`.
* @param {number} a
* @param {number} b
* @param {number} t 0..1
* @returns {number}
*/
export function lerp(a, b, t) {
return a + (b - a) * t;
}
/** @param {number} deg @returns {number} */
export function degToRad(deg) {
return (deg * Math.PI) / 180;
}
/** @param {number} x @param {number} y @returns {Vec2} */
export function vec(x = 0, y = 0) {
return { x, y };
}
/** @param {Vec2} a @param {Vec2} b @returns {Vec2} */
export function add(a, b) {
return { x: a.x + b.x, y: a.y + b.y };
}
/** @param {Vec2} a @param {Vec2} b @returns {Vec2} */
export function sub(a, b) {
return { x: a.x - b.x, y: a.y - b.y };
}
/** @param {Vec2} v @param {number} s @returns {Vec2} */
export function scale(v, s) {
return { x: v.x * s, y: v.y * s };
}
/** @param {Vec2} v @returns {number} */
export function length(v) {
return Math.hypot(v.x, v.y);
}
/** @param {Vec2} a @param {Vec2} b @returns {number} */
export function distance(a, b) {
return Math.hypot(b.x - a.x, b.y - a.y);
}
/**
* Einheitsvektor in Richtung `v`. Der Nullvektor bleibt der Nullvektor –
* so muss kein Aufrufer Division durch null abfangen.
* @param {Vec2} v
* @returns {Vec2}
*/
export function normalize(v) {
const len = length(v);
return len > 0 ? { x: v.x / len, y: v.y / len } : { x: 0, y: 0 };
}
/**
* Kürzt `v` auf höchstens `max` Länge, die Richtung bleibt erhalten.
* @param {Vec2} v
* @param {number} max
* @returns {Vec2}
*/
export function clampLength(v, max) {
const len = length(v);
return len > max && len > 0 ? scale(v, max / len) : { x: v.x, y: v.y };
}
/**
* Dreht `v` um `angle` (Bogenmaß, im Uhrzeigersinn bei y nach unten wie im Canvas).
* @param {Vec2} v
* @param {number} angle
* @returns {Vec2}
*/
export function rotate(v, angle) {
const cos = Math.cos(angle);
const sin = Math.sin(angle);
return { x: v.x * cos - v.y * sin, y: v.x * sin + v.y * cos };
}
/**
* Winkel des Vektors von `from` nach `to` (Bogenmaß, 0 = nach rechts).
* @param {Vec2} from
* @param {Vec2} to
* @returns {number}
*/
export function angleTo(from, to) {
return Math.atan2(to.y - from.y, to.x - from.x);
}
/** @param {number} angle @returns {Vec2} Einheitsvektor für den Winkel. */
export function fromAngle(angle) {
return { x: Math.cos(angle), y: Math.sin(angle) };
}
/**
* Prüft, ob ein Punkt in einem Kreis liegt (inkl. Radius eines Objekts).
* @param {Vec2} point
* @param {Vec2} center
* @param {number} radius
* @param {number} [objectRadius=0] Ausdehnung des Objekts, damit große Gegner am Rand zählen.
* @returns {boolean}
*/
export function inCircle(point, center, radius, objectRadius = 0) {
return distance(point, center) <= radius + objectRadius;
}
/**
* Richtungsvektor aus gedrückten Tasten; diagonal wird normalisiert, damit man
* schräg nicht schneller läuft (klassischer 8-Wege-Fehler).
* @param {{up: boolean, down: boolean, left: boolean, right: boolean}} keys
* @returns {Vec2}
*/
export function directionFromKeys(keys) {
const x = (keys.right ? 1 : 0) - (keys.left ? 1 : 0);
const y = (keys.down ? 1 : 0) - (keys.up ? 1 : 0);
return normalize({ x, y });
}