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
package/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # Samengine 🎮
2
+
3
+ A lightweight, TypeScript-first web game engine framework for building
4
+ 2D games *and maybe 3D Games in the Future*.
5
+
6
+ ## Features
7
+
8
+ - 🎯 Simple game loop management
9
+ - 🎨 Rendering system with text and sprite support
10
+ - ⌨️ Input handling (keyboard & mouse)
11
+ - 📦 TypeScript support out of the box
12
+ - 🛠️ Build tools included
13
+ - 📝 Logging utilities
14
+ - 💾 Save/Load system
15
+
16
+ ## Quick Start
17
+
18
+ ```sh
19
+ # Make sure both of them have the same Version
20
+
21
+ npm init
22
+ npm install samengine
23
+ npm install samengine-build
24
+ npx samengine-build --new
25
+ npx samengine-build
26
+ ```
27
+
28
+ ### Basic Game Loop
29
+
30
+ ```typescript
31
+ import { startEngine, setupInput, dlog, renderText
32
+ } from 'samengine';
33
+
34
+ const { canvas, ctx, applyScaling, virtualWidth, virtualHeight
35
+
36
+ } = createCanvas({ fullscreen: true, scaling: "fit",
37
+ virtualWidth: 1920, virtualHeight: 1080 });
38
+ setupInput(canvas, virtualWidth, virtualHeight);
39
+
40
+ function init() {
41
+ dlog('🎮 Game initialized!');
42
+ }
43
+
44
+ function gameLoop(dt: number) {
45
+ // Clear canvas
46
+ ctx.fillStyle = 'black';
47
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
48
+
49
+ // Your game logic here
50
+ renderText(ctx, `FPS: ${(1 / dt).toFixed(0)}`, 10, 20);
51
+ }
52
+
53
+ startEngine(init, gameLoop);
54
+ ```
55
+
56
+ ## Development & Building
57
+
58
+ ### Using Bun (local development)
59
+
60
+ ```sh
61
+ npx samengine-build # Start Dev Server
62
+ npx samengine-build --release # Production build
63
+ npx samengine-build --new # Create a new project with a
64
+ # simple Snake Clone as Template
65
+ npx samengine-build --new-empty # Create a new empty project
66
+ ```
67
+
68
+ ### Configuration
69
+
70
+ Edit `samengine.config.ts` to configure your game:
71
+
72
+ ```typescript
73
+ import { defineConfig } from 'samengine-build';
74
+
75
+ export function defineConfig() {
76
+ return {
77
+ entryname: 'main',
78
+ outdir: 'dist',
79
+ // ... other config
80
+ };
81
+ }
82
+ ```
83
+
84
+ or
85
+
86
+ ```typescript
87
+ // Project File for the Game
88
+
89
+ import { type buildconfig, new_buildconfig
90
+ } from "samengine-build";
91
+
92
+ export function defineConfig(): buildconfig {
93
+ let config: buildconfig = new_buildconfig();
94
+ return config;
95
+ }
96
+ ```
97
+
98
+ ## API Reference
99
+
100
+ ### Core Engine
101
+ - `startEngine(init, gameLoop)` - Initialize game loop
102
+
103
+ ### Rendering
104
+ - `renderText(ctx, text, x, y, color?, font?)` - Render text
105
+ - `renderBitmapText()` - Render bitmap font text
106
+
107
+ ### Input System
108
+ - `setupInput(canvas, width?, height?)` - Initialize input
109
+ - `getKeyState(key)` - Check key state
110
+ - Mouse state available via input module
111
+
112
+ ### Types
113
+ - `Vector2D` / `Vector3D` - Vector mathematics
114
+ - `Color` - Color management
115
+ - `Rect` - Rectangle collision
116
+ - Math utilities for game logic
117
+
118
+ ### Utilities
119
+ <!-- - `dlog()` - Development logging -->
120
+ - `startEngine()` - Manage game loop
121
+
122
+ ## License
123
+
124
+ MIT
125
+
126
+ ## More Addons in the Game Library
127
+
128
+ - a Full Markdown Parser *(maybe for notes or easy docs, feel free to use)*
129
+ - a JSON with Comments Parser
130
+
131
+ *(I dont now why i added this)*
132
+
133
+ ## More Tools for samengine
134
+
135
+ - [samengine-build](https://www.npmjs.com/package/samengine-build)
136
+ - [samengine-cli](https://www.npmjs.com/package/samengine-cli)
137
+ - [old deprecated npm package](https://www.npmjs.com/package/@shadowdara/webgameengine)
138
+ <!--
139
+
140
+ IDEAS
141
+
142
+ - SVG Integration
143
+ - SVG Generator
144
+
145
+ -->
@@ -0,0 +1 @@
1
+ export { version } from "./version.js";
@@ -0,0 +1,2 @@
1
+ // Export the Version
2
+ export { version } from "./version.js";
@@ -0,0 +1 @@
1
+ export declare function version(): string;
@@ -0,0 +1,4 @@
1
+ // Function to get the Version
2
+ export function version() {
3
+ return "1.6.4";
4
+ }
package/dist/core.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ type GameLoop = (dt: number) => void;
2
+ export declare function startEngine(start: () => void, gameLoop: GameLoop): void;
3
+ export {};
package/dist/core.js ADDED
@@ -0,0 +1,13 @@
1
+ let lastTime = 0;
2
+ let loop;
3
+ export function startEngine(start, gameLoop) {
4
+ loop = gameLoop;
5
+ start();
6
+ requestAnimationFrame(run);
7
+ }
8
+ function run(time) {
9
+ const dt = (time - lastTime) / 1000;
10
+ lastTime = time;
11
+ loop(dt);
12
+ requestAnimationFrame(run);
13
+ }
package/dist/html.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export type CanvasConfig = {
2
+ width?: number;
3
+ height?: number;
4
+ fullscreen?: boolean;
5
+ scaling?: "none" | "fit";
6
+ virtualWidth?: number;
7
+ virtualHeight?: number;
8
+ };
9
+ export declare function createCanvas(config?: CanvasConfig): {
10
+ canvas: HTMLCanvasElement;
11
+ ctx: CanvasRenderingContext2D;
12
+ applyScaling: () => void;
13
+ virtualWidth: number;
14
+ virtualHeight: number;
15
+ };
16
+ export declare function resizeCanvas(canvas: HTMLCanvasElement): void;
17
+ export declare function enableFullscreen(canvas: HTMLCanvasElement): void;
18
+ export declare function setupFullscreenButton(canvas: HTMLCanvasElement): void;
package/dist/html.js ADDED
@@ -0,0 +1,66 @@
1
+ export function createCanvas(config = {}) {
2
+ const canvas = document.createElement("canvas");
3
+ const ctx = canvas.getContext("2d");
4
+ document.body.appendChild(canvas);
5
+ const virtualWidth = config.virtualWidth ?? 800;
6
+ const virtualHeight = config.virtualHeight ?? 800;
7
+ function resize() {
8
+ if (config.fullscreen) {
9
+ canvas.width = window.innerWidth;
10
+ canvas.height = window.innerHeight;
11
+ }
12
+ else {
13
+ canvas.width = config.width ?? 800;
14
+ canvas.height = config.height ?? 800;
15
+ }
16
+ }
17
+ window.addEventListener("resize", resize);
18
+ resize();
19
+ function applyScaling() {
20
+ if (config.scaling === "fit") {
21
+ const scale = Math.min(canvas.width / virtualWidth, canvas.height / virtualHeight);
22
+ const offsetX = (canvas.width - virtualWidth * scale) / 2;
23
+ const offsetY = (canvas.height - virtualHeight * scale) / 2;
24
+ ctx.setTransform(scale, 0, 0, scale, offsetX, offsetY);
25
+ }
26
+ else {
27
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
28
+ }
29
+ }
30
+ return {
31
+ canvas,
32
+ ctx,
33
+ applyScaling,
34
+ virtualWidth,
35
+ virtualHeight,
36
+ };
37
+ }
38
+ export function resizeCanvas(canvas) {
39
+ canvas.width = window.innerWidth;
40
+ canvas.height = window.innerHeight;
41
+ }
42
+ export function enableFullscreen(canvas) {
43
+ window.addEventListener("keydown", (e) => {
44
+ if (e.key === "f") {
45
+ if (!document.fullscreenElement) {
46
+ canvas.requestFullscreen();
47
+ }
48
+ else {
49
+ document.exitFullscreen();
50
+ }
51
+ }
52
+ });
53
+ }
54
+ export function setupFullscreenButton(canvas) {
55
+ const btn = document.getElementById("fullscreenBtn");
56
+ if (!btn)
57
+ return;
58
+ btn.addEventListener("click", () => {
59
+ if (!document.fullscreenElement) {
60
+ canvas.requestFullscreen();
61
+ }
62
+ else {
63
+ document.exitFullscreen();
64
+ }
65
+ });
66
+ }
@@ -0,0 +1,10 @@
1
+ export { startEngine } from "./core.js";
2
+ export { renderText, renderBitmapText, drawRect, drawRectOutline, drawCircle, drawCircleOutline, drawTriangle, drawTriangleOutline, } from "./renderer.js";
3
+ export type { Mouse } from "./input.js";
4
+ export { setupInput, isKeyJustPressed, resetInput, getMouse } from "./input.js";
5
+ export { dlog } from "./logger.js";
6
+ export { saveGame, loadGame, clearSave } from "./save.js";
7
+ export type { Texture, DrawOptions, TextureAtlas, Animation, } from "./texture.js";
8
+ export { loadTextureAsync, getTexture, drawTexture, loadAtlas, drawAtlasFrame, AnimationPlayer, drawAnimation, getFlipFromDirection, } from "./texture.js";
9
+ export { createCanvas, enableFullscreen, setupFullscreenButton } from "./html.js";
10
+ export { Key } from "./keys.js";
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ // Core Engine Exports
2
+ export { startEngine } from "./core.js";
3
+ // Rendering
4
+ export { renderText, renderBitmapText, drawRect, drawRectOutline, drawCircle, drawCircleOutline, drawTriangle, drawTriangleOutline, } from "./renderer.js";
5
+ export { setupInput, isKeyJustPressed, resetInput, getMouse } from "./input.js";
6
+ // Logging
7
+ export { dlog } from "./logger.js";
8
+ // Save System
9
+ export { saveGame, loadGame, clearSave } from "./save.js";
10
+ export { loadTextureAsync, getTexture, drawTexture, loadAtlas, drawAtlasFrame, AnimationPlayer, drawAnimation, getFlipFromDirection, } from "./texture.js";
11
+ // HTML Generation
12
+ export { createCanvas, enableFullscreen, setupFullscreenButton } from "./html.js";
13
+ // Keys Reference
14
+ export { Key } from "./keys.js";
@@ -0,0 +1,17 @@
1
+ export type Mouse = {
2
+ x: number;
3
+ y: number;
4
+ pressed: boolean;
5
+ justPressed: boolean;
6
+ justReleased: boolean;
7
+ rightPressed: boolean;
8
+ rightjustPressed: boolean;
9
+ rightjustReleased: boolean;
10
+ wheelDelta: number;
11
+ };
12
+ export declare function setupInput(canvas: HTMLCanvasElement, vWidth?: number, vHeight?: number): void;
13
+ export declare function isKeyPressed(code: string): boolean;
14
+ export declare function isKeyJustPressed(code: string): boolean;
15
+ export declare function isKeyJustReleased(code: string): boolean;
16
+ export declare function getMouse(): Readonly<Mouse>;
17
+ export declare function resetInput(): void;
package/dist/input.js ADDED
@@ -0,0 +1,111 @@
1
+ const keys = {};
2
+ const mouse = {
3
+ x: 0,
4
+ y: 0,
5
+ // for Left Buttons
6
+ pressed: false,
7
+ justPressed: false,
8
+ justReleased: false,
9
+ // TODO
10
+ // do the same for the right Buttons
11
+ rightPressed: false,
12
+ rightjustPressed: false,
13
+ rightjustReleased: false,
14
+ wheelDelta: 0,
15
+ };
16
+ let canvasRef;
17
+ // 👉 optional: für scaling (kannst du später aus deiner engine holen)
18
+ let virtualWidth = 800;
19
+ let virtualHeight = 800;
20
+ export function setupInput(canvas, vWidth = 800, vHeight = 800) {
21
+ canvasRef = canvas;
22
+ virtualWidth = vWidth;
23
+ virtualHeight = vHeight;
24
+ // ===== KEYBOARD =====
25
+ window.addEventListener("keydown", (e) => {
26
+ if (!keys[e.code]) {
27
+ keys[e.code] = { pressed: false, justPressed: false, justReleased: false };
28
+ }
29
+ const key = keys[e.code];
30
+ if (!key.pressed)
31
+ key.justPressed = true;
32
+ key.pressed = true;
33
+ });
34
+ window.addEventListener("keyup", (e) => {
35
+ if (!keys[e.code]) {
36
+ keys[e.code] = { pressed: false, justPressed: false, justReleased: false };
37
+ }
38
+ const key = keys[e.code];
39
+ key.pressed = false;
40
+ key.justReleased = true;
41
+ });
42
+ // ===== MOUSE =====
43
+ canvas.addEventListener("mousedown", (e) => {
44
+ if (e.button === 0) {
45
+ if (!mouse.pressed)
46
+ mouse.justPressed = true;
47
+ mouse.pressed = true;
48
+ }
49
+ if (e.button === 2) {
50
+ if (!mouse.rightPressed)
51
+ mouse.rightjustPressed = true;
52
+ mouse.rightPressed = true;
53
+ }
54
+ });
55
+ canvas.addEventListener("mouseup", (e) => {
56
+ if (e.button === 0) {
57
+ mouse.pressed = false;
58
+ mouse.justReleased = true;
59
+ }
60
+ if (e.button === 2) {
61
+ mouse.rightPressed = false;
62
+ mouse.rightjustReleased = false;
63
+ }
64
+ });
65
+ // 👉 wichtig: verhindert context menu bei right click
66
+ canvas.addEventListener("contextmenu", (e) => e.preventDefault());
67
+ // ===== MOUSE MOVE (mit scaling fix 🔥) =====
68
+ canvas.addEventListener("mousemove", (e) => {
69
+ const rect = canvas.getBoundingClientRect();
70
+ const scale = Math.min(canvas.width / virtualWidth, canvas.height / virtualHeight);
71
+ const offsetX = (canvas.width - virtualWidth * scale) / 2;
72
+ const offsetY = (canvas.height - virtualHeight * scale) / 2;
73
+ mouse.x = (e.clientX - rect.left - offsetX) / scale;
74
+ mouse.y = (e.clientY - rect.top - offsetY) / scale;
75
+ });
76
+ // ===== MOUSE WHEEL =====
77
+ canvas.addEventListener("wheel", (e) => {
78
+ mouse.wheelDelta = e.deltaY;
79
+ });
80
+ // 👉 Fix: wenn Maus Canvas verlässt
81
+ canvas.addEventListener("mouseleave", () => {
82
+ mouse.pressed = false;
83
+ mouse.rightPressed = false;
84
+ });
85
+ }
86
+ // ===== KEY HELPERS =====
87
+ export function isKeyPressed(code) {
88
+ return keys[code]?.pressed || false;
89
+ }
90
+ export function isKeyJustPressed(code) {
91
+ return keys[code]?.justPressed || false;
92
+ }
93
+ export function isKeyJustReleased(code) {
94
+ return keys[code]?.justReleased || false;
95
+ }
96
+ // ===== MOUSE =====
97
+ export function getMouse() {
98
+ return { ...mouse };
99
+ }
100
+ // ===== RESET =====
101
+ export function resetInput() {
102
+ for (const k in keys) {
103
+ keys[k].justPressed = false;
104
+ keys[k].justReleased = false;
105
+ }
106
+ mouse.justPressed = false;
107
+ mouse.justReleased = false;
108
+ mouse.rightjustPressed = false;
109
+ mouse.rightjustReleased = false;
110
+ mouse.wheelDelta = 0;
111
+ }
package/dist/keys.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ export declare enum Key {
2
+ ArrowUp = "ArrowUp",
3
+ ArrowDown = "ArrowDown",
4
+ ArrowLeft = "ArrowLeft",
5
+ ArrowRight = "ArrowRight",
6
+ Space = "Space",
7
+ Enter = "Enter",
8
+ Escape = "Escape",
9
+ Tab = "Tab",
10
+ ShiftLeft = "ShiftLeft",
11
+ ShiftRight = "ShiftRight",
12
+ ControlLeft = "ControlLeft",
13
+ ControlRight = "ControlRight",
14
+ AltLeft = "AltLeft",
15
+ AltRight = "AltRight",
16
+ KeyA = "KeyA",
17
+ KeyB = "KeyB",
18
+ KeyC = "KeyC",
19
+ KeyD = "KeyD",
20
+ KeyE = "KeyE",
21
+ KeyF = "KeyF",
22
+ KeyG = "KeyG",
23
+ KeyH = "KeyH",
24
+ KeyI = "KeyI",
25
+ KeyJ = "KeyJ",
26
+ KeyK = "KeyK",
27
+ KeyL = "KeyL",
28
+ KeyM = "KeyM",
29
+ KeyN = "KeyN",
30
+ KeyO = "KeyO",
31
+ KeyP = "KeyP",
32
+ KeyQ = "KeyQ",
33
+ KeyR = "KeyR",
34
+ KeyS = "KeyS",
35
+ KeyT = "KeyT",
36
+ KeyU = "KeyU",
37
+ KeyV = "KeyV",
38
+ KeyW = "KeyW",
39
+ KeyX = "KeyX",
40
+ KeyY = "KeyY",
41
+ KeyZ = "KeyZ",
42
+ Digit0 = "Digit0",
43
+ Digit1 = "Digit1",
44
+ Digit2 = "Digit2",
45
+ Digit3 = "Digit3",
46
+ Digit4 = "Digit4",
47
+ Digit5 = "Digit5",
48
+ Digit6 = "Digit6",
49
+ Digit7 = "Digit7",
50
+ Digit8 = "Digit8",
51
+ Digit9 = "Digit9"
52
+ }
package/dist/keys.js ADDED
@@ -0,0 +1,55 @@
1
+ // keys.ts
2
+ // to view the Keys easily with the Autocomplete Feature
3
+ export var Key;
4
+ (function (Key) {
5
+ Key["ArrowUp"] = "ArrowUp";
6
+ Key["ArrowDown"] = "ArrowDown";
7
+ Key["ArrowLeft"] = "ArrowLeft";
8
+ Key["ArrowRight"] = "ArrowRight";
9
+ Key["Space"] = "Space";
10
+ Key["Enter"] = "Enter";
11
+ Key["Escape"] = "Escape";
12
+ Key["Tab"] = "Tab";
13
+ Key["ShiftLeft"] = "ShiftLeft";
14
+ Key["ShiftRight"] = "ShiftRight";
15
+ Key["ControlLeft"] = "ControlLeft";
16
+ Key["ControlRight"] = "ControlRight";
17
+ Key["AltLeft"] = "AltLeft";
18
+ Key["AltRight"] = "AltRight";
19
+ Key["KeyA"] = "KeyA";
20
+ Key["KeyB"] = "KeyB";
21
+ Key["KeyC"] = "KeyC";
22
+ Key["KeyD"] = "KeyD";
23
+ Key["KeyE"] = "KeyE";
24
+ Key["KeyF"] = "KeyF";
25
+ Key["KeyG"] = "KeyG";
26
+ Key["KeyH"] = "KeyH";
27
+ Key["KeyI"] = "KeyI";
28
+ Key["KeyJ"] = "KeyJ";
29
+ Key["KeyK"] = "KeyK";
30
+ Key["KeyL"] = "KeyL";
31
+ Key["KeyM"] = "KeyM";
32
+ Key["KeyN"] = "KeyN";
33
+ Key["KeyO"] = "KeyO";
34
+ Key["KeyP"] = "KeyP";
35
+ Key["KeyQ"] = "KeyQ";
36
+ Key["KeyR"] = "KeyR";
37
+ Key["KeyS"] = "KeyS";
38
+ Key["KeyT"] = "KeyT";
39
+ Key["KeyU"] = "KeyU";
40
+ Key["KeyV"] = "KeyV";
41
+ Key["KeyW"] = "KeyW";
42
+ Key["KeyX"] = "KeyX";
43
+ Key["KeyY"] = "KeyY";
44
+ Key["KeyZ"] = "KeyZ";
45
+ Key["Digit0"] = "Digit0";
46
+ Key["Digit1"] = "Digit1";
47
+ Key["Digit2"] = "Digit2";
48
+ Key["Digit3"] = "Digit3";
49
+ Key["Digit4"] = "Digit4";
50
+ Key["Digit5"] = "Digit5";
51
+ Key["Digit6"] = "Digit6";
52
+ Key["Digit7"] = "Digit7";
53
+ Key["Digit8"] = "Digit8";
54
+ Key["Digit9"] = "Digit9";
55
+ })(Key || (Key = {}));
@@ -0,0 +1 @@
1
+ export declare const dlog: (...args: any[]) => void;
package/dist/logger.js ADDED
@@ -0,0 +1,16 @@
1
+ // Debug Log Function
2
+ export const dlog =
3
+ // (import.meta.env?.DEV ?? true) // Default true, falls undefined
4
+ // ? (...args: any[]) => {
5
+ // const now = new Date();
6
+ // const time =
7
+ // `[${now.getHours().toString().padStart(2, "0")}:` +
8
+ // `${now.getMinutes().toString().padStart(2, "0")}:` +
9
+ // `${now.getSeconds().toString().padStart(2, "0")}.` +
10
+ // `${now.getMilliseconds().toString().padStart(3, "0")}]`;
11
+ // console.log(time, ...args);
12
+ // }
13
+ // :
14
+ (...args) => { }; // Release: nichts loggen
15
+ // Dlog in Release Mode:
16
+ // export const dlog = () => {};
@@ -0,0 +1,13 @@
1
+ import { type Rect } from "./types/rectangle.js";
2
+ import { type Circle } from "./types/circle.js";
3
+ import { type Triangle } from "./types/triangle.js";
4
+ export declare function renderText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, color?: string, font?: string): void;
5
+ type CharMap = Record<string, Rect>;
6
+ export declare function renderBitmapText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, sprite: HTMLImageElement, charMap: CharMap, scale?: number): void;
7
+ export declare function drawRect(ctx: CanvasRenderingContext2D, rect: Rect, color?: string): void;
8
+ export declare function drawRectOutline(ctx: CanvasRenderingContext2D, rect: Rect, color?: string, lineWidth?: number): void;
9
+ export declare function drawCircle(ctx: CanvasRenderingContext2D, circle: Circle, color?: string): void;
10
+ export declare function drawCircleOutline(ctx: CanvasRenderingContext2D, circle: Circle, color?: string, lineWidth?: number): void;
11
+ export declare function drawTriangle(ctx: CanvasRenderingContext2D, triangle: Triangle, color?: string): void;
12
+ export declare function drawTriangleOutline(ctx: CanvasRenderingContext2D, triangle: Triangle, color?: string, lineWidth?: number): void;
13
+ export {};
@@ -0,0 +1,81 @@
1
+ // Function to render Text
2
+ export function renderText(ctx, text, x, y, color = "white", font = "20px Arial") {
3
+ ctx.fillStyle = color;
4
+ ctx.font = font;
5
+ ctx.textBaseline = "top";
6
+ ctx.fillText(text, x, y);
7
+ }
8
+ export function renderBitmapText(ctx, text, x, y, sprite, charMap, scale = 1) {
9
+ let offsetX = 0;
10
+ for (const c of text) {
11
+ const rect = charMap[c];
12
+ if (!rect)
13
+ continue;
14
+ ctx.drawImage(sprite, rect.x, rect.y, rect.width, rect.height, x + offsetX, y, rect.width * scale, rect.height * scale);
15
+ offsetX += rect.width * scale;
16
+ }
17
+ }
18
+ // ===== SHAPE DRAWING =====
19
+ // Function to draw a filled Rectangle
20
+ export function drawRect(ctx, rect, color = "white") {
21
+ ctx.fillStyle = color;
22
+ const radius = rect.borderRadius ?? 0;
23
+ if (radius > 0 && ctx.roundRect) {
24
+ ctx.beginPath();
25
+ ctx.roundRect(rect.x, rect.y, rect.width, rect.height, radius);
26
+ ctx.fill();
27
+ }
28
+ else {
29
+ ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
30
+ }
31
+ }
32
+ // Function to draw a Rectangle outline
33
+ export function drawRectOutline(ctx, rect, color = "white", lineWidth = 1) {
34
+ ctx.strokeStyle = color;
35
+ ctx.lineWidth = lineWidth;
36
+ const radius = rect.borderRadius ?? 0;
37
+ if (radius > 0 && ctx.roundRect) {
38
+ ctx.beginPath();
39
+ ctx.roundRect(rect.x, rect.y, rect.width, rect.height, radius);
40
+ ctx.stroke();
41
+ }
42
+ else {
43
+ ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);
44
+ }
45
+ }
46
+ // Function to draw a filled Circle
47
+ export function drawCircle(ctx, circle, color = "white") {
48
+ ctx.fillStyle = color;
49
+ ctx.beginPath();
50
+ ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
51
+ ctx.fill();
52
+ }
53
+ // Function to draw a Circle outline
54
+ export function drawCircleOutline(ctx, circle, color = "white", lineWidth = 1) {
55
+ ctx.strokeStyle = color;
56
+ ctx.lineWidth = lineWidth;
57
+ ctx.beginPath();
58
+ ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
59
+ ctx.stroke();
60
+ }
61
+ // Function to draw a filled Triangle
62
+ export function drawTriangle(ctx, triangle, color = "white") {
63
+ ctx.fillStyle = color;
64
+ ctx.beginPath();
65
+ ctx.moveTo(triangle.x1, triangle.y1);
66
+ ctx.lineTo(triangle.x2, triangle.y2);
67
+ ctx.lineTo(triangle.x3, triangle.y3);
68
+ ctx.closePath();
69
+ ctx.fill();
70
+ }
71
+ // Function to draw a Triangle outline
72
+ export function drawTriangleOutline(ctx, triangle, color = "white", lineWidth = 1) {
73
+ ctx.strokeStyle = color;
74
+ ctx.lineWidth = lineWidth;
75
+ ctx.beginPath();
76
+ ctx.moveTo(triangle.x1, triangle.y1);
77
+ ctx.lineTo(triangle.x2, triangle.y2);
78
+ ctx.lineTo(triangle.x3, triangle.y3);
79
+ ctx.closePath();
80
+ ctx.stroke();
81
+ }
package/dist/save.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ type SaveData = Record<string, any>;
2
+ export declare function saveGame(data: SaveData): void;
3
+ export declare function loadGame(): SaveData | null;
4
+ export declare function clearSave(): void;
5
+ export {};
package/dist/save.js ADDED
@@ -0,0 +1,27 @@
1
+ const SAVE_KEY = "my_game_save";
2
+ export function saveGame(data) {
3
+ try {
4
+ const json = JSON.stringify(data);
5
+ localStorage.setItem(SAVE_KEY, json);
6
+ console.log("Game saved!");
7
+ }
8
+ catch (err) {
9
+ console.error("Save failed:", err);
10
+ }
11
+ }
12
+ export function loadGame() {
13
+ try {
14
+ const json = localStorage.getItem(SAVE_KEY);
15
+ if (!json)
16
+ return null;
17
+ return JSON.parse(json);
18
+ }
19
+ catch (err) {
20
+ console.error("Load failed:", err);
21
+ return null;
22
+ }
23
+ }
24
+ export function clearSave() {
25
+ localStorage.removeItem(SAVE_KEY);
26
+ console.log("Save cleared!");
27
+ }