samengine 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +145 -0
  2. package/dist/build/index.d.ts +1 -0
  3. package/dist/build/index.js +2 -0
  4. package/dist/build/version.d.ts +1 -0
  5. package/dist/build/version.js +4 -0
  6. package/dist/core.d.ts +3 -0
  7. package/dist/core.js +13 -0
  8. package/dist/html.d.ts +18 -0
  9. package/dist/html.js +66 -0
  10. package/dist/index.d.ts +10 -0
  11. package/dist/index.js +14 -0
  12. package/dist/input.d.ts +17 -0
  13. package/dist/input.js +111 -0
  14. package/dist/keys.d.ts +52 -0
  15. package/dist/keys.js +55 -0
  16. package/dist/logger.d.ts +1 -0
  17. package/dist/logger.js +16 -0
  18. package/dist/renderer.d.ts +13 -0
  19. package/dist/renderer.js +81 -0
  20. package/dist/save.d.ts +5 -0
  21. package/dist/save.js +27 -0
  22. package/dist/sound/audioplayer.d.ts +17 -0
  23. package/dist/sound/audioplayer.js +84 -0
  24. package/dist/sound/index.d.ts +1 -0
  25. package/dist/sound/index.js +2 -0
  26. package/dist/texture.d.ts +37 -0
  27. package/dist/texture.js +171 -0
  28. package/dist/types/circle.d.ts +14 -0
  29. package/dist/types/circle.js +38 -0
  30. package/dist/types/color.d.ts +9 -0
  31. package/dist/types/color.js +27 -0
  32. package/dist/types/index.d.ts +6 -0
  33. package/dist/types/index.js +13 -0
  34. package/dist/types/rectangle.d.ts +16 -0
  35. package/dist/types/rectangle.js +41 -0
  36. package/dist/types/triangle.d.ts +16 -0
  37. package/dist/types/triangle.js +49 -0
  38. package/dist/types/vector2d.d.ts +14 -0
  39. package/dist/types/vector2d.js +72 -0
  40. package/dist/types/vector3d.d.ts +16 -0
  41. package/dist/types/vector3d.js +86 -0
  42. package/dist/utils/index.d.ts +4 -0
  43. package/dist/utils/index.js +6 -0
  44. package/dist/utils/jsonc-parser.d.ts +4 -0
  45. package/dist/utils/jsonc-parser.js +166 -0
  46. package/dist/utils/markdown.d.ts +41 -0
  47. package/dist/utils/markdown.js +657 -0
  48. package/dist/utils/math.d.ts +3 -0
  49. package/dist/utils/math.js +12 -0
  50. package/package.json +41 -0
@@ -0,0 +1,17 @@
1
+ export declare class SoundSystem {
2
+ private ctx;
3
+ private bufferCache;
4
+ private activeSources;
5
+ private masterGain;
6
+ constructor();
7
+ load(url: string): Promise<AudioBuffer>;
8
+ play(url: string, options?: {
9
+ volume?: number;
10
+ loop?: boolean;
11
+ playbackRate?: number;
12
+ }): Promise<AudioBufferSourceNode>;
13
+ stopAll(): void;
14
+ setVolume(v: number): void;
15
+ resume(): Promise<void>;
16
+ pause(): Promise<void>;
17
+ }
@@ -0,0 +1,84 @@
1
+ export class SoundSystem {
2
+ constructor() {
3
+ this.bufferCache = new Map();
4
+ this.activeSources = new Set();
5
+ // 👉 zuerst globalen nehmen, sonst neuen erstellen
6
+ this.ctx = window.__audioCtx ?? new AudioContext();
7
+ this.masterGain = this.ctx.createGain();
8
+ this.masterGain.gain.value = 1;
9
+ this.masterGain.connect(this.ctx.destination);
10
+ }
11
+ // ================= LOAD =================
12
+ async load(url) {
13
+ if (this.bufferCache.has(url)) {
14
+ return this.bufferCache.get(url);
15
+ }
16
+ let arrayBuffer;
17
+ // Check if resource is embedded in single-file export
18
+ const loadResource = window.__loadResource;
19
+ if (loadResource) {
20
+ const dataUri = loadResource(url);
21
+ if (dataUri) {
22
+ // Convert data URI to ArrayBuffer
23
+ const response = await fetch(dataUri);
24
+ arrayBuffer = await response.arrayBuffer();
25
+ }
26
+ else {
27
+ // Fallback to fetch if resource not found
28
+ const res = await fetch(url);
29
+ arrayBuffer = await res.arrayBuffer();
30
+ }
31
+ }
32
+ else {
33
+ // Normal fetch for multi-file export
34
+ const res = await fetch(url);
35
+ arrayBuffer = await res.arrayBuffer();
36
+ }
37
+ const buffer = await this.ctx.decodeAudioData(arrayBuffer);
38
+ this.bufferCache.set(url, buffer);
39
+ return buffer;
40
+ }
41
+ // ================= PLAY =================
42
+ async play(url, options = {}) {
43
+ const buffer = await this.load(url);
44
+ const source = this.ctx.createBufferSource();
45
+ source.buffer = buffer;
46
+ source.loop = options.loop ?? false;
47
+ source.playbackRate.value = options.playbackRate ?? 1;
48
+ const gain = this.ctx.createGain();
49
+ gain.gain.value = options.volume ?? 1;
50
+ source.connect(gain);
51
+ gain.connect(this.masterGain);
52
+ source.start(0);
53
+ this.activeSources.add(source);
54
+ source.onended = () => {
55
+ this.activeSources.delete(source);
56
+ };
57
+ return source;
58
+ }
59
+ // ================= STOP =================
60
+ stopAll() {
61
+ for (const s of this.activeSources) {
62
+ try {
63
+ s.stop();
64
+ }
65
+ catch { }
66
+ }
67
+ this.activeSources.clear();
68
+ }
69
+ // ================= GLOBAL VOLUME =================
70
+ setVolume(v) {
71
+ this.masterGain.gain.value = v;
72
+ }
73
+ // ================= CONTEXT CONTROL =================
74
+ async resume() {
75
+ if (this.ctx.state === "suspended") {
76
+ await this.ctx.resume();
77
+ }
78
+ }
79
+ async pause() {
80
+ if (this.ctx.state === "running") {
81
+ await this.ctx.suspend();
82
+ }
83
+ }
84
+ }
@@ -0,0 +1 @@
1
+ export { SoundSystem } from "./audioplayer.js";
@@ -0,0 +1,2 @@
1
+ // Sound Part
2
+ export { SoundSystem } from "./audioplayer.js";
@@ -0,0 +1,37 @@
1
+ import { Rect } from "./types/rectangle.js";
2
+ export type Texture = HTMLImageElement | undefined;
3
+ export type DrawOptions = {
4
+ width?: number;
5
+ height?: number;
6
+ rotation?: number;
7
+ flipX?: boolean;
8
+ flipY?: boolean;
9
+ scale?: number;
10
+ };
11
+ export declare function loadTextureAsync(src: string): Promise<HTMLImageElement>;
12
+ export declare function getTexture(src: string): Texture;
13
+ export declare function drawTexture(ctx: CanvasRenderingContext2D, texture: Texture, x: number, y: number, options?: DrawOptions): void;
14
+ export type TextureAtlas = {
15
+ image: HTMLImageElement;
16
+ frames: Record<string, Rect>;
17
+ };
18
+ export declare function loadAtlas(imageSrc: string, dataSrc: string): Promise<TextureAtlas>;
19
+ export declare function drawAtlasFrame(ctx: CanvasRenderingContext2D, atlas: TextureAtlas, frameName: string, x: number, y: number, options?: DrawOptions): void;
20
+ export declare class AnimationPlayer {
21
+ animation: Animation;
22
+ private time;
23
+ private currentFrameIndex;
24
+ private finished;
25
+ constructor(animation: Animation);
26
+ update(deltaTime: number): void;
27
+ getCurrentFrame(): string;
28
+ reset(): void;
29
+ isFinished(): boolean;
30
+ }
31
+ export type Animation = {
32
+ frames: string[];
33
+ fps: number;
34
+ loop?: boolean;
35
+ };
36
+ export declare function drawAnimation(ctx: CanvasRenderingContext2D, atlas: TextureAtlas, player: AnimationPlayer, x: number, y: number, options?: DrawOptions): void;
37
+ export declare function getFlipFromDirection(dir: number): boolean;
@@ -0,0 +1,171 @@
1
+ import { dlog } from "./logger.js";
2
+ const textures = {};
3
+ function getresourcepath(path) {
4
+ return "resources/" + path;
5
+ }
6
+ // Function to load a Texture Async
7
+ export function loadTextureAsync(src) {
8
+ return new Promise((resolve, reject) => {
9
+ // Wenn schon geladen
10
+ const existing = getTexture(src);
11
+ if (existing)
12
+ return resolve(existing);
13
+ const img = new Image();
14
+ // 🔹 Hier Pfad modifizieren, z.B. Prefix hinzufügen
15
+ let finalSrc = getresourcepath(src);
16
+ const cacheKey = finalSrc;
17
+ // Check if resources are embedded (single file build)
18
+ const embeddedResources = window.__resources;
19
+ if (embeddedResources && embeddedResources[src]) {
20
+ // Use embedded resource (data URI)
21
+ finalSrc = embeddedResources[src];
22
+ }
23
+ img.onload = () => {
24
+ // Cache speichern - always use the same cache key for consistency
25
+ textures[cacheKey] = img;
26
+ resolve(img);
27
+ };
28
+ img.onerror = () => {
29
+ const msg = `❌ Failed to load texture: ${finalSrc}`;
30
+ console.error(msg);
31
+ reject(new Error(msg));
32
+ };
33
+ // 🔹 Bild laden mit finalem Pfad
34
+ img.src = finalSrc;
35
+ });
36
+ }
37
+ // Function to get the Texture
38
+ export function getTexture(src) {
39
+ return textures[getresourcepath(src)];
40
+ }
41
+ // Function to draw a texture to the Screen
42
+ export function drawTexture(ctx, texture, x, y, options = {}) {
43
+ const { width, height, rotation = 0, flipX = false, flipY = false, scale = 1 } = options;
44
+ if (!texture) {
45
+ dlog("Texture not found");
46
+ ctx.fillStyle = "magenta";
47
+ ctx.fillRect(x, y, (width ?? 32) * scale, (height ?? 32) * scale);
48
+ return;
49
+ }
50
+ const w = (width ?? texture.width) * scale; // 🔹 scale anwenden
51
+ const h = (height ?? texture.height) * scale; // 🔹 scale anwenden
52
+ ctx.save();
53
+ const cx = x + w / 2;
54
+ const cy = y + h / 2;
55
+ ctx.translate(cx, cy);
56
+ ctx.rotate(rotation);
57
+ ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
58
+ ctx.drawImage(texture, -w / 2, -h / 2, w, h);
59
+ ctx.restore();
60
+ }
61
+ // Funtion to load an Atlas
62
+ //
63
+ // JSON Format for the LoadAtlas Function
64
+ //
65
+ // {
66
+ // "frames": {
67
+ // "player_idle_0": { "x": 0, "y": 0, "w": 32, "h": 32 },
68
+ // "player_idle_1": { "x": 32, "y": 0, "w": 32, "h": 32 }
69
+ // }
70
+ // }
71
+ //
72
+ export async function loadAtlas(imageSrc, dataSrc) {
73
+ const [image, data] = await Promise.all([
74
+ loadTextureAsync(imageSrc),
75
+ fetch(getresourcepath(dataSrc)).then(r => r.json())
76
+ ]);
77
+ return {
78
+ image,
79
+ frames: data.frames
80
+ };
81
+ }
82
+ export function drawAtlasFrame(ctx, atlas, frameName, x, y, options = {}) {
83
+ const { width, height, rotation = 0, flipX = false, flipY = false, scale = 1 } = options;
84
+ const frame = atlas.frames[frameName];
85
+ if (!frame) {
86
+ dlog(`Frame not found: ${frameName}`);
87
+ return;
88
+ }
89
+ const w = (width ?? frame.width) * scale;
90
+ const h = (height ?? frame.height) * scale;
91
+ ctx.save();
92
+ const cx = x + w / 2;
93
+ const cy = y + h / 2;
94
+ ctx.translate(cx, cy);
95
+ ctx.rotate(rotation);
96
+ ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);
97
+ ctx.drawImage(atlas.image, frame.x, frame.y, frame.width, frame.height, -w / 2, -h / 2, w, h);
98
+ ctx.restore();
99
+ }
100
+ //
101
+ //
102
+ // Animation Player
103
+ //
104
+ //
105
+ //
106
+ // // Define Animation
107
+ // const walkAnimation: Animation = {
108
+ // frames: ["walk_0", "walk_1", "walk_2", "walk_3"],
109
+ // fps: 8,
110
+ // loop: true
111
+ // };
112
+ //
113
+ // const player = new AnimationPlayer(walkAnimation);
114
+ //
115
+ // // Game Loop
116
+ // function update(dt: number) {
117
+ // player.update(dt);
118
+ // }
119
+ //
120
+ // function render(ctx: CanvasRenderingContext2D) {
121
+ // drawAnimation(ctx, atlas, player, 100, 100, 64, 64);
122
+ // }
123
+ //
124
+ //
125
+ // Animation Player Class
126
+ export class AnimationPlayer {
127
+ // Konstruktor Function
128
+ constructor(animation) {
129
+ this.animation = animation;
130
+ this.time = 0;
131
+ this.currentFrameIndex = 0;
132
+ this.finished = false;
133
+ }
134
+ update(deltaTime) {
135
+ if (this.finished)
136
+ return;
137
+ this.time += deltaTime;
138
+ const frameDuration = 1 / this.animation.fps;
139
+ while (this.time >= frameDuration) {
140
+ this.time -= frameDuration;
141
+ this.currentFrameIndex++;
142
+ if (this.currentFrameIndex >= this.animation.frames.length) {
143
+ if (this.animation.loop) {
144
+ this.currentFrameIndex = 0;
145
+ }
146
+ else {
147
+ this.currentFrameIndex = this.animation.frames.length - 1;
148
+ this.finished = true;
149
+ }
150
+ }
151
+ }
152
+ }
153
+ getCurrentFrame() {
154
+ return this.animation.frames[this.currentFrameIndex];
155
+ }
156
+ reset() {
157
+ this.time = 0;
158
+ this.currentFrameIndex = 0;
159
+ this.finished = false;
160
+ }
161
+ isFinished() {
162
+ return this.finished;
163
+ }
164
+ }
165
+ export function drawAnimation(ctx, atlas, player, x, y, options = {}) {
166
+ const frame = player.getCurrentFrame();
167
+ drawAtlasFrame(ctx, atlas, frame, x, y, options);
168
+ }
169
+ export function getFlipFromDirection(dir) {
170
+ return dir < 0; // links = true
171
+ }
@@ -0,0 +1,14 @@
1
+ import { Mouse } from "../input.js";
2
+ import { type Vector2d } from "./vector2d.js";
3
+ export type Circle = {
4
+ x: number;
5
+ y: number;
6
+ radius: number;
7
+ };
8
+ export declare function makeCircle(x: number, y: number, radius: number): Circle;
9
+ export declare function centerCircle(circle: Circle): Vector2d;
10
+ export declare function isPointInCircle(x: number, y: number, circle: Circle): boolean;
11
+ export declare function isMouseInCircle(mouse: Mouse, circle: Circle): boolean;
12
+ export declare function isCircleClicked(mouse: Mouse, circle: Circle): boolean;
13
+ export declare function isCircleColliding(circle1: Circle, circle2: Circle): boolean;
14
+ export declare function getCircleDistance(circle1: Circle, circle2: Circle): number;
@@ -0,0 +1,38 @@
1
+ // Circle Type for Hitboxes
2
+ // Function to create an Object of Type Circle
3
+ export function makeCircle(x, y, radius) {
4
+ return {
5
+ x: x,
6
+ y: y,
7
+ radius: radius,
8
+ };
9
+ }
10
+ // Function to get the Center of the Circle as Vector2d
11
+ export function centerCircle(circle) {
12
+ return { x: circle.x, y: circle.y };
13
+ }
14
+ // Check if a Point is in the Circle
15
+ export function isPointInCircle(x, y, circle) {
16
+ const distance = Math.sqrt((x - circle.x) * (x - circle.x) +
17
+ (y - circle.y) * (y - circle.y));
18
+ return distance <= circle.radius;
19
+ }
20
+ // Check if Mouse is in the Circle
21
+ export function isMouseInCircle(mouse, circle) {
22
+ return isPointInCircle(mouse.x, mouse.y, circle);
23
+ }
24
+ // Function to check if a Circle is clicked
25
+ export function isCircleClicked(mouse, circle) {
26
+ return isMouseInCircle(mouse, circle) && mouse.justPressed;
27
+ }
28
+ // Check if two Circles collide
29
+ export function isCircleColliding(circle1, circle2) {
30
+ const distance = Math.sqrt((circle1.x - circle2.x) * (circle1.x - circle2.x) +
31
+ (circle1.y - circle2.y) * (circle1.y - circle2.y));
32
+ return distance <= (circle1.radius + circle2.radius);
33
+ }
34
+ // Check if Circle collides with Rectangle (imported from rectangle.ts would cause circular dependency)
35
+ export function getCircleDistance(circle1, circle2) {
36
+ return Math.sqrt((circle1.x - circle2.x) * (circle1.x - circle2.x) +
37
+ (circle1.y - circle2.y) * (circle1.y - circle2.y));
38
+ }
@@ -0,0 +1,9 @@
1
+ export type Color = {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ a?: number;
6
+ };
7
+ export declare function makeColor(r: number, g: number, b: number, a?: number): Color;
8
+ export declare function invertcolor(color: Color): Color;
9
+ export declare function invertHexColor(hex: string): string;
@@ -0,0 +1,27 @@
1
+ // Function to create an Object of Type Color
2
+ export function makeColor(r, g, b, a) {
3
+ return {
4
+ r: r,
5
+ g: g,
6
+ b: b,
7
+ a: a
8
+ };
9
+ }
10
+ export function invertcolor(color) {
11
+ return {
12
+ r: 255 - color.r,
13
+ g: 255 - color.g,
14
+ b: 255 - color.b,
15
+ ...(color.a !== undefined ? { a: color.a } : {}) // optional alpha behalten
16
+ };
17
+ }
18
+ export function invertHexColor(hex) {
19
+ // Entferne das führende #
20
+ const cleanHex = hex.replace('#', '');
21
+ // Wandeln in R, G, B
22
+ const r = 255 - parseInt(cleanHex.slice(0, 2), 16);
23
+ const g = 255 - parseInt(cleanHex.slice(2, 4), 16);
24
+ const b = 255 - parseInt(cleanHex.slice(4, 6), 16);
25
+ // Zurück in Hex-String
26
+ return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
27
+ }
@@ -0,0 +1,6 @@
1
+ export { type Vector2d, makeVector2d, add2d, subtract2d, length2d, normalize2d, dot2d, distance2d, clamp2d, lerp2d, map2d } from "./vector2d.js";
2
+ export { type Vector3d, makeVector3d, add3d, subtract3d, length3d, normalize3d, dot3d, crossprodukt3d, distance3d, clamp3d, lerp3d, map3d } from "./vector3d.js";
3
+ export { type Color, makeColor, invertcolor, invertHexColor } from "./color.js";
4
+ export { type Rect, makeRect, centerRectX, centerRectY, centerRect, isPointInRect, isMouseInRect, isRectClicked } from "./rectangle.js";
5
+ export { type Circle, makeCircle, centerCircle, isPointInCircle, isMouseInCircle, isCircleClicked, isCircleColliding, getCircleDistance } from "./circle.js";
6
+ export { type Triangle, makeTriangle, centerTriangle, isPointInTriangle, isMouseInTriangle, isTriangleClicked, getTrianglePerimeter, } from "./triangle.js";
@@ -0,0 +1,13 @@
1
+ // Types Export
2
+ // Vector 2D
3
+ export { makeVector2d, add2d, subtract2d, length2d, normalize2d, dot2d, distance2d, clamp2d, lerp2d, map2d } from "./vector2d.js";
4
+ // Vector 3D
5
+ export { makeVector3d, add3d, subtract3d, length3d, normalize3d, dot3d, crossprodukt3d, distance3d, clamp3d, lerp3d, map3d } from "./vector3d.js";
6
+ // Color Type
7
+ export { makeColor, invertcolor, invertHexColor } from "./color.js";
8
+ // Retangle Type
9
+ export { makeRect, centerRectX, centerRectY, centerRect, isPointInRect, isMouseInRect, isRectClicked } from "./rectangle.js";
10
+ // Circle Type
11
+ export { makeCircle, centerCircle, isPointInCircle, isMouseInCircle, isCircleClicked, isCircleColliding, getCircleDistance } from "./circle.js";
12
+ // Triangle Type
13
+ export { makeTriangle, centerTriangle, isPointInTriangle, isMouseInTriangle, isTriangleClicked, getTrianglePerimeter, } from "./triangle.js";
@@ -0,0 +1,16 @@
1
+ import { type Mouse } from "../input.js";
2
+ import { type Vector2d } from "./vector2d.js";
3
+ export type Rect = {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ borderRadius?: number;
9
+ };
10
+ export declare function makeRect(x: number, y: number, width: number, height: number, borderRadius?: number): Rect;
11
+ export declare function centerRectX(rect: Rect): number;
12
+ export declare function centerRectY(rect: Rect): number;
13
+ export declare function centerRect(rect: Rect): Vector2d;
14
+ export declare function isPointInRect(x: number, y: number, rect: Rect): boolean;
15
+ export declare function isMouseInRect(mouse: Mouse, rect: Rect): boolean;
16
+ export declare function isRectClicked(mouse: Mouse, rect: Rect): boolean;
@@ -0,0 +1,41 @@
1
+ // Rectangle Type for Hitboxes
2
+ // Function to create an Object of Type rect
3
+ export function makeRect(x, y, width, height, borderRadius = 0) {
4
+ return {
5
+ x: x,
6
+ y: y,
7
+ height: height,
8
+ width: width,
9
+ borderRadius: borderRadius
10
+ };
11
+ }
12
+ // Function to get the Center of the Width of the Object
13
+ export function centerRectX(rect) {
14
+ return (rect.x + (rect.width / 2));
15
+ }
16
+ // Function to get the Center of the Height of the Object
17
+ export function centerRectY(rect) {
18
+ return (rect.y + (rect.height / 2));
19
+ }
20
+ // Get the Center of a Rectangle
21
+ export function centerRect(rect) {
22
+ let vector = { x: centerRectX(rect), y: centerRectY(rect) };
23
+ return vector;
24
+ }
25
+ // Check if a Point in the Rectangle
26
+ export function isPointInRect(x, y, rect) {
27
+ return (x >= rect.x &&
28
+ x <= rect.x + rect.width &&
29
+ y >= rect.y &&
30
+ y <= rect.y + rect.height);
31
+ }
32
+ export function isMouseInRect(mouse, rect) {
33
+ return (mouse.x >= rect.x &&
34
+ mouse.x <= rect.x + rect.width &&
35
+ mouse.y >= rect.y &&
36
+ mouse.y <= rect.y + rect.height);
37
+ }
38
+ // Function to check if a Rectangle is clicked
39
+ export function isRectClicked(mouse, rect) {
40
+ return isMouseInRect(mouse, rect) && mouse.justPressed;
41
+ }
@@ -0,0 +1,16 @@
1
+ import { Mouse } from "../input.js";
2
+ import { type Vector2d } from "./vector2d.js";
3
+ export type Triangle = {
4
+ x1: number;
5
+ y1: number;
6
+ x2: number;
7
+ y2: number;
8
+ x3: number;
9
+ y3: number;
10
+ };
11
+ export declare function makeTriangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): Triangle;
12
+ export declare function centerTriangle(triangle: Triangle): Vector2d;
13
+ export declare function isPointInTriangle(x: number, y: number, triangle: Triangle): boolean;
14
+ export declare function isMouseInTriangle(mouse: Mouse, triangle: Triangle): boolean;
15
+ export declare function isTriangleClicked(mouse: Mouse, triangle: Triangle): boolean;
16
+ export declare function getTrianglePerimeter(triangle: Triangle): number;
@@ -0,0 +1,49 @@
1
+ // Triangle Type for Hitboxes
2
+ // Function to create an Object of Type triangle
3
+ export function makeTriangle(x1, y1, x2, y2, x3, y3) {
4
+ return {
5
+ x1: x1,
6
+ x2: x2,
7
+ x3: x3,
8
+ y1: y1,
9
+ y2: y2,
10
+ y3: y3,
11
+ };
12
+ }
13
+ // Helper function to calculate the area of a triangle (used for point-in-triangle)
14
+ function getTriangleArea(x1, y1, x2, y2, x3, y3) {
15
+ return Math.abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0);
16
+ }
17
+ // Function to get the Center of the Triangle
18
+ export function centerTriangle(triangle) {
19
+ return {
20
+ x: (triangle.x1 + triangle.x2 + triangle.x3) / 3,
21
+ y: (triangle.y1 + triangle.y2 + triangle.y3) / 3
22
+ };
23
+ }
24
+ // Check if a Point is in the Triangle using barycentric coordinates
25
+ export function isPointInTriangle(x, y, triangle) {
26
+ const areaTriangle = getTriangleArea(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3);
27
+ const area1 = getTriangleArea(x, y, triangle.x2, triangle.y2, triangle.x3, triangle.y3);
28
+ const area2 = getTriangleArea(triangle.x1, triangle.y1, x, y, triangle.x3, triangle.y3);
29
+ const area3 = getTriangleArea(triangle.x1, triangle.y1, triangle.x2, triangle.y2, x, y);
30
+ return Math.abs(areaTriangle - (area1 + area2 + area3)) < 0.01;
31
+ }
32
+ // Check if Mouse is in the Triangle
33
+ export function isMouseInTriangle(mouse, triangle) {
34
+ return isPointInTriangle(mouse.x, mouse.y, triangle);
35
+ }
36
+ // Function to check if a Triangle is clicked
37
+ export function isTriangleClicked(mouse, triangle) {
38
+ return isMouseInTriangle(mouse, triangle) && mouse.justPressed;
39
+ }
40
+ // Get the Perimeter of the Triangle
41
+ export function getTrianglePerimeter(triangle) {
42
+ const side1 = Math.sqrt((triangle.x2 - triangle.x1) * (triangle.x2 - triangle.x1) +
43
+ (triangle.y2 - triangle.y1) * (triangle.y2 - triangle.y1));
44
+ const side2 = Math.sqrt((triangle.x3 - triangle.x2) * (triangle.x3 - triangle.x2) +
45
+ (triangle.y3 - triangle.y2) * (triangle.y3 - triangle.y2));
46
+ const side3 = Math.sqrt((triangle.x1 - triangle.x3) * (triangle.x1 - triangle.x3) +
47
+ (triangle.y1 - triangle.y3) * (triangle.y1 - triangle.y3));
48
+ return side1 + side2 + side3;
49
+ }
@@ -0,0 +1,14 @@
1
+ export type Vector2d = {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export declare function makeVector2d(x: number, y: number): Vector2d;
6
+ export declare function add2d(vector1: Vector2d, vector2: Vector2d): Vector2d;
7
+ export declare function subtract2d(vector1: Vector2d, vector2: Vector2d): Vector2d;
8
+ export declare function length2d(vector: Vector2d): number;
9
+ export declare function normalize2d(vector: Vector2d): Vector2d;
10
+ export declare function dot2d(v1: Vector2d, v2: Vector2d): number;
11
+ export declare function distance2d(v1: Vector2d, v2: Vector2d): number;
12
+ export declare function clamp2d(vector: Vector2d, min: Vector2d, max: Vector2d): Vector2d;
13
+ export declare function lerp2d(start: Vector2d, end: Vector2d, t: Vector2d): Vector2d;
14
+ export declare function map2d(value: Vector2d, inMin: Vector2d, inMax: Vector2d, outMin: Vector2d, outMax: Vector2d): Vector2d;
@@ -0,0 +1,72 @@
1
+ // 2 Dimensional Vector Type
2
+ import { clamp, lerp, map } from "../utils/math.js";
3
+ // Function to create an Object of Type Vector2D
4
+ export function makeVector2d(x, y) {
5
+ return {
6
+ x: x,
7
+ y: y
8
+ };
9
+ }
10
+ // Function to add 2 Vectors together
11
+ export function add2d(vector1, vector2) {
12
+ return {
13
+ x: vector1.x + vector2.x,
14
+ y: vector1.y + vector2.y,
15
+ };
16
+ }
17
+ // Function to subtract 2 Vectors from each other
18
+ export function subtract2d(vector1, vector2) {
19
+ return {
20
+ x: vector1.x - vector2.x,
21
+ y: vector1.y - vector2.y,
22
+ };
23
+ }
24
+ // Function to get the length from an Vector
25
+ export function length2d(vector) {
26
+ let produkt = vector.x * vector.x + vector.y * vector.y;
27
+ let root = Math.sqrt(produkt);
28
+ return root;
29
+ }
30
+ // Function to normalize a Vector 2d
31
+ export function normalize2d(vector) {
32
+ // Check if the Vector is zero because then you dont need to
33
+ // calculate sth
34
+ if (vector.x == 0 && vector.y == 0) {
35
+ return vector;
36
+ }
37
+ let root = length2d(vector);
38
+ vector.x = vector.x / root;
39
+ vector.y = vector.y / root;
40
+ return vector;
41
+ }
42
+ // Function to make scalar produkt from an Vector
43
+ export function dot2d(v1, v2) {
44
+ return (v1.x * v2.x + v1.y * v2.y);
45
+ }
46
+ // crossprodukt (only for 3 Dimensinal Vectors)
47
+ // Calculate the Distance between 2 Vectors
48
+ export function distance2d(v1, v2) {
49
+ let tmp = subtract2d(v1, v2);
50
+ return length2d(tmp);
51
+ }
52
+ // Function to clamp a Vector 2d
53
+ export function clamp2d(vector, min, max) {
54
+ return {
55
+ x: clamp(vector.x, min.x, max.x),
56
+ y: clamp(vector.y, min.y, max.y),
57
+ };
58
+ }
59
+ // Lerp for a 2d Vector
60
+ export function lerp2d(start, end, t) {
61
+ return {
62
+ x: lerp(start.x, end.x, t.x),
63
+ y: lerp(start.y, end.y, t.y),
64
+ };
65
+ }
66
+ // Map Function for a 2d Vector
67
+ export function map2d(value, inMin, inMax, outMin, outMax) {
68
+ return {
69
+ x: map(value.x, inMin.x, inMax.x, outMin.x, outMax.x),
70
+ y: map(value.y, inMin.y, inMax.y, outMin.y, outMax.y),
71
+ };
72
+ }
@@ -0,0 +1,16 @@
1
+ export type Vector3d = {
2
+ x: number;
3
+ y: number;
4
+ z: number;
5
+ };
6
+ export declare function makeVector3d(x: number, y: number, z: number): Vector3d;
7
+ export declare function add3d(vector1: Vector3d, vector2: Vector3d): Vector3d;
8
+ export declare function subtract3d(vector1: Vector3d, vector2: Vector3d): Vector3d;
9
+ export declare function length3d(vector: Vector3d): number;
10
+ export declare function normalize3d(vector: Vector3d): Vector3d;
11
+ export declare function dot3d(v1: Vector3d, v2: Vector3d): number;
12
+ export declare function crossprodukt3d(v1: Vector3d, v2: Vector3d): Vector3d;
13
+ export declare function distance3d(v1: Vector3d, v2: Vector3d): number;
14
+ export declare function clamp3d(vector: Vector3d, min: Vector3d, max: Vector3d): Vector3d;
15
+ export declare function lerp3d(start: Vector3d, end: Vector3d, t: Vector3d): Vector3d;
16
+ export declare function map3d(value: Vector3d, inMin: Vector3d, inMax: Vector3d, outMin: Vector3d, outMax: Vector3d): Vector3d;