@starweb-libs/menus 0.0.2 → 0.0.3
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 +6 -0
- package/dist/complete.d.mts +8 -0
- package/dist/complete.mjs +90 -0
- package/dist/complete.mjs.map +1 -0
- package/dist/failed.d.mts +8 -0
- package/dist/failed.mjs +67 -0
- package/dist/failed.mjs.map +1 -0
- package/dist/levels.d.mts +10 -0
- package/dist/levels.mjs +76 -0
- package/dist/levels.mjs.map +1 -0
- package/dist/pause.d.mts +8 -0
- package/dist/pause.mjs +85 -0
- package/dist/pause.mjs.map +1 -0
- package/dist/settings.d.mts +12 -0
- package/dist/settings.mjs +75 -0
- package/dist/settings.mjs.map +1 -0
- package/dist/title.d.mts +8 -0
- package/dist/title.mjs +61 -0
- package/dist/title.mjs.map +1 -0
- package/dist/transition.mjs.map +1 -1
- package/dist/types.d.mts +100 -0
- package/dist/types.mjs +1 -0
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -14,6 +14,12 @@ Composable canvas menu screens for browser games, built with TypeScript.
|
|
|
14
14
|
| Module | Description |
|
|
15
15
|
| ------ | ----------- |
|
|
16
16
|
| `transition.js` | Plays the button sound, runs an optional callback, and flushes pointer + keyboard input between screens. |
|
|
17
|
+
| `title.js` | Title screen with START and SETTINGS buttons; takes a level count and an optional on-start callback. |
|
|
18
|
+
| `levels.js` | Level-select grid (up to 9) with a Back button; takes the level list and a `selectLevel(index)` callback. |
|
|
19
|
+
| `settings.js` | Settings screen with mute toggle and volume slider; takes the current slider state and returns the updated state alongside the frame. |
|
|
20
|
+
| `pause.js` | Pause overlay with Resume / Restart / Quit buttons; takes a `resetPlayState` callback. |
|
|
21
|
+
| `complete.js` | Level-complete overlay with Restart / Quit buttons, plus Next when a further level exists; takes the level index/count and `selectLevel` + `resetPlayState` callbacks. |
|
|
22
|
+
| `failed.js` | Level-failed overlay with Restart / Quit buttons; takes a `resetPlayState` callback. |
|
|
17
23
|
|
|
18
24
|
## Installation
|
|
19
25
|
```bash
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CompleteFrame, CompleteMenuState } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
//#region src/complete.d.ts
|
|
4
|
+
declare function handleCompleteFrame(w: number, h: number, a: Audio, levelIndex: number, levelCount: number, selectLevel: (i: number) => void, resetPlayState: () => void): CompleteFrame;
|
|
5
|
+
declare function renderCompleteFrame(ctx: CanvasRenderingContext2D, ui: CompleteMenuState | null, w: number, h: number): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { handleCompleteFrame, renderCompleteFrame };
|
|
8
|
+
//# sourceMappingURL=complete.d.mts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
//#region src/complete.ts
|
|
6
|
+
function handleCompleteFrame(w, h, a, levelIndex, levelCount, selectLevel, resetPlayState) {
|
|
7
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
8
|
+
const hasNext = levelIndex < levelCount - 1;
|
|
9
|
+
const btnCount = hasNext ? 3 : 2;
|
|
10
|
+
const firstY = cy - (btnH * btnCount + gap * (btnCount - 1)) / 2;
|
|
11
|
+
const titleY = firstY - btnH * .5 - gap * 2;
|
|
12
|
+
const restartBtn = {
|
|
13
|
+
x: cx - btnW / 2,
|
|
14
|
+
y: firstY,
|
|
15
|
+
w: btnW,
|
|
16
|
+
h: btnH,
|
|
17
|
+
label: "Restart"
|
|
18
|
+
};
|
|
19
|
+
const quitBtn = {
|
|
20
|
+
x: cx - btnW / 2,
|
|
21
|
+
y: firstY + (btnH + gap) * (btnCount - 1),
|
|
22
|
+
w: btnW,
|
|
23
|
+
h: btnH,
|
|
24
|
+
label: "Quit"
|
|
25
|
+
};
|
|
26
|
+
const restart = {
|
|
27
|
+
btn: restartBtn,
|
|
28
|
+
state: getButtonState(restartBtn, getPointer())
|
|
29
|
+
};
|
|
30
|
+
const quit = {
|
|
31
|
+
btn: quitBtn,
|
|
32
|
+
state: getButtonState(quitBtn, getPointer())
|
|
33
|
+
};
|
|
34
|
+
let next = null;
|
|
35
|
+
if (hasNext) {
|
|
36
|
+
const nextBtn = {
|
|
37
|
+
x: cx - btnW / 2,
|
|
38
|
+
y: firstY + (btnH + gap),
|
|
39
|
+
w: btnW,
|
|
40
|
+
h: btnH,
|
|
41
|
+
label: "Next"
|
|
42
|
+
};
|
|
43
|
+
next = {
|
|
44
|
+
btn: nextBtn,
|
|
45
|
+
state: getButtonState(nextBtn, getPointer())
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
let action = null;
|
|
49
|
+
if (next?.state.clicked) action = "next";
|
|
50
|
+
if (restart.state.clicked) action = "restart";
|
|
51
|
+
if (quit.state.clicked) action = "quit";
|
|
52
|
+
const ui = {
|
|
53
|
+
cx,
|
|
54
|
+
scale,
|
|
55
|
+
titleY,
|
|
56
|
+
restart,
|
|
57
|
+
next,
|
|
58
|
+
quit,
|
|
59
|
+
action
|
|
60
|
+
};
|
|
61
|
+
if (ui.action === "quit") return transition({
|
|
62
|
+
game: "menu-title",
|
|
63
|
+
ui: null
|
|
64
|
+
}, a);
|
|
65
|
+
if (ui.action === "next") return transition({
|
|
66
|
+
game: "level-playing",
|
|
67
|
+
ui: null
|
|
68
|
+
}, a, () => selectLevel(levelIndex + 1));
|
|
69
|
+
if (ui.action === "restart") return transition({
|
|
70
|
+
game: "level-playing",
|
|
71
|
+
ui: null
|
|
72
|
+
}, a, () => resetPlayState());
|
|
73
|
+
return {
|
|
74
|
+
game: "level-complete",
|
|
75
|
+
ui
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function renderCompleteFrame(ctx, ui, w, h) {
|
|
79
|
+
if (!ui) return;
|
|
80
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.6)";
|
|
81
|
+
ctx.fillRect(0, 0, w, h);
|
|
82
|
+
drawTitle(ctx, "Level Complete!", ui.cx, ui.titleY, ui.scale);
|
|
83
|
+
drawButton(ctx, ui.restart.btn, ui.restart.state);
|
|
84
|
+
if (ui.next) drawButton(ctx, ui.next.btn, ui.next.state);
|
|
85
|
+
drawButton(ctx, ui.quit.btn, ui.quit.state);
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { handleCompleteFrame, renderCompleteFrame };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=complete.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.mjs","names":[],"sources":["../src/complete.ts"],"sourcesContent":["import type { Button } from \"@starweb-libs/ui/types.js\";\nimport type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport type { CompleteAction, CompleteFrame, CompleteMenuState } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handleCompleteFrame(\n w: number, h: number, a: Audio,\n levelIndex: number,\n levelCount: number,\n selectLevel: (i: number) => void, resetPlayState: () => void,\n): CompleteFrame {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const hasNext = levelIndex < levelCount - 1\n const btnCount = hasNext ? 3 : 2;\n const totalH = btnH * btnCount + gap * (btnCount - 1);\n const firstY = cy - totalH / 2;\n const titleY = firstY - btnH * 0.5 - gap * 2;\n\n const restartBtn: Button = { x: cx - btnW/2, y: firstY, w: btnW, h: btnH, label: \"Restart\" };\n const quitBtn: Button = { x: cx - btnW/2, y: firstY + (btnH + gap) * (btnCount - 1), w: btnW, h: btnH, label: \"Quit\" };\n\n const restart = { btn: restartBtn, state: getButtonState(restartBtn, getPointer()) };\n const quit = { btn: quitBtn, state: getButtonState(quitBtn, getPointer()) };\n\n let next: CompleteMenuState[\"next\"] = null;\n if (hasNext) {\n const nextBtn: Button = { x: cx - btnW/2, y: firstY + (btnH + gap), w: btnW, h: btnH, label: \"Next\" };\n next = { btn: nextBtn, state: getButtonState(nextBtn, getPointer()) };\n }\n\n let action: CompleteAction = null;\n if (next?.state.clicked) action = \"next\";\n if (restart.state.clicked) action = \"restart\";\n if (quit.state.clicked) action = \"quit\";\n\n const ui = { cx, scale, titleY, restart, next, quit, action };\n\n if (ui.action === \"quit\") return transition({ game: \"menu-title\", ui: null }, a);\n if (ui.action === \"next\") return transition(\n { game: \"level-playing\", ui: null },\n a,\n () => selectLevel(levelIndex + 1)\n );\n if (ui.action === \"restart\") return transition(\n { game: \"level-playing\", ui: null },\n a,\n () => resetPlayState()\n );\n return { game: \"level-complete\", ui };\n}\n\nexport function renderCompleteFrame(\n ctx: CanvasRenderingContext2D,\n ui: CompleteMenuState | null,\n w: number, h: number,\n): void {\n if (!ui) return;\n\n ctx.fillStyle = \"rgba(0, 0, 0, 0.6)\";\n ctx.fillRect(0, 0, w, h);\n drawTitle(ctx, \"Level Complete!\", ui.cx, ui.titleY, ui.scale);\n drawButton(ctx, ui.restart.btn, ui.restart.state);\n if (ui.next) drawButton(ctx, ui.next.btn, ui.next.state);\n drawButton(ctx, ui.quit.btn, ui.quit.state);\n}\n\n\n"],"mappings":";;;;;AAQA,SAAgB,oBACd,GAAW,GAAW,GACtB,YACA,YACA,aAAkC,gBACnB;CACf,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CACzD,MAAM,UAAU,aAAa,aAAa;CAC1C,MAAM,WAAW,UAAU,IAAI;CAE/B,MAAM,SAAS,MADA,OAAO,WAAW,OAAO,WAAW,MACtB;CAC7B,MAAM,SAAS,SAAS,OAAO,KAAM,MAAM;CAE3C,MAAM,aAAqB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG;EAAwC,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CAC3H,MAAM,UAAqB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,UAAU,OAAO,QAAQ,WAAW;EAAI,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CAE3H,MAAM,UAAU;EAAE,KAAK;EAAY,OAAO,eAAe,YAAY,WAAW,CAAC;CAAE;CACnF,MAAM,OAAU;EAAE,KAAK;EAAY,OAAO,eAAe,SAAY,WAAW,CAAC;CAAE;CAEnF,IAAI,OAAkC;CACtC,IAAI,SAAS;EACX,MAAM,UAAkB;GAAE,GAAG,KAAK,OAAK;GAAG,GAAG,UAAU,OAAO;GAAM,GAAG;GAAM,GAAG;GAAM,OAAO;EAAO;EACpG,OAAO;GAAE,KAAK;GAAS,OAAO,eAAe,SAAS,WAAW,CAAC;EAAE;CACtE;CAEA,IAAI,SAAyB;CAC7B,IAAI,MAAM,MAAM,SAAW,SAAS;CACpC,IAAI,QAAQ,MAAM,SAAS,SAAS;CACpC,IAAI,KAAK,MAAM,SAAY,SAAS;CAEpC,MAAM,KAAK;EAAE;EAAI;EAAO;EAAQ;EAAS;EAAM;EAAM;CAAO;CAE5D,IAAI,GAAG,WAAW,QAAW,OAAO,WAAW;EAAE,MAAM;EAAc,IAAI;CAAK,GAAG,CAAC;CAClF,IAAI,GAAG,WAAW,QAAW,OAAO,WAClC;EAAE,MAAM;EAAiB,IAAI;CAAK,GAClC,SACM,YAAY,aAAa,CAAC,CAClC;CACA,IAAI,GAAG,WAAW,WAAW,OAAO,WAClC;EAAE,MAAM;EAAiB,IAAI;CAAK,GAClC,SACM,eAAe,CACvB;CACA,OAAO;EAAE,MAAM;EAAkB;CAAG;AACtC;AAEA,SAAgB,oBACd,KACA,IACA,GAAW,GACL;CACN,IAAI,CAAC,IAAI;CAET,IAAI,YAAY;CAChB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;CACvB,UAAU,KAAK,mBAAmB,GAAG,IAAI,GAAG,QAAQ,GAAG,KAAK;CAC5D,WAAW,KAAK,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK;CAChD,IAAI,GAAG,MAAM,WAAW,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;CACvD,WAAW,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;AAC5C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FailedFrame, FailedMenuState } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
//#region src/failed.d.ts
|
|
4
|
+
declare function handleFailedFrame(w: number, h: number, a: Audio, resetPlayState: () => void): FailedFrame;
|
|
5
|
+
declare function renderFailedFrame(ctx: CanvasRenderingContext2D, ui: FailedMenuState | null, w: number, h: number): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { handleFailedFrame, renderFailedFrame };
|
|
8
|
+
//# sourceMappingURL=failed.d.mts.map
|
package/dist/failed.mjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
//#region src/failed.ts
|
|
6
|
+
function handleFailedFrame(w, h, a, resetPlayState) {
|
|
7
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
8
|
+
const firstY = cy - (btnH * 2 + gap) / 2;
|
|
9
|
+
const titleY = firstY - btnH * .5 - gap * 2;
|
|
10
|
+
const restartBtn = {
|
|
11
|
+
x: cx - btnW / 2,
|
|
12
|
+
y: firstY,
|
|
13
|
+
w: btnW,
|
|
14
|
+
h: btnH,
|
|
15
|
+
label: "Restart"
|
|
16
|
+
};
|
|
17
|
+
const quitBtn = {
|
|
18
|
+
x: cx - btnW / 2,
|
|
19
|
+
y: firstY + btnH + gap,
|
|
20
|
+
w: btnW,
|
|
21
|
+
h: btnH,
|
|
22
|
+
label: "Quit"
|
|
23
|
+
};
|
|
24
|
+
const restart = {
|
|
25
|
+
btn: restartBtn,
|
|
26
|
+
state: getButtonState(restartBtn, getPointer())
|
|
27
|
+
};
|
|
28
|
+
const quit = {
|
|
29
|
+
btn: quitBtn,
|
|
30
|
+
state: getButtonState(quitBtn, getPointer())
|
|
31
|
+
};
|
|
32
|
+
let action = null;
|
|
33
|
+
if (restart.state.clicked) action = "restart";
|
|
34
|
+
if (quit.state.clicked) action = "quit";
|
|
35
|
+
const ui = {
|
|
36
|
+
cx,
|
|
37
|
+
scale,
|
|
38
|
+
titleY,
|
|
39
|
+
restart,
|
|
40
|
+
quit,
|
|
41
|
+
action
|
|
42
|
+
};
|
|
43
|
+
if (ui.action === "quit") return transition({
|
|
44
|
+
game: "menu-title",
|
|
45
|
+
ui: null
|
|
46
|
+
}, a);
|
|
47
|
+
if (ui.action === "restart") return transition({
|
|
48
|
+
game: "level-playing",
|
|
49
|
+
ui: null
|
|
50
|
+
}, a, () => resetPlayState());
|
|
51
|
+
return {
|
|
52
|
+
game: "level-failed",
|
|
53
|
+
ui
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function renderFailedFrame(ctx, ui, w, h) {
|
|
57
|
+
if (!ui) return;
|
|
58
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.6)";
|
|
59
|
+
ctx.fillRect(0, 0, w, h);
|
|
60
|
+
drawTitle(ctx, "Level Failed!", ui.cx, ui.titleY, ui.scale);
|
|
61
|
+
drawButton(ctx, ui.restart.btn, ui.restart.state);
|
|
62
|
+
drawButton(ctx, ui.quit.btn, ui.quit.state);
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { handleFailedFrame, renderFailedFrame };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=failed.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failed.mjs","names":[],"sources":["../src/failed.ts"],"sourcesContent":["import type { Button } from \"@starweb-libs/ui/types.js\";\nimport type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport type { FailedAction, FailedFrame, FailedMenuState } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handleFailedFrame(\n w: number, h: number, a: Audio,\n resetPlayState: () => void\n): FailedFrame {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const totalH = btnH * 2 + gap;\n const firstY = cy - totalH / 2;\n const titleY = firstY - btnH * 0.5 - gap * 2;\n\n const restartBtn: Button = { x: cx - btnW/2, y: firstY, w: btnW, h: btnH, label: \"Restart\" };\n const quitBtn: Button = { x: cx - btnW/2, y: firstY + btnH + gap, w: btnW, h: btnH, label: \"Quit\" };\n\n const restart = { btn: restartBtn, state: getButtonState(restartBtn, getPointer()) };\n const quit = { btn: quitBtn, state: getButtonState(quitBtn, getPointer()) };\n\n let action: FailedAction = null;\n if (restart.state.clicked) action = \"restart\";\n if (quit.state.clicked) action = \"quit\";\n\n const ui = { cx, scale, titleY, restart, quit, action };\n\n if (ui.action === \"quit\") return transition({ game: \"menu-title\", ui: null }, a);\n if (ui.action === \"restart\") return transition(\n { game: \"level-playing\", ui: null },\n a,\n () => resetPlayState()\n );\n return { game: \"level-failed\", ui };\n}\n\nexport function renderFailedFrame(\n ctx: CanvasRenderingContext2D,\n ui: FailedMenuState | null,\n w: number, h: number\n): void {\n if (!ui) return;\n\n ctx.fillStyle = \"rgba(0, 0, 0, 0.6)\";\n ctx.fillRect(0, 0, w, h);\n drawTitle(ctx, \"Level Failed!\", ui.cx, ui.titleY, ui.scale);\n drawButton(ctx, ui.restart.btn, ui.restart.state);\n drawButton(ctx, ui.quit.btn, ui.quit.state);\n}\n"],"mappings":";;;;;AAQA,SAAgB,kBACd,GAAW,GAAW,GACtB,gBACa;CACb,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CAEzD,MAAM,SAAU,MADA,OAAO,IAAI,OACG;CAC9B,MAAM,SAAS,SAAS,OAAO,KAAM,MAAM;CAE3C,MAAM,aAAqB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG;EAAwC,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CAC3H,MAAM,UAAkB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,SAAS,OAAO;EAAK,GAAG;EAAM,GAAG;EAAM,OAAO;CAAO;CAElG,MAAM,UAAU;EAAE,KAAK;EAAY,OAAO,eAAe,YAAY,WAAW,CAAC;CAAE;CACnF,MAAM,OAAU;EAAE,KAAK;EAAY,OAAO,eAAe,SAAS,WAAW,CAAC;CAAK;CAEnF,IAAI,SAAuB;CAC3B,IAAI,QAAQ,MAAM,SAAS,SAAS;CACpC,IAAI,KAAK,MAAM,SAAY,SAAS;CAEpC,MAAM,KAAK;EAAE;EAAI;EAAO;EAAQ;EAAS;EAAM;CAAO;CAEtD,IAAI,GAAG,WAAW,QAAW,OAAO,WAAW;EAAE,MAAM;EAAc,IAAI;CAAK,GAAG,CAAC;CAClF,IAAI,GAAG,WAAW,WAAW,OAAO,WAClC;EAAE,MAAM;EAAiB,IAAI;CAAK,GAClC,SACM,eAAe,CACvB;CACA,OAAO;EAAE,MAAM;EAAgB;CAAG;AACpC;AAEA,SAAgB,kBACd,KACA,IACA,GAAW,GACL;CACN,IAAI,CAAC,IAAI;CAET,IAAI,YAAY;CAChB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;CACvB,UAAU,KAAK,iBAAiB,GAAG,IAAI,GAAG,QAAQ,GAAG,KAAK;CAC1D,WAAW,KAAK,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK;CAChD,WAAW,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;AAC5C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LevelSelectState, LevelsFrame } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
//#region src/levels.d.ts
|
|
4
|
+
declare function handleLevelFrame(w: number, h: number, a: Audio, levels: {
|
|
5
|
+
name?: string;
|
|
6
|
+
}[], selectLevel: (i: number) => void): LevelsFrame;
|
|
7
|
+
declare function renderLevelFrame(ctx: CanvasRenderingContext2D, ui: LevelSelectState | null): void;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { handleLevelFrame, renderLevelFrame };
|
|
10
|
+
//# sourceMappingURL=levels.d.mts.map
|
package/dist/levels.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
//#region src/levels.ts
|
|
6
|
+
function handleLevelFrame(w, h, a, levels, selectLevel) {
|
|
7
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
8
|
+
const titleY = scale * .15;
|
|
9
|
+
const cols = 3;
|
|
10
|
+
const cellW = btnH * 3;
|
|
11
|
+
const gridW = cellW * cols + gap * (cols - 1);
|
|
12
|
+
const gridH = btnH * 3 + gap * 2;
|
|
13
|
+
const gridX = cx - gridW / 2;
|
|
14
|
+
const gridY = cy - gridH / 2;
|
|
15
|
+
let clickedIndex = null;
|
|
16
|
+
const levelEntries = Array.from({ length: Math.min(levels.length, 9) }, (_, i) => {
|
|
17
|
+
const col = i % cols;
|
|
18
|
+
const row = Math.floor(i / cols);
|
|
19
|
+
const btn = {
|
|
20
|
+
x: gridX + col * (cellW + gap),
|
|
21
|
+
y: gridY + row * (btnH + gap),
|
|
22
|
+
w: cellW,
|
|
23
|
+
h: btnH,
|
|
24
|
+
label: levels[i]?.name ?? `Level ${i + 1}`
|
|
25
|
+
};
|
|
26
|
+
const state = getButtonState(btn, getPointer());
|
|
27
|
+
if (state.clicked) clickedIndex = i;
|
|
28
|
+
return {
|
|
29
|
+
btn,
|
|
30
|
+
state
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
const backBtn = {
|
|
34
|
+
x: cx - btnW / 2,
|
|
35
|
+
y: h - btnH - gap * 2,
|
|
36
|
+
w: btnW,
|
|
37
|
+
h: btnH,
|
|
38
|
+
label: "Back"
|
|
39
|
+
};
|
|
40
|
+
const ui = {
|
|
41
|
+
cx,
|
|
42
|
+
scale,
|
|
43
|
+
titleY,
|
|
44
|
+
levels: levelEntries,
|
|
45
|
+
back: {
|
|
46
|
+
btn: backBtn,
|
|
47
|
+
state: getButtonState(backBtn, getPointer())
|
|
48
|
+
},
|
|
49
|
+
clickedIndex
|
|
50
|
+
};
|
|
51
|
+
if (ui.back.state.clicked) return transition({
|
|
52
|
+
game: "menu-title",
|
|
53
|
+
ui: null
|
|
54
|
+
}, a);
|
|
55
|
+
if (ui.clickedIndex !== null) {
|
|
56
|
+
const index = ui.clickedIndex;
|
|
57
|
+
return transition({
|
|
58
|
+
game: "level-playing",
|
|
59
|
+
ui: null
|
|
60
|
+
}, a, () => selectLevel(index));
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
game: "menu-levels",
|
|
64
|
+
ui
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function renderLevelFrame(ctx, ui) {
|
|
68
|
+
if (!ui) return;
|
|
69
|
+
drawTitle(ctx, "Select Level", ui.cx, ui.titleY, ui.scale);
|
|
70
|
+
for (const entry of ui.levels) drawButton(ctx, entry.btn, entry.state);
|
|
71
|
+
drawButton(ctx, ui.back.btn, ui.back.state);
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { handleLevelFrame, renderLevelFrame };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=levels.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"levels.mjs","names":[],"sources":["../src/levels.ts"],"sourcesContent":["import type { Button } from \"@starweb-libs/ui/types.js\";\nimport type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport type { LevelSelectState, LevelsFrame } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handleLevelFrame(\n w: number, h: number, a: Audio,\n levels: { name?: string }[],\n selectLevel: (i: number) => void,\n): LevelsFrame {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const titleY = scale * 0.15;\n\n const cols = 3;\n const cellW = btnH * 3;\n const gridW = cellW * cols + gap * (cols - 1);\n const gridH = btnH * 3 + gap * 2;\n const gridX = cx - gridW / 2;\n const gridY = cy - gridH / 2;\n\n let clickedIndex: number | null = null;\n const levelEntries = Array.from({ length: Math.min(levels.length, 9) }, (_, i) => {\n const col = i % cols;\n const row = Math.floor(i / cols);\n const btn: Button = {\n x: gridX + col * (cellW + gap),\n y: gridY + row * (btnH + gap),\n w: cellW, h: btnH,\n label: levels[i]?.name ?? `Level ${i + 1}`,\n };\n const state = getButtonState(btn, getPointer());\n if (state.clicked) clickedIndex = i;\n return { btn, state };\n });\n\n const backBtn: Button = { x: cx - btnW/2, y: h - btnH - gap*2, w: btnW, h: btnH, label: \"Back\" };\n const back = { btn: backBtn, state: getButtonState(backBtn, getPointer()) };\n\n const ui = { cx, scale, titleY, levels: levelEntries, back, clickedIndex };\n\n if (ui.back.state.clicked) return transition({ game: \"menu-title\", ui: null }, a);\n if (ui.clickedIndex !== null) {\n const index = ui.clickedIndex;\n return transition(\n { game: \"level-playing\", ui: null },\n a,\n () => selectLevel(index)\n );\n }\n return { game: \"menu-levels\", ui };\n}\n\nexport function renderLevelFrame(\n ctx: CanvasRenderingContext2D,\n ui: LevelSelectState | null\n): void {\n if (!ui) return;\n drawTitle(ctx, \"Select Level\", ui.cx, ui.titleY, ui.scale);\n for (const entry of ui.levels) drawButton(ctx, entry.btn, entry.state);\n drawButton(ctx, ui.back.btn, ui.back.state);\n}\n"],"mappings":";;;;;AAQA,SAAgB,iBACd,GAAW,GAAW,GACtB,QACA,aACa;CACb,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CACzD,MAAM,SAAS,QAAQ;CAEvB,MAAM,OAAQ;CACd,MAAM,QAAQ,OAAO;CACrB,MAAM,QAAQ,QAAQ,OAAO,OAAO,OAAO;CAC3C,MAAM,QAAQ,OAAO,IAAI,MAAM;CAC/B,MAAM,QAAQ,KAAK,QAAQ;CAC3B,MAAM,QAAQ,KAAK,QAAQ;CAE3B,IAAI,eAA8B;CAClC,MAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM;EAChF,MAAM,MAAM,IAAI;EAChB,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI;EAC/B,MAAM,MAAc;GAClB,GAAG,QAAQ,OAAO,QAAQ;GAC1B,GAAG,QAAQ,OAAO,OAAO;GACzB,GAAG;GAAO,GAAG;GACb,OAAO,OAAO,EAAE,EAAE,QAAQ,SAAS,IAAI;EACzC;EACA,MAAM,QAAQ,eAAe,KAAK,WAAW,CAAC;EAC9C,IAAI,MAAM,SAAS,eAAe;EAClC,OAAO;GAAE;GAAK;EAAM;CACtB,CAAC;CAED,MAAM,UAAkB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,IAAI,OAAO,MAAI;EAAG,GAAG;EAAM,GAAG;EAAM,OAAO;CAAO;CAG/F,MAAM,KAAK;EAAE;EAAI;EAAO;EAAQ,QAAQ;EAAc,MAAA;GAFvC,KAAK;GAAS,OAAO,eAAe,SAAS,WAAW,CAAC;EAEf;EAAG;CAAa;CAEzE,IAAI,GAAG,KAAK,MAAM,SAAS,OAAO,WAAW;EAAE,MAAM;EAAc,IAAI;CAAK,GAAG,CAAC;CAChF,IAAI,GAAG,iBAAiB,MAAM;EAC5B,MAAM,QAAQ,GAAG;EACjB,OAAO,WACL;GAAE,MAAM;GAAiB,IAAI;EAAK,GAClC,SACM,YAAY,KAAK,CACzB;CACF;CACA,OAAO;EAAE,MAAM;EAAe;CAAG;AACnC;AAEA,SAAgB,iBACd,KACA,IACM;CACN,IAAI,CAAC,IAAI;CACT,UAAU,KAAK,gBAAgB,GAAG,IAAI,GAAG,QAAQ,GAAG,KAAK;CACzD,KAAK,MAAM,SAAS,GAAG,QAAQ,WAAW,KAAK,MAAM,KAAK,MAAM,KAAK;CACrE,WAAW,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK;AAC5C"}
|
package/dist/pause.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PauseFrame, PauseMenuState } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
//#region src/pause.d.ts
|
|
4
|
+
declare function handlePauseFrame(w: number, h: number, a: Audio, resetPlayState: () => void): PauseFrame;
|
|
5
|
+
declare function renderPauseFrame(ctx: CanvasRenderingContext2D, ui: PauseMenuState | null, w: number, h: number): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { handlePauseFrame, renderPauseFrame };
|
|
8
|
+
//# sourceMappingURL=pause.d.mts.map
|
package/dist/pause.mjs
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
//#region src/pause.ts
|
|
6
|
+
function handlePauseFrame(w, h, a, resetPlayState) {
|
|
7
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
8
|
+
const firstY = cy - (btnH * 3 + gap * 2) / 2;
|
|
9
|
+
const titleY = firstY - btnH * .5 - gap * 2;
|
|
10
|
+
const resumeBtn = {
|
|
11
|
+
x: cx - btnW / 2,
|
|
12
|
+
y: firstY,
|
|
13
|
+
w: btnW,
|
|
14
|
+
h: btnH,
|
|
15
|
+
label: "Resume"
|
|
16
|
+
};
|
|
17
|
+
const restartBtn = {
|
|
18
|
+
x: cx - btnW / 2,
|
|
19
|
+
y: firstY + (btnH + gap),
|
|
20
|
+
w: btnW,
|
|
21
|
+
h: btnH,
|
|
22
|
+
label: "Restart"
|
|
23
|
+
};
|
|
24
|
+
const quitBtn = {
|
|
25
|
+
x: cx - btnW / 2,
|
|
26
|
+
y: firstY + (btnH + gap) * 2,
|
|
27
|
+
w: btnW,
|
|
28
|
+
h: btnH,
|
|
29
|
+
label: "Quit"
|
|
30
|
+
};
|
|
31
|
+
const resume = {
|
|
32
|
+
btn: resumeBtn,
|
|
33
|
+
state: getButtonState(resumeBtn, getPointer())
|
|
34
|
+
};
|
|
35
|
+
const restart = {
|
|
36
|
+
btn: restartBtn,
|
|
37
|
+
state: getButtonState(restartBtn, getPointer())
|
|
38
|
+
};
|
|
39
|
+
const quit = {
|
|
40
|
+
btn: quitBtn,
|
|
41
|
+
state: getButtonState(quitBtn, getPointer())
|
|
42
|
+
};
|
|
43
|
+
let action = null;
|
|
44
|
+
if (resume.state.clicked) action = "resume";
|
|
45
|
+
if (restart.state.clicked) action = "restart";
|
|
46
|
+
if (quit.state.clicked) action = "quit";
|
|
47
|
+
const ui = {
|
|
48
|
+
cx,
|
|
49
|
+
scale,
|
|
50
|
+
titleY,
|
|
51
|
+
resume,
|
|
52
|
+
restart,
|
|
53
|
+
quit,
|
|
54
|
+
action
|
|
55
|
+
};
|
|
56
|
+
if (ui.action === "resume") return transition({
|
|
57
|
+
game: "level-playing",
|
|
58
|
+
ui: null
|
|
59
|
+
}, a);
|
|
60
|
+
if (ui.action === "quit") return transition({
|
|
61
|
+
game: "menu-title",
|
|
62
|
+
ui: null
|
|
63
|
+
}, a);
|
|
64
|
+
if (ui.action === "restart") return transition({
|
|
65
|
+
game: "level-playing",
|
|
66
|
+
ui: null
|
|
67
|
+
}, a, () => resetPlayState());
|
|
68
|
+
return {
|
|
69
|
+
game: "level-paused",
|
|
70
|
+
ui
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function renderPauseFrame(ctx, ui, w, h) {
|
|
74
|
+
if (!ui) return;
|
|
75
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.6)";
|
|
76
|
+
ctx.fillRect(0, 0, w, h);
|
|
77
|
+
drawTitle(ctx, "Paused", ui.cx, ui.titleY, ui.scale);
|
|
78
|
+
drawButton(ctx, ui.resume.btn, ui.resume.state);
|
|
79
|
+
drawButton(ctx, ui.restart.btn, ui.restart.state);
|
|
80
|
+
drawButton(ctx, ui.quit.btn, ui.quit.state);
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { handlePauseFrame, renderPauseFrame };
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=pause.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pause.mjs","names":[],"sources":["../src/pause.ts"],"sourcesContent":["import type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport type { PauseAction, PauseFrame, PauseMenuState } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handlePauseFrame(\n w: number, h: number, a: Audio,\n resetPlayState: () => void\n): PauseFrame {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const totalH = btnH * 3 + gap * 2;\n const firstY = cy - totalH / 2;\n const titleY = firstY - btnH * 0.5 - gap * 2;\n\n const resumeBtn = { x: cx - btnW/2, y: firstY, w: btnW, h: btnH, label: \"Resume\" };\n const restartBtn = { x: cx - btnW/2, y: firstY + (btnH + gap), w: btnW, h: btnH, label: \"Restart\" };\n const quitBtn = { x: cx - btnW/2, y: firstY + (btnH + gap) * 2, w: btnW, h: btnH, label: \"Quit\" };\n\n const resume = { btn: resumeBtn, state: getButtonState(resumeBtn, getPointer()) };\n const restart = { btn: restartBtn, state: getButtonState(restartBtn, getPointer()) };\n const quit = { btn: quitBtn, state: getButtonState(quitBtn, getPointer()) };\n\n let action: PauseAction = null;\n if (resume.state.clicked) action = \"resume\";\n if (restart.state.clicked) action = \"restart\";\n if (quit.state.clicked) action = \"quit\";\n\n const ui = { cx, scale, titleY, resume, restart, quit, action };\n\n if (ui.action === \"resume\") return transition({ game: \"level-playing\", ui: null }, a);\n if (ui.action === \"quit\") return transition({ game: \"menu-title\", ui: null }, a);\n if (ui.action === \"restart\") return transition(\n { game: \"level-playing\", ui: null },\n a,\n () => resetPlayState()\n );\n return { game: \"level-paused\", ui };\n}\n\nexport function renderPauseFrame(\n ctx: CanvasRenderingContext2D,\n ui: PauseMenuState | null,\n w: number, h: number,\n): void {\n if (!ui) return;\n ctx.fillStyle = \"rgba(0, 0, 0, 0.6)\";\n ctx.fillRect(0, 0, w, h);\n drawTitle(ctx, \"Paused\", ui.cx, ui.titleY, ui.scale);\n drawButton(ctx, ui.resume.btn, ui.resume.state);\n drawButton(ctx, ui.restart.btn, ui.restart.state);\n drawButton(ctx, ui.quit.btn, ui.quit.state);\n}\n"],"mappings":";;;;;AAOA,SAAgB,iBACd,GAAW,GAAW,GACtB,gBACY;CACZ,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CAEzD,MAAM,SAAS,MADA,OAAO,IAAI,MAAM,KACH;CAC7B,MAAM,SAAS,SAAS,OAAO,KAAM,MAAM;CAE3C,MAAM,YAAa;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG;EAA2B,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CACtG,MAAM,aAAa;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,UAAU,OAAO;EAAU,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CACtG,MAAM,UAAa;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,UAAU,OAAO,OAAO;EAAG,GAAG;EAAM,GAAG;EAAM,OAAO;CAAU;CAEtG,MAAM,SAAU;EAAE,KAAK;EAAY,OAAO,eAAe,WAAY,WAAW,CAAC;CAAE;CACnF,MAAM,UAAU;EAAE,KAAK;EAAY,OAAO,eAAe,YAAY,WAAW,CAAC;CAAE;CACnF,MAAM,OAAU;EAAE,KAAK;EAAY,OAAO,eAAe,SAAY,WAAW,CAAC;CAAE;CAEnF,IAAI,SAAsB;CAC1B,IAAI,OAAO,MAAM,SAAU,SAAS;CACpC,IAAI,QAAQ,MAAM,SAAS,SAAS;CACpC,IAAI,KAAK,MAAM,SAAY,SAAS;CAEpC,MAAM,KAAK;EAAE;EAAI;EAAO;EAAQ;EAAQ;EAAS;EAAM;CAAO;CAE9D,IAAI,GAAG,WAAW,UAAW,OAAO,WAAW;EAAE,MAAM;EAAiB,IAAI;CAAK,GAAG,CAAC;CACrF,IAAI,GAAG,WAAW,QAAW,OAAO,WAAW;EAAE,MAAM;EAAiB,IAAI;CAAK,GAAG,CAAC;CACrF,IAAI,GAAG,WAAW,WAAW,OAAO,WAClC;EAAE,MAAM;EAAiB,IAAI;CAAK,GAClC,SACM,eAAe,CACvB;CACA,OAAO;EAAE,MAAM;EAAgB;CAAG;AACpC;AAEA,SAAgB,iBACd,KACA,IACA,GAAW,GACL;CACN,IAAI,CAAC,IAAI;CACT,IAAI,YAAY;CAChB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;CACvB,UAAU,KAAK,UAAU,GAAG,IAAI,GAAG,QAAQ,GAAG,KAAK;CACnD,WAAW,KAAK,GAAG,OAAO,KAAM,GAAG,OAAO,KAAK;CAC/C,WAAW,KAAK,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK;CAChD,WAAW,KAAK,GAAG,KAAK,KAAQ,GAAG,KAAK,KAAK;AAC/C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SettingsFrame, SettingsMenuState } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
import { SliderState } from "@starweb-libs/ui/types.js";
|
|
4
|
+
//#region src/settings.d.ts
|
|
5
|
+
declare function handleSettingsFrame(w: number, h: number, volState: SliderState, a: Audio): {
|
|
6
|
+
frame: SettingsFrame;
|
|
7
|
+
volState: SliderState;
|
|
8
|
+
};
|
|
9
|
+
declare function renderSettingsFrame(ctx: CanvasRenderingContext2D, ui: SettingsMenuState | null): void;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { handleSettingsFrame, renderSettingsFrame };
|
|
12
|
+
//# sourceMappingURL=settings.d.mts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
import { drawSlider, updateSlider } from "@starweb-libs/ui/slider.js";
|
|
6
|
+
//#region src/settings.ts
|
|
7
|
+
function handleSettingsFrame(w, h, volState, a) {
|
|
8
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
9
|
+
const titleY = scale * .15;
|
|
10
|
+
const muteBtn = {
|
|
11
|
+
x: cx - btnW / 2,
|
|
12
|
+
y: cy - btnH / 2,
|
|
13
|
+
w: btnW,
|
|
14
|
+
h: btnH,
|
|
15
|
+
label: a.muted ? "Unmute" : "Mute"
|
|
16
|
+
};
|
|
17
|
+
const backBtn = {
|
|
18
|
+
x: cx - btnW / 2,
|
|
19
|
+
y: h - btnH - gap * 2,
|
|
20
|
+
w: btnW,
|
|
21
|
+
h: btnH,
|
|
22
|
+
label: "Back"
|
|
23
|
+
};
|
|
24
|
+
const volSlider = {
|
|
25
|
+
x: cx - btnW / 2,
|
|
26
|
+
y: cy + btnH / 2 + gap,
|
|
27
|
+
w: btnW,
|
|
28
|
+
h: btnH,
|
|
29
|
+
label: "Volume"
|
|
30
|
+
};
|
|
31
|
+
const mute = {
|
|
32
|
+
btn: muteBtn,
|
|
33
|
+
state: getButtonState(muteBtn, getPointer())
|
|
34
|
+
};
|
|
35
|
+
const back = {
|
|
36
|
+
btn: backBtn,
|
|
37
|
+
state: getButtonState(backBtn, getPointer())
|
|
38
|
+
};
|
|
39
|
+
if (mute.state.clicked) a.setMuted(!a.muted);
|
|
40
|
+
volState = updateSlider(volSlider, volState, getPointer());
|
|
41
|
+
a.setVolume(volState.value);
|
|
42
|
+
const ui = {
|
|
43
|
+
cx,
|
|
44
|
+
scale,
|
|
45
|
+
titleY,
|
|
46
|
+
mute,
|
|
47
|
+
back,
|
|
48
|
+
vol: {
|
|
49
|
+
slider: volSlider,
|
|
50
|
+
state: volState
|
|
51
|
+
},
|
|
52
|
+
muted: a.muted
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
frame: ui.back.state.clicked ? transition({
|
|
56
|
+
game: "menu-title",
|
|
57
|
+
ui: null
|
|
58
|
+
}, a) : {
|
|
59
|
+
game: "menu-settings",
|
|
60
|
+
ui
|
|
61
|
+
},
|
|
62
|
+
volState
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function renderSettingsFrame(ctx, ui) {
|
|
66
|
+
if (!ui) return;
|
|
67
|
+
drawTitle(ctx, "Settings", ui.cx, ui.titleY, ui.scale);
|
|
68
|
+
drawButton(ctx, ui.mute.btn, ui.mute.state);
|
|
69
|
+
drawSlider(ctx, ui.vol.slider, ui.vol.state.value);
|
|
70
|
+
drawButton(ctx, ui.back.btn, ui.back.state);
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { handleSettingsFrame, renderSettingsFrame };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=settings.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.mjs","names":[],"sources":["../src/settings.ts"],"sourcesContent":["import type { Button, Slider, SliderState } from \"@starweb-libs/ui/types.js\";\nimport type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport { updateSlider, drawSlider } from \"@starweb-libs/ui/slider.js\";\nimport type { SettingsFrame, SettingsMenuState } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handleSettingsFrame(\n w: number, h: number, volState: SliderState, a: Audio,\n): { frame: SettingsFrame; volState: SliderState } {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const titleY = scale * 0.15;\n\n const muteBtn: Button = { x: cx - btnW/2, y: cy - btnH/2, w: btnW, h: btnH, label: a.muted ? \"Unmute\" : \"Mute\" };\n const backBtn: Button = { x: cx - btnW/2, y: h - btnH - gap*2, w: btnW, h: btnH, label: \"Back\" };\n const volSlider: Slider = { x: cx - btnW/2, y: cy + btnH/2 + gap, w: btnW, h: btnH, label: \"Volume\" };\n\n const mute = { btn: muteBtn, state: getButtonState(muteBtn, getPointer()) };\n const back = { btn: backBtn, state: getButtonState(backBtn, getPointer()) };\n\n if (mute.state.clicked) a.setMuted(!a.muted);\n volState = updateSlider(volSlider, volState, getPointer());\n a.setVolume(volState.value);\n\n const ui = { cx, scale, titleY, mute, back, vol: { slider: volSlider, state: volState }, muted: a.muted };\n const frame: SettingsFrame = ui.back.state.clicked\n ? transition({ game: \"menu-title\", ui: null }, a)\n : { game: \"menu-settings\", ui };\n return { frame, volState };\n}\n\nexport function renderSettingsFrame(\n ctx: CanvasRenderingContext2D,\n ui: SettingsMenuState | null\n): void {\n if (!ui) return;\n drawTitle(ctx, \"Settings\", ui.cx, ui.titleY, ui.scale);\n drawButton(ctx, ui.mute.btn, ui.mute.state);\n drawSlider(ctx, ui.vol.slider, ui.vol.state.value);\n drawButton(ctx, ui.back.btn, ui.back.state);\n}\n"],"mappings":";;;;;;AASA,SAAgB,oBACd,GAAW,GAAW,UAAuB,GACI;CACjD,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CACzD,MAAM,SAAS,QAAQ;CAEvB,MAAM,UAAoB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,KAAK,OAAK;EAAS,GAAG;EAAM,GAAG;EAAM,OAAO,EAAE,QAAQ,WAAW;CAAO;CACvH,MAAM,UAAoB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,IAAI,OAAO,MAAI;EAAI,GAAG;EAAM,GAAG;EAAM,OAAO;CAAO;CAClG,MAAM,YAAoB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,KAAK,OAAK,IAAI;EAAK,GAAG;EAAM,GAAG;EAAM,OAAO;CAAS;CAEpG,MAAM,OAAO;EAAE,KAAK;EAAS,OAAO,eAAe,SAAS,WAAW,CAAC;CAAE;CAC1E,MAAM,OAAO;EAAE,KAAK;EAAS,OAAO,eAAe,SAAS,WAAW,CAAC;CAAE;CAE1E,IAAI,KAAK,MAAM,SAAS,EAAE,SAAS,CAAC,EAAE,KAAK;CAC3C,WAAW,aAAa,WAAW,UAAU,WAAW,CAAC;CACzD,EAAE,UAAU,SAAS,KAAK;CAE1B,MAAM,KAAK;EAAE;EAAI;EAAO;EAAQ;EAAM;EAAM,KAAK;GAAE,QAAQ;GAAW,OAAO;EAAS;EAAG,OAAO,EAAE;CAAM;CAIxG,OAAO;EAAE,OAHoB,GAAG,KAAK,MAAM,UACvC,WAAW;GAAE,MAAM;GAAc,IAAI;EAAK,GAAG,CAAC,IAC9C;GAAE,MAAM;GAAiB;EAAG;EAChB;CAAS;AAC3B;AAEA,SAAgB,oBACd,KACA,IACM;CACN,IAAI,CAAC,IAAI;CACT,UAAU,KAAK,YAAY,GAAG,IAAI,GAAG,QAAQ,GAAG,KAAK;CACrD,WAAW,KAAK,GAAG,KAAK,KAAO,GAAG,KAAK,KAAK;CAC5C,WAAW,KAAK,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,KAAK;CACjD,WAAW,KAAK,GAAG,KAAK,KAAO,GAAG,KAAK,KAAK;AAC9C"}
|
package/dist/title.d.mts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TitleFrame, TitleMenuState } from "./types.mjs";
|
|
2
|
+
import { Audio } from "@starweb-libs/audio/audio.js";
|
|
3
|
+
//#region src/title.d.ts
|
|
4
|
+
declare function handleTitleFrame(w: number, h: number, a: Audio, levelCount: number, onStart?: () => void): TitleFrame;
|
|
5
|
+
declare function renderTitleFrame(ctx: CanvasRenderingContext2D, ui: TitleMenuState | null, text: string, scaleFactor: number): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { handleTitleFrame, renderTitleFrame };
|
|
8
|
+
//# sourceMappingURL=title.d.mts.map
|
package/dist/title.mjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { transition } from "./transition.mjs";
|
|
2
|
+
import { getPointer } from "@starweb-libs/engine/input/pointer.js";
|
|
3
|
+
import { drawTitle, getLayout } from "@starweb-libs/ui/layout.js";
|
|
4
|
+
import { drawButton, getButtonState } from "@starweb-libs/ui/button.js";
|
|
5
|
+
//#region src/title.ts
|
|
6
|
+
function handleTitleFrame(w, h, a, levelCount, onStart) {
|
|
7
|
+
const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);
|
|
8
|
+
const titleY = cy - btnH * 1.5 - gap * 2;
|
|
9
|
+
const startBtn = {
|
|
10
|
+
x: cx - btnW / 2,
|
|
11
|
+
y: cy - btnH / 2,
|
|
12
|
+
w: btnW,
|
|
13
|
+
h: btnH,
|
|
14
|
+
label: "START"
|
|
15
|
+
};
|
|
16
|
+
const settingsBtn = {
|
|
17
|
+
x: cx - btnW / 2,
|
|
18
|
+
y: cy + btnH / 2 + gap,
|
|
19
|
+
w: btnW,
|
|
20
|
+
h: btnH,
|
|
21
|
+
label: "SETTINGS"
|
|
22
|
+
};
|
|
23
|
+
const ui = {
|
|
24
|
+
cx,
|
|
25
|
+
scale,
|
|
26
|
+
titleY,
|
|
27
|
+
start: {
|
|
28
|
+
btn: startBtn,
|
|
29
|
+
state: getButtonState(startBtn, getPointer())
|
|
30
|
+
},
|
|
31
|
+
settings: {
|
|
32
|
+
btn: settingsBtn,
|
|
33
|
+
state: getButtonState(settingsBtn, getPointer())
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
if (ui.start.state.clicked) return transition(levelCount > 1 ? {
|
|
37
|
+
game: "menu-levels",
|
|
38
|
+
ui: null
|
|
39
|
+
} : {
|
|
40
|
+
game: "level-playing",
|
|
41
|
+
ui: null
|
|
42
|
+
}, a, onStart);
|
|
43
|
+
if (ui.settings.state.clicked) return transition({
|
|
44
|
+
game: "menu-settings",
|
|
45
|
+
ui: null
|
|
46
|
+
}, a);
|
|
47
|
+
return {
|
|
48
|
+
game: "menu-title",
|
|
49
|
+
ui
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function renderTitleFrame(ctx, ui, text, scaleFactor) {
|
|
53
|
+
if (!ui) return;
|
|
54
|
+
drawTitle(ctx, text, ui.cx, ui.titleY, ui.scale, scaleFactor);
|
|
55
|
+
drawButton(ctx, ui.start.btn, ui.start.state);
|
|
56
|
+
drawButton(ctx, ui.settings.btn, ui.settings.state);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { handleTitleFrame, renderTitleFrame };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=title.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title.mjs","names":[],"sources":["../src/title.ts"],"sourcesContent":["import type { Button } from \"@starweb-libs/ui/types.js\";\nimport type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { getPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { getLayout, drawTitle } from \"@starweb-libs/ui/layout.js\";\nimport { getButtonState, drawButton } from \"@starweb-libs/ui/button.js\";\nimport type { TitleFrame, TitleMenuState } from \"./types.ts\";\nimport { transition } from \"./transition.ts\";\n\nexport function handleTitleFrame(\n w: number, h: number, a: Audio,\n levelCount: number,\n onStart?: () => void,\n): TitleFrame {\n const { scale, gap, cx, cy, btnW, btnH } = getLayout(w, h);\n const titleY = cy - btnH * 1.5 - gap * 2;\n\n const startBtn: Button = { x: cx - btnW/2, y: cy - btnH/2, w: btnW, h: btnH, label: \"START\" };\n const settingsBtn: Button = { x: cx - btnW/2, y: cy + btnH/2 + gap, w: btnW, h: btnH, label: \"SETTINGS\" };\n\n const ui = {\n cx, scale, titleY,\n start: { btn: startBtn, state: getButtonState(startBtn, getPointer()) },\n settings: { btn: settingsBtn, state: getButtonState(settingsBtn, getPointer()) },\n };\n\n if (ui.start.state.clicked) return transition(\n levelCount > 1\n ? { game: \"menu-levels\", ui: null }\n : { game: \"level-playing\", ui: null },\n a,\n onStart,\n );\n if (ui.settings.state.clicked) return transition({ game: \"menu-settings\", ui: null }, a);\n return { game: \"menu-title\", ui };\n}\n\nexport function renderTitleFrame(\n ctx: CanvasRenderingContext2D,\n ui: TitleMenuState | null,\n text: string,\n scaleFactor: number,\n): void {\n if (!ui) return;\n drawTitle(ctx, text, ui.cx, ui.titleY, ui.scale, scaleFactor);\n drawButton(ctx, ui.start.btn, ui.start.state);\n drawButton(ctx, ui.settings.btn, ui.settings.state);\n}\n"],"mappings":";;;;;AAQA,SAAgB,iBACd,GAAW,GAAW,GACtB,YACA,SACY;CACZ,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,UAAU,GAAG,CAAC;CACzD,MAAM,SAAS,KAAK,OAAO,MAAM,MAAM;CAEvC,MAAM,WAAsB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,KAAK,OAAK;EAAS,GAAG;EAAM,GAAG;EAAM,OAAO;CAAW;CACxG,MAAM,cAAsB;EAAE,GAAG,KAAK,OAAK;EAAG,GAAG,KAAK,OAAK,IAAI;EAAK,GAAG;EAAM,GAAG;EAAM,OAAO;CAAW;CAExG,MAAM,KAAK;EACT;EAAI;EAAO;EACX,OAAU;GAAE,KAAK;GAAa,OAAO,eAAe,UAAU,WAAW,CAAC;EAAK;EAC/E,UAAU;GAAE,KAAK;GAAa,OAAO,eAAe,aAAa,WAAW,CAAC;EAAE;CACjF;CAEA,IAAI,GAAG,MAAM,MAAM,SAAS,OAAO,WACjC,aAAa,IACT;EAAE,MAAM;EAAe,IAAI;CAAK,IAChC;EAAE,MAAM;EAAiB,IAAI;CAAK,GACtC,GACA,OACF;CACA,IAAI,GAAG,SAAS,MAAM,SAAS,OAAO,WAAW;EAAE,MAAM;EAAiB,IAAI;CAAK,GAAG,CAAC;CACvF,OAAO;EAAE,MAAM;EAAc;CAAG;AAClC;AAEA,SAAgB,iBACd,KACA,IACA,MACA,aACM;CACN,IAAI,CAAC,IAAI;CACT,UAAU,KAAK,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,OAAO,WAAW;CAC5D,WAAW,KAAK,GAAG,MAAM,KAAQ,GAAG,MAAM,KAAK;CAC/C,WAAW,KAAK,GAAG,SAAS,KAAK,GAAG,SAAS,KAAK;AACpD"}
|
package/dist/transition.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transition.mjs","names":[],"sources":["../src/transition.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"transition.mjs","names":[],"sources":["../src/transition.ts"],"sourcesContent":["import type { Audio } from \"@starweb-libs/audio/audio.js\";\nimport { flushPointer } from \"@starweb-libs/engine/input/pointer.js\";\nimport { flushKeyboard } from \"@starweb-libs/engine/input/keyboard.js\";\n\nexport function transition<T>(frame: T, audio: Audio, fn?: () => void): T {\n audio.playSound(\"button\");\n fn?.();\n flushPointer();\n flushKeyboard();\n return frame;\n}\n"],"mappings":";;;AAIA,SAAgB,WAAc,OAAU,OAAc,IAAoB;CACxE,MAAM,UAAU,QAAQ;CACxB,KAAK;CACL,aAAa;CACb,cAAc;CACd,OAAO;AACT"}
|
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ButtonEntry, MenuLayout, SliderEntry } from "@starweb-libs/ui/types.js";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
interface TitleMenuState extends MenuLayout {
|
|
4
|
+
start: ButtonEntry;
|
|
5
|
+
settings: ButtonEntry;
|
|
6
|
+
}
|
|
7
|
+
type TitleFrame = {
|
|
8
|
+
game: "menu-levels";
|
|
9
|
+
ui: null;
|
|
10
|
+
} | {
|
|
11
|
+
game: "level-playing";
|
|
12
|
+
ui: null;
|
|
13
|
+
} | {
|
|
14
|
+
game: "menu-settings";
|
|
15
|
+
ui: null;
|
|
16
|
+
} | {
|
|
17
|
+
game: "menu-title";
|
|
18
|
+
ui: TitleMenuState;
|
|
19
|
+
};
|
|
20
|
+
type SettingsFrame = {
|
|
21
|
+
game: "menu-title";
|
|
22
|
+
ui: null;
|
|
23
|
+
} | {
|
|
24
|
+
game: "menu-settings";
|
|
25
|
+
ui: SettingsMenuState;
|
|
26
|
+
};
|
|
27
|
+
interface SettingsMenuState extends MenuLayout {
|
|
28
|
+
mute: ButtonEntry;
|
|
29
|
+
back: ButtonEntry;
|
|
30
|
+
vol: SliderEntry;
|
|
31
|
+
muted: boolean;
|
|
32
|
+
}
|
|
33
|
+
type LevelsFrame = {
|
|
34
|
+
game: "menu-title";
|
|
35
|
+
ui: null;
|
|
36
|
+
} | {
|
|
37
|
+
game: "level-playing";
|
|
38
|
+
ui: null;
|
|
39
|
+
} | {
|
|
40
|
+
game: "menu-levels";
|
|
41
|
+
ui: LevelSelectState;
|
|
42
|
+
};
|
|
43
|
+
interface LevelSelectState extends MenuLayout {
|
|
44
|
+
levels: ButtonEntry[];
|
|
45
|
+
back: ButtonEntry;
|
|
46
|
+
clickedIndex: number | null;
|
|
47
|
+
}
|
|
48
|
+
type PauseFrame = {
|
|
49
|
+
game: "level-playing";
|
|
50
|
+
ui: null;
|
|
51
|
+
} | {
|
|
52
|
+
game: "menu-title";
|
|
53
|
+
ui: null;
|
|
54
|
+
} | {
|
|
55
|
+
game: "level-paused";
|
|
56
|
+
ui: PauseMenuState;
|
|
57
|
+
};
|
|
58
|
+
type PauseAction = "resume" | "restart" | "quit" | null;
|
|
59
|
+
interface PauseMenuState extends MenuLayout {
|
|
60
|
+
resume: ButtonEntry;
|
|
61
|
+
restart: ButtonEntry;
|
|
62
|
+
quit: ButtonEntry;
|
|
63
|
+
action: PauseAction;
|
|
64
|
+
}
|
|
65
|
+
type FailedFrame = {
|
|
66
|
+
game: "menu-title";
|
|
67
|
+
ui: null;
|
|
68
|
+
} | {
|
|
69
|
+
game: "level-playing";
|
|
70
|
+
ui: null;
|
|
71
|
+
} | {
|
|
72
|
+
game: "level-failed";
|
|
73
|
+
ui: FailedMenuState;
|
|
74
|
+
};
|
|
75
|
+
type FailedAction = "restart" | "quit" | null;
|
|
76
|
+
interface FailedMenuState extends MenuLayout {
|
|
77
|
+
restart: ButtonEntry;
|
|
78
|
+
quit: ButtonEntry;
|
|
79
|
+
action: FailedAction;
|
|
80
|
+
}
|
|
81
|
+
type CompleteFrame = {
|
|
82
|
+
game: "menu-title";
|
|
83
|
+
ui: null;
|
|
84
|
+
} | {
|
|
85
|
+
game: "level-playing";
|
|
86
|
+
ui: null;
|
|
87
|
+
} | {
|
|
88
|
+
game: "level-complete";
|
|
89
|
+
ui: CompleteMenuState;
|
|
90
|
+
};
|
|
91
|
+
type CompleteAction = "next" | "restart" | "quit" | null;
|
|
92
|
+
interface CompleteMenuState extends MenuLayout {
|
|
93
|
+
restart: ButtonEntry;
|
|
94
|
+
next: ButtonEntry | null;
|
|
95
|
+
quit: ButtonEntry;
|
|
96
|
+
action: CompleteAction;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { CompleteAction, CompleteFrame, CompleteMenuState, FailedAction, FailedFrame, FailedMenuState, LevelSelectState, LevelsFrame, PauseAction, PauseFrame, PauseMenuState, SettingsFrame, SettingsMenuState, TitleFrame, TitleMenuState };
|
|
100
|
+
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@starweb-libs/menus",
|
|
3
3
|
"description": "Composable canvas menu screens for browser games",
|
|
4
4
|
"author": "Mason L'Etoile",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.3",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -39,10 +39,13 @@
|
|
|
39
39
|
},
|
|
40
40
|
"files": ["dist"],
|
|
41
41
|
"exports": {
|
|
42
|
-
"./
|
|
43
|
-
|
|
44
|
-
"@starweb-libs/source": "./src/
|
|
45
|
-
|
|
46
|
-
}
|
|
42
|
+
"./types.js": { "types": "./dist/types.d.mts", "@starweb-libs/source": "./src/types.ts", "import": "./dist/types.mjs" },
|
|
43
|
+
"./transition.js": { "types": "./dist/transition.d.mts", "@starweb-libs/source": "./src/transition.ts", "import": "./dist/transition.mjs" },
|
|
44
|
+
"./title.js": { "types": "./dist/title.d.mts", "@starweb-libs/source": "./src/title.ts", "import": "./dist/title.mjs" },
|
|
45
|
+
"./settings.js": { "types": "./dist/settings.d.mts", "@starweb-libs/source": "./src/settings.ts", "import": "./dist/settings.mjs" },
|
|
46
|
+
"./levels.js": { "types": "./dist/levels.d.mts", "@starweb-libs/source": "./src/levels.ts", "import": "./dist/levels.mjs" },
|
|
47
|
+
"./pause.js": { "types": "./dist/pause.d.mts", "@starweb-libs/source": "./src/pause.ts", "import": "./dist/pause.mjs" },
|
|
48
|
+
"./complete.js": { "types": "./dist/complete.d.mts", "@starweb-libs/source": "./src/complete.ts", "import": "./dist/complete.mjs" },
|
|
49
|
+
"./failed.js": { "types": "./dist/failed.d.mts", "@starweb-libs/source": "./src/failed.ts", "import": "./dist/failed.mjs" }
|
|
47
50
|
}
|
|
48
51
|
}
|