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.
- package/README.md +145 -0
- package/dist/build/index.d.ts +1 -0
- package/dist/build/index.js +2 -0
- package/dist/build/version.d.ts +1 -0
- package/dist/build/version.js +4 -0
- package/dist/core.d.ts +3 -0
- package/dist/core.js +13 -0
- package/dist/html.d.ts +18 -0
- package/dist/html.js +66 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +14 -0
- package/dist/input.d.ts +17 -0
- package/dist/input.js +111 -0
- package/dist/keys.d.ts +52 -0
- package/dist/keys.js +55 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.js +16 -0
- package/dist/renderer.d.ts +13 -0
- package/dist/renderer.js +81 -0
- package/dist/save.d.ts +5 -0
- package/dist/save.js +27 -0
- package/dist/sound/audioplayer.d.ts +17 -0
- package/dist/sound/audioplayer.js +84 -0
- package/dist/sound/index.d.ts +1 -0
- package/dist/sound/index.js +2 -0
- package/dist/texture.d.ts +37 -0
- package/dist/texture.js +171 -0
- package/dist/types/circle.d.ts +14 -0
- package/dist/types/circle.js +38 -0
- package/dist/types/color.d.ts +9 -0
- package/dist/types/color.js +27 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +13 -0
- package/dist/types/rectangle.d.ts +16 -0
- package/dist/types/rectangle.js +41 -0
- package/dist/types/triangle.d.ts +16 -0
- package/dist/types/triangle.js +49 -0
- package/dist/types/vector2d.d.ts +14 -0
- package/dist/types/vector2d.js +72 -0
- package/dist/types/vector3d.d.ts +16 -0
- package/dist/types/vector3d.js +86 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/jsonc-parser.d.ts +4 -0
- package/dist/utils/jsonc-parser.js +166 -0
- package/dist/utils/markdown.d.ts +41 -0
- package/dist/utils/markdown.js +657 -0
- package/dist/utils/math.d.ts +3 -0
- package/dist/utils/math.js +12 -0
- 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 @@
|
|
|
1
|
+
export declare function version(): string;
|
package/dist/core.d.ts
ADDED
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
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -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";
|
package/dist/input.d.ts
ADDED
|
@@ -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 = {}));
|
package/dist/logger.d.ts
ADDED
|
@@ -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 {};
|
package/dist/renderer.js
ADDED
|
@@ -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
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
|
+
}
|