@zylem/game-lib 0.3.15 → 0.3.17

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 (119) hide show
  1. package/README.md +38 -13
  2. package/dist/.vite/manifest.json +665 -2
  3. package/dist/actions.d.ts +4 -0
  4. package/dist/actions.js +10 -0
  5. package/dist/behaviors.d.ts +3 -0
  6. package/dist/behaviors.js +8 -0
  7. package/dist/camera.d.ts +3 -0
  8. package/dist/camera.js +6 -0
  9. package/dist/core.d.ts +5 -0
  10. package/dist/core.js +11 -0
  11. package/dist/entities.d.ts +8 -0
  12. package/dist/entities.js +19 -0
  13. package/dist/lib/actions/behaviors/actions.js +35 -0
  14. package/dist/lib/actions/behaviors/boundaries/boundary.d.ts +1 -1
  15. package/dist/lib/actions/behaviors/boundaries/boundary.js +40 -0
  16. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-collision.js +100 -0
  17. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.js +37 -0
  18. package/dist/lib/actions/behaviors/ricochet/ricochet.d.ts +2 -0
  19. package/dist/lib/actions/behaviors/ricochet/ricochet.js +6 -0
  20. package/dist/lib/actions/capabilities/moveable.js +108 -0
  21. package/dist/lib/actions/capabilities/rotatable.js +82 -0
  22. package/dist/lib/actions/capabilities/transformable.js +9 -0
  23. package/dist/lib/actions/global-change.js +40 -0
  24. package/dist/lib/camera/camera.js +19 -0
  25. package/dist/lib/camera/fixed-2d.js +30 -0
  26. package/dist/lib/camera/perspective.js +10 -0
  27. package/dist/lib/camera/third-person.js +42 -0
  28. package/dist/lib/camera/zylem-camera.js +145 -0
  29. package/dist/lib/collision/collision-builder.js +46 -0
  30. package/dist/lib/collision/collision-delegate.js +6 -0
  31. package/dist/lib/collision/utils.js +24 -0
  32. package/dist/lib/collision/world.js +77 -0
  33. package/dist/lib/core/base-node-life-cycle.d.ts +14 -0
  34. package/dist/lib/core/base-node.d.ts +6 -2
  35. package/dist/lib/core/base-node.js +62 -0
  36. package/dist/lib/core/entity-asset-loader.js +57 -0
  37. package/dist/lib/core/lazy-loader.d.ts +2 -2
  38. package/dist/lib/core/lifecycle-base.js +20 -0
  39. package/dist/lib/core/preset-shader.js +30 -0
  40. package/dist/lib/core/three-addons/Timer.js +103 -0
  41. package/dist/lib/core/utility/nodes.d.ts +11 -0
  42. package/dist/lib/core/utility/nodes.js +27 -0
  43. package/dist/lib/core/utility/strings.d.ts +2 -0
  44. package/dist/lib/core/utility/strings.js +14 -0
  45. package/dist/lib/core/{utility.d.ts → utility/vector.d.ts} +0 -2
  46. package/dist/lib/core/utility/vector.js +8 -0
  47. package/dist/lib/core/vessel.d.ts +3 -1
  48. package/dist/lib/core/vessel.js +27 -0
  49. package/dist/lib/debug/console/console-state.js +11 -0
  50. package/dist/lib/debug/debug-state.js +40 -0
  51. package/dist/lib/device/aspect-ratio.d.ts +37 -0
  52. package/dist/lib/device/aspect-ratio.js +44 -0
  53. package/dist/lib/entities/actor.js +125 -0
  54. package/dist/lib/entities/box.js +68 -0
  55. package/dist/lib/entities/builder.js +79 -0
  56. package/dist/lib/entities/create.js +31 -0
  57. package/dist/lib/entities/delegates/animation.js +58 -0
  58. package/dist/lib/entities/delegates/debug.js +72 -0
  59. package/dist/lib/entities/delegates/loader.js +19 -0
  60. package/dist/lib/entities/destroy.js +15 -0
  61. package/dist/lib/entities/entity.d.ts +3 -1
  62. package/dist/lib/entities/entity.js +120 -0
  63. package/dist/lib/entities/plane.js +81 -0
  64. package/dist/lib/entities/rect.js +160 -0
  65. package/dist/lib/entities/sphere.js +68 -0
  66. package/dist/lib/entities/sprite.js +118 -0
  67. package/dist/lib/entities/text.js +111 -0
  68. package/dist/lib/entities/zone.js +103 -0
  69. package/dist/lib/game/game-blueprint.d.ts +44 -0
  70. package/dist/lib/game/game-canvas.d.ts +34 -0
  71. package/dist/lib/game/game-canvas.js +57 -0
  72. package/dist/lib/game/game-config.d.ts +47 -0
  73. package/dist/lib/game/game-config.js +53 -0
  74. package/dist/lib/game/game-default.d.ts +18 -0
  75. package/dist/lib/game/game-default.js +24 -0
  76. package/dist/lib/game/game-state.js +17 -0
  77. package/dist/lib/game/game.d.ts +2 -5
  78. package/dist/lib/game/game.js +133 -0
  79. package/dist/lib/game/zylem-game.d.ts +12 -1
  80. package/dist/lib/game/zylem-game.js +133 -0
  81. package/dist/lib/graphics/geometries/XZPlaneGeometry.js +34 -0
  82. package/dist/lib/graphics/material.d.ts +1 -1
  83. package/dist/lib/graphics/material.js +64 -0
  84. package/dist/lib/graphics/mesh.js +14 -0
  85. package/dist/lib/graphics/render-pass.js +56 -0
  86. package/dist/lib/graphics/shaders/fragment/debug.glsl.js +23 -0
  87. package/dist/lib/graphics/shaders/fragment/fire.glsl.js +52 -0
  88. package/dist/lib/graphics/shaders/fragment/standard.glsl.js +11 -0
  89. package/dist/lib/graphics/shaders/fragment/stars.glsl.js +44 -0
  90. package/dist/lib/graphics/shaders/vertex/debug.glsl.js +15 -0
  91. package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +11 -0
  92. package/dist/lib/graphics/shaders/vertex/standard.glsl.js +9 -0
  93. package/dist/lib/graphics/zylem-scene.d.ts +7 -7
  94. package/dist/lib/graphics/zylem-scene.js +75 -0
  95. package/dist/lib/input/gamepad-provider.js +58 -0
  96. package/dist/lib/input/input-manager.js +70 -0
  97. package/dist/lib/input/keyboard-provider.js +120 -0
  98. package/dist/lib/stage/debug-entity-cursor.js +53 -0
  99. package/dist/lib/stage/entity-spawner.js +27 -0
  100. package/dist/lib/stage/stage-blueprint.d.ts +44 -0
  101. package/dist/lib/stage/stage-blueprint.js +56 -0
  102. package/dist/lib/stage/stage-debug-delegate.js +100 -0
  103. package/dist/lib/stage/stage-default.d.ts +9 -0
  104. package/dist/lib/stage/stage-default.js +42 -0
  105. package/dist/lib/stage/stage-state.js +36 -0
  106. package/dist/lib/stage/stage.d.ts +2 -2
  107. package/dist/lib/stage/stage.js +60 -0
  108. package/dist/lib/stage/zylem-stage.d.ts +4 -3
  109. package/dist/lib/stage/zylem-stage.js +268 -0
  110. package/dist/lib/systems/transformable.system.js +43 -0
  111. package/dist/main.d.ts +6 -15
  112. package/dist/main.js +56 -45933
  113. package/dist/stage.d.ts +6 -0
  114. package/dist/stage.js +22 -0
  115. package/dist/tests/stage/stage-blueprint.spec.d.ts +1 -0
  116. package/package.json +35 -1
  117. package/dist/lib/actions/behaviors/index.d.ts +0 -1
  118. package/dist/lib/core/game-canvas.d.ts +0 -4
  119. package/dist/main.cjs +0 -4023
@@ -0,0 +1,111 @@
1
+ import { Vector2 as u, Group as H, CanvasTexture as w, LinearFilter as l, SpriteMaterial as k, Sprite as M, ClampToEdgeWrapping as C, Color as v } from "three";
2
+ import { GameEntity as R } from "./entity.js";
3
+ import { EntityBuilder as W } from "./builder.js";
4
+ import { createEntity as E } from "./create.js";
5
+ import { DebugDelegate as D } from "./delegates/debug.js";
6
+ const x = {
7
+ position: void 0,
8
+ text: "",
9
+ fontFamily: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
10
+ fontSize: 18,
11
+ fontColor: "#FFFFFF",
12
+ backgroundColor: null,
13
+ padding: 4,
14
+ stickToViewport: !0,
15
+ screenPosition: new u(24, 24),
16
+ zDistance: 1
17
+ };
18
+ class P extends W {
19
+ createEntity(t) {
20
+ return new o(t);
21
+ }
22
+ }
23
+ const z = Symbol("Text");
24
+ class o extends R {
25
+ static type = z;
26
+ _sprite = null;
27
+ _texture = null;
28
+ _canvas = null;
29
+ _ctx = null;
30
+ _cameraRef = null;
31
+ _lastCanvasW = 0;
32
+ _lastCanvasH = 0;
33
+ constructor(t) {
34
+ super(), this.options = { ...x, ...t }, this.group = new H(), this.createSprite(), this.lifeCycleDelegate = {
35
+ setup: [this.textSetup.bind(this)],
36
+ update: [this.textUpdate.bind(this)]
37
+ };
38
+ }
39
+ createSprite() {
40
+ this._canvas = document.createElement("canvas"), this._ctx = this._canvas.getContext("2d"), this._texture = new w(this._canvas), this._texture.minFilter = l, this._texture.magFilter = l;
41
+ const t = new k({
42
+ map: this._texture,
43
+ transparent: !0,
44
+ depthTest: !1,
45
+ depthWrite: !1,
46
+ alphaTest: 0.5
47
+ });
48
+ this._sprite = new M(t), this.group?.add(this._sprite), this.redrawText(this.options.text ?? "");
49
+ }
50
+ redrawText(t) {
51
+ if (!this._canvas || !this._ctx)
52
+ return;
53
+ const e = this.options.fontSize ?? 18, r = this.options.fontFamily ?? x.fontFamily, a = this.options.padding ?? 4;
54
+ this._ctx.font = `${e}px ${r}`;
55
+ const p = this._ctx.measureText(t), _ = Math.ceil(p.width), h = Math.ceil(e * 1.4), n = Math.max(2, _ + a * 2), s = Math.max(2, h + a * 2), f = n !== this._lastCanvasW || s !== this._lastCanvasH;
56
+ this._canvas.width = n, this._canvas.height = s, this._lastCanvasW = n, this._lastCanvasH = s, this._ctx.font = `${e}px ${r}`, this._ctx.textBaseline = "top", this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height), this.options.backgroundColor && (this._ctx.fillStyle = this.toCssColor(this.options.backgroundColor), this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height)), this._ctx.fillStyle = this.toCssColor(this.options.fontColor ?? "#FFFFFF"), this._ctx.fillText(t, a, a), this._texture && (f && (this._texture.dispose(), this._texture = new w(this._canvas), this._texture.minFilter = l, this._texture.magFilter = l, this._texture.wrapS = C, this._texture.wrapT = C), this._texture.image = this._canvas, this._texture.needsUpdate = !0, this._sprite && this._sprite.material && (this._sprite.material.map = this._texture, this._sprite.material.needsUpdate = !0));
57
+ }
58
+ toCssColor(t) {
59
+ return typeof t == "string" ? t : `#${(t instanceof v ? t : new v(t)).getHexString()}`;
60
+ }
61
+ textSetup(t) {
62
+ this._cameraRef = t.camera, this.options.stickToViewport && this._cameraRef && this._cameraRef.camera.add(this.group);
63
+ }
64
+ textUpdate(t) {
65
+ this._sprite && this.options.stickToViewport && this._cameraRef && this.updateStickyTransform();
66
+ }
67
+ updateStickyTransform() {
68
+ if (!this._sprite || !this._cameraRef)
69
+ return;
70
+ const t = this._cameraRef.camera, e = this._cameraRef.renderer.domElement, r = e.clientWidth, a = e.clientHeight, p = (this.options.screenPosition ?? new u(24, 24)).x, _ = (this.options.screenPosition ?? new u(24, 24)).y, h = Math.max(1e-3, this.options.zDistance ?? 1);
71
+ let n = 1, s = 1;
72
+ if (t.isPerspectiveCamera) {
73
+ const i = t, c = Math.tan(i.fov * Math.PI / 180 / 2) * h;
74
+ n = c * i.aspect, s = c;
75
+ } else if (t.isOrthographicCamera) {
76
+ const i = t;
77
+ n = (i.right - i.left) / 2, s = (i.top - i.bottom) / 2;
78
+ }
79
+ const f = p / r * 2 - 1, y = 1 - _ / a * 2, T = f * n, F = y * s;
80
+ if (this.group?.position.set(T, F, -h), this._canvas) {
81
+ const c = s * 2 / a, m = this._canvas.height, g = Math.max(1e-4, m * c), S = this._canvas.width / this._canvas.height, b = g * S;
82
+ this._sprite.scale.set(b, g, 1);
83
+ }
84
+ }
85
+ updateText(t) {
86
+ this.options.text = t, this.redrawText(t), this.options.stickToViewport && this._cameraRef && this.updateStickyTransform();
87
+ }
88
+ buildInfo() {
89
+ return {
90
+ ...new D(this).buildDebugInfo(),
91
+ type: String(o.type),
92
+ text: this.options.text ?? "",
93
+ sticky: this.options.stickToViewport
94
+ };
95
+ }
96
+ }
97
+ async function X(...d) {
98
+ return E({
99
+ args: d,
100
+ defaultConfig: { ...x },
101
+ EntityClass: o,
102
+ BuilderClass: P,
103
+ entityType: o.type
104
+ });
105
+ }
106
+ export {
107
+ z as TEXT_TYPE,
108
+ P as TextBuilder,
109
+ o as ZylemText,
110
+ X as text
111
+ };
@@ -0,0 +1,103 @@
1
+ import { ColliderDesc as a, ActiveCollisionTypes as h } from "@dimforge/rapier3d-compat";
2
+ import { Vector3 as l } from "three";
3
+ import { GameEntity as u } from "./entity.js";
4
+ import { EntityCollisionBuilder as c, EntityBuilder as p } from "./builder.js";
5
+ import { createEntity as E } from "./create.js";
6
+ import { state as o } from "../game/game-state.js";
7
+ const d = {
8
+ size: new l(1, 1, 1),
9
+ position: new l(0, 0, 0),
10
+ collision: {
11
+ static: !0
12
+ },
13
+ material: {
14
+ shader: "standard"
15
+ }
16
+ };
17
+ class f extends c {
18
+ collider(e) {
19
+ const t = e.size || new l(1, 1, 1), i = { x: t.x / 2, y: t.y / 2, z: t.z / 2 };
20
+ let s = a.cuboid(i.x, i.y, i.z);
21
+ return s.setSensor(!0), s.activeCollisionTypes = h.KINEMATIC_FIXED, s;
22
+ }
23
+ }
24
+ class x extends p {
25
+ createEntity(e) {
26
+ return new r(e);
27
+ }
28
+ }
29
+ const Z = Symbol("Zone");
30
+ class r extends u {
31
+ static type = Z;
32
+ _enteredZone = /* @__PURE__ */ new Map();
33
+ _exitedZone = /* @__PURE__ */ new Map();
34
+ _zoneEntities = /* @__PURE__ */ new Map();
35
+ constructor(e) {
36
+ super(), this.options = { ...d, ...e };
37
+ }
38
+ handlePostCollision({ delta: e }) {
39
+ return this._enteredZone.forEach((t, i) => {
40
+ this.exited(e, i);
41
+ }), this._enteredZone.size > 0;
42
+ }
43
+ handleIntersectionEvent({ other: e, delta: t }) {
44
+ this._enteredZone.get(e.uuid) ? this.held(t, e) : (this.entered(e), this._zoneEntities.set(e.uuid, e));
45
+ }
46
+ onEnter(e) {
47
+ return this.options.onEnter = e, this;
48
+ }
49
+ onHeld(e) {
50
+ return this.options.onHeld = e, this;
51
+ }
52
+ onExit(e) {
53
+ return this.options.onExit = e, this;
54
+ }
55
+ entered(e) {
56
+ this._enteredZone.set(e.uuid, 1), this.options.onEnter && this.options.onEnter({
57
+ self: this,
58
+ visitor: e,
59
+ globals: o.globals
60
+ });
61
+ }
62
+ exited(e, t) {
63
+ const i = this._exitedZone.get(t);
64
+ if (i && i > 1 + e) {
65
+ this._exitedZone.delete(t), this._enteredZone.delete(t);
66
+ const s = this._zoneEntities.get(t);
67
+ this.options.onExit && this.options.onExit({
68
+ self: this,
69
+ visitor: s,
70
+ globals: o.globals
71
+ });
72
+ return;
73
+ }
74
+ this._exitedZone.set(t, 1 + e);
75
+ }
76
+ held(e, t) {
77
+ const i = this._enteredZone.get(t.uuid) ?? 0;
78
+ this._enteredZone.set(t.uuid, i + e), this._exitedZone.set(t.uuid, 1), this.options.onHeld && this.options.onHeld({
79
+ delta: e,
80
+ self: this,
81
+ visitor: t,
82
+ globals: o.globals,
83
+ heldTime: i
84
+ });
85
+ }
86
+ }
87
+ async function b(...n) {
88
+ return E({
89
+ args: n,
90
+ defaultConfig: d,
91
+ EntityClass: r,
92
+ BuilderClass: x,
93
+ CollisionBuilderClass: f,
94
+ entityType: r.type
95
+ });
96
+ }
97
+ export {
98
+ Z as ZONE_TYPE,
99
+ x as ZoneBuilder,
100
+ f as ZoneCollisionBuilder,
101
+ r as ZylemZone,
102
+ b as zone
103
+ };
@@ -0,0 +1,44 @@
1
+ import type { Stage } from '../stage/stage';
2
+ import type { BasicTypes, GlobalVariablesType, ZylemGameConfig } from './game-interfaces';
3
+ import type { GameOptions } from '../core/utility/nodes';
4
+ /**
5
+ * A lightweight, serializable blueprint representing the initial configuration
6
+ * of a `Game`. It should not include runtime references. Use blueprints only to
7
+ * build games.
8
+ */
9
+ export interface GameBlueprint<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType> {
10
+ id: string;
11
+ name?: string;
12
+ config: Partial<ZylemGameConfig<Stage, any, TGlobals>>;
13
+ }
14
+ export declare const gameBlueprintsState: {
15
+ byId: Record<string, GameBlueprint>;
16
+ order: string[];
17
+ currentId: string | null;
18
+ };
19
+ /** Reset the blueprints store back to its initial empty state. */
20
+ export declare function resetGameBlueprints(): void;
21
+ /** Create and register a new `GameBlueprint`. */
22
+ export declare function createGameBlueprint<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType>(config: Partial<ZylemGameConfig<Stage, any, TGlobals>>, options?: {
23
+ id?: string;
24
+ name?: string;
25
+ setCurrent?: boolean;
26
+ }): GameBlueprint<TGlobals>;
27
+ /** Upsert a blueprint into the store. */
28
+ export declare function upsertGameBlueprint<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType>(blueprint: GameBlueprint<TGlobals>): void;
29
+ /** Remove a blueprint by id. */
30
+ export declare function removeGameBlueprint(id: string): void;
31
+ /** Get a blueprint by id. */
32
+ export declare function getGameBlueprint(id: string): GameBlueprint | undefined;
33
+ /** List all blueprints in insertion order. */
34
+ export declare function listGameBlueprints(): GameBlueprint[];
35
+ /** Set the current blueprint id (or clear by passing null). */
36
+ export declare function setCurrentGameBlueprint(id: string | null): void;
37
+ /** Get the current blueprint object, if any. */
38
+ export declare function getCurrentGameBlueprint(): GameBlueprint | null;
39
+ /**
40
+ * Build a `Game` instance from a blueprint and optional extra `GameOptions`
41
+ * (e.g., additional stages or nodes). This returns a `Game` wrapper instance;
42
+ * call `.start()` to run it.
43
+ */
44
+ export declare function buildGameFromBlueprint<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType>(input: string | GameBlueprint<TGlobals>, ...extras: GameOptions<TGlobals>): import("./game").Game<TGlobals>;
@@ -0,0 +1,34 @@
1
+ import { AspectRatioValue } from '../device/aspect-ratio';
2
+ export interface GameCanvasOptions {
3
+ id: string;
4
+ container?: HTMLElement;
5
+ containerId?: string;
6
+ canvas?: HTMLCanvasElement;
7
+ bodyBackground?: string;
8
+ fullscreen?: boolean;
9
+ aspectRatio: AspectRatioValue | number;
10
+ }
11
+ /**
12
+ * GameCanvas is a DOM delegate that owns:
13
+ * - container lookup/creation and styling (including fullscreen centering)
14
+ * - body background application
15
+ * - canvas mounting into container
16
+ * - aspect ratio sizing via AspectRatioDelegate
17
+ */
18
+ export declare class GameCanvas {
19
+ id: string;
20
+ container: HTMLElement;
21
+ canvas: HTMLCanvasElement;
22
+ bodyBackground?: string;
23
+ fullscreen: boolean;
24
+ aspectRatio: number;
25
+ private ratioDelegate;
26
+ constructor(options: GameCanvasOptions);
27
+ applyBodyBackground(): void;
28
+ mountCanvas(): void;
29
+ mountRenderer(rendererDom: HTMLCanvasElement, onResize: (width: number, height: number) => void): void;
30
+ centerIfFullscreen(): void;
31
+ attachAspectRatio(onResize: (width: number, height: number) => void): void;
32
+ destroy(): void;
33
+ private ensureContainer;
34
+ }
@@ -0,0 +1,57 @@
1
+ import { AspectRatioDelegate as s } from "../device/aspect-ratio.js";
2
+ class o {
3
+ id;
4
+ container;
5
+ canvas;
6
+ bodyBackground;
7
+ fullscreen;
8
+ aspectRatio;
9
+ ratioDelegate = null;
10
+ constructor(t) {
11
+ this.id = t.id, this.container = this.ensureContainer(t.containerId ?? t.id, t.container), this.canvas = t.canvas ?? document.createElement("canvas"), this.bodyBackground = t.bodyBackground, this.fullscreen = !!t.fullscreen, this.aspectRatio = (typeof t.aspectRatio == "number", t.aspectRatio);
12
+ }
13
+ applyBodyBackground() {
14
+ this.bodyBackground && (document.body.style.background = this.bodyBackground);
15
+ }
16
+ mountCanvas() {
17
+ for (; this.container.firstChild; )
18
+ this.container.removeChild(this.container.firstChild);
19
+ this.container.appendChild(this.canvas);
20
+ }
21
+ mountRenderer(t, i) {
22
+ for (; this.container.firstChild; )
23
+ this.container.removeChild(this.container.firstChild);
24
+ this.container.appendChild(t), this.canvas = t, this.attachAspectRatio(i);
25
+ }
26
+ centerIfFullscreen() {
27
+ if (!this.fullscreen)
28
+ return;
29
+ const t = this.container.style;
30
+ t.display = "flex", t.alignItems = "center", t.justifyContent = "center", t.position = "fixed", t.inset = "0";
31
+ }
32
+ attachAspectRatio(t) {
33
+ this.ratioDelegate ? this.ratioDelegate.apply() : (this.ratioDelegate = new s({
34
+ container: this.container,
35
+ canvas: this.canvas,
36
+ aspectRatio: this.aspectRatio,
37
+ onResize: t
38
+ }), this.ratioDelegate.attach());
39
+ }
40
+ destroy() {
41
+ this.ratioDelegate?.detach(), this.ratioDelegate = null;
42
+ }
43
+ ensureContainer(t, i) {
44
+ if (i)
45
+ return i;
46
+ if (t) {
47
+ const a = document.getElementById(t);
48
+ if (a)
49
+ return a;
50
+ }
51
+ const n = t || this.id || "zylem-root", e = document.createElement("main");
52
+ return e.setAttribute("id", n), e.style.position = "relative", e.style.width = "100%", e.style.height = "100%", document.body.appendChild(e), e;
53
+ }
54
+ }
55
+ export {
56
+ o as GameCanvas
57
+ };
@@ -0,0 +1,47 @@
1
+ import { StageInterface } from "../types";
2
+ import { GameInputConfig } from "./game-interfaces";
3
+ import { AspectRatio, AspectRatioValue } from "../device/aspect-ratio";
4
+ export type GameConfigLike = Partial<{
5
+ id: string;
6
+ globals: Record<string, any>;
7
+ stages: StageInterface[];
8
+ debug: boolean;
9
+ time: number;
10
+ input: GameInputConfig;
11
+ /** numeric value or key in AspectRatio */
12
+ aspectRatio: AspectRatioValue | keyof typeof AspectRatio;
13
+ fullscreen: boolean;
14
+ /** CSS background value for document body */
15
+ bodyBackground: string;
16
+ /** existing container by reference */
17
+ container: HTMLElement;
18
+ /** create/find container by id */
19
+ containerId: string;
20
+ /** optional canvas if caller wants to manage it */
21
+ canvas: HTMLCanvasElement;
22
+ }>;
23
+ export declare class GameConfig {
24
+ id: string;
25
+ globals: Record<string, any>;
26
+ stages: StageInterface[];
27
+ debug: boolean;
28
+ time: number;
29
+ input: GameInputConfig | undefined;
30
+ aspectRatio: number;
31
+ fullscreen: boolean;
32
+ bodyBackground: string | undefined;
33
+ container: HTMLElement;
34
+ containerId?: string | undefined;
35
+ canvas?: HTMLCanvasElement | undefined;
36
+ constructor(id: string, globals: Record<string, any>, stages: StageInterface[], debug: boolean, time: number, input: GameInputConfig | undefined, aspectRatio: number, fullscreen: boolean, bodyBackground: string | undefined, container: HTMLElement, containerId?: string | undefined, canvas?: HTMLCanvasElement | undefined);
37
+ }
38
+ export declare function createDefaultGameConfig(base?: Partial<Pick<GameConfig, 'id' | 'debug' | 'time' | 'input'>> & {
39
+ stages?: StageInterface[];
40
+ globals?: Record<string, any>;
41
+ }): GameConfig;
42
+ export declare function resolveGameConfig(user?: GameConfigLike): GameConfig;
43
+ /**
44
+ * Factory for authoring configuration objects in user code.
45
+ * Returns a plain object that can be passed to `game(...)`.
46
+ */
47
+ export declare function gameConfig(config: GameConfigLike): GameConfigLike;
@@ -0,0 +1,53 @@
1
+ import { AspectRatio as d } from "../device/aspect-ratio.js";
2
+ class g {
3
+ id;
4
+ globals;
5
+ stages;
6
+ debug;
7
+ time;
8
+ input;
9
+ aspectRatio;
10
+ fullscreen;
11
+ bodyBackground;
12
+ container;
13
+ containerId;
14
+ canvas;
15
+ constructor(n, o, e, i, a, c, s, l, u, m, f, p) {
16
+ this.id = n, this.globals = o, this.stages = e, this.debug = i, this.time = a, this.input = c, this.aspectRatio = s, this.fullscreen = l, this.bodyBackground = u, this.container = m, this.containerId = f, this.canvas = p;
17
+ }
18
+ }
19
+ function r(t, n) {
20
+ if (n)
21
+ return n;
22
+ if (t) {
23
+ const i = document.getElementById(t);
24
+ if (i)
25
+ return i;
26
+ }
27
+ const o = t || "zylem-root", e = document.createElement("main");
28
+ return e.setAttribute("id", o), e.style.position = "relative", e.style.width = "100%", e.style.height = "100%", document.body.appendChild(e), e;
29
+ }
30
+ function b(t) {
31
+ const n = t?.id ?? "zylem", o = r(n);
32
+ return new g(n, t?.globals ?? {}, t?.stages ?? [], !!t?.debug, t?.time ?? 0, t?.input, d.SixteenByNine, !0, "#000000", o, n, void 0);
33
+ }
34
+ function y(t) {
35
+ const n = b({
36
+ id: t?.id ?? "zylem",
37
+ debug: !!t?.debug,
38
+ time: t?.time ?? 0,
39
+ input: t?.input,
40
+ stages: t?.stages ?? [],
41
+ globals: t?.globals ?? {}
42
+ }), o = t?.containerId ?? n.containerId, e = r(o, t?.container ?? null), i = t?.aspectRatio ?? n.aspectRatio, a = typeof i == "number" ? i : d[i] ?? d.SixteenByNine, c = t?.fullscreen ?? n.fullscreen, s = t?.bodyBackground ?? n.bodyBackground, l = t?.canvas ?? void 0;
43
+ return new g(t?.id ?? n.id, t?.globals ?? n.globals, t?.stages ?? n.stages, !!(t?.debug ?? n.debug), t?.time ?? n.time, t?.input ?? n.input, a, c, s, e, o, l);
44
+ }
45
+ function B(t) {
46
+ return { ...t };
47
+ }
48
+ export {
49
+ g as GameConfig,
50
+ b as createDefaultGameConfig,
51
+ B as gameConfig,
52
+ y as resolveGameConfig
53
+ };
@@ -0,0 +1,18 @@
1
+ import { Stage } from '../stage/stage';
2
+ import type { BasicTypes, GlobalVariablesType, ZylemGameConfig, GameInputConfig } from './game-interfaces';
3
+ export declare const gameDefaultsState: Partial<ZylemGameConfig<Stage, any, GlobalVariablesType>>;
4
+ /** Replace multiple defaults at once (shallow merge). */
5
+ export declare function setGameDefaults(partial: Partial<ZylemGameConfig<Stage, any, GlobalVariablesType>>): void;
6
+ /** Reset defaults back to library defaults. */
7
+ export declare function resetGameDefaults(): void;
8
+ /**
9
+ * Get a plain object copy of the current defaults.
10
+ */
11
+ export declare function getGameDefaultConfig<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType>(): {
12
+ id: string;
13
+ globals: TGlobals;
14
+ stages: Stage[];
15
+ debug?: boolean;
16
+ time?: number;
17
+ input?: GameInputConfig;
18
+ };
@@ -0,0 +1,24 @@
1
+ import { proxy as i } from "valtio/vanilla";
2
+ import { stage as e } from "../stage/stage.js";
3
+ const a = () => ({
4
+ id: "zylem",
5
+ globals: {},
6
+ stages: [e()],
7
+ debug: !1,
8
+ time: 0,
9
+ input: void 0
10
+ }), t = i({ ...a() });
11
+ function g() {
12
+ return {
13
+ id: t.id ?? "zylem",
14
+ globals: t.globals ?? {},
15
+ stages: t.stages ?? [e()],
16
+ debug: t.debug,
17
+ time: t.time,
18
+ input: t.input
19
+ };
20
+ }
21
+ export {
22
+ t as gameDefaultsState,
23
+ g as getGameDefaultConfig
24
+ };
@@ -0,0 +1,17 @@
1
+ import { proxy as a } from "valtio/vanilla";
2
+ const o = a({
3
+ id: "",
4
+ globals: {},
5
+ time: 0
6
+ });
7
+ function r(t, l) {
8
+ o.globals[t] = l;
9
+ }
10
+ function i(t) {
11
+ return t !== void 0 ? o.globals[t] : o.globals;
12
+ }
13
+ export {
14
+ i as getGlobalState,
15
+ r as setGlobalState,
16
+ o as state
17
+ };
@@ -1,9 +1,8 @@
1
- import { BaseNode } from '../core/base-node';
2
1
  import { ZylemGame } from './zylem-game';
3
2
  import { Stage } from '../stage/stage';
4
3
  import { DestroyFunction, IGame, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';
5
- import { GameEntityLifeCycle } from '../entities/entity';
6
- import { BasicTypes, GlobalVariablesType, ZylemGameConfig } from './game-interfaces';
4
+ import { BasicTypes, GlobalVariablesType } from './game-interfaces';
5
+ import { GameOptions } from '../core/utility/nodes';
7
6
  export declare class Game<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType> implements IGame<TGlobals> {
8
7
  gameRef: ZylemGame<TGlobals> | null;
9
8
  options: GameOptions<TGlobals>;
@@ -28,7 +27,6 @@ export declare class Game<TGlobals extends Record<string, BasicTypes> = GlobalVa
28
27
  setGlobal<K extends keyof TGlobals>(key: K, value: TGlobals[K]): void;
29
28
  onGlobalChange<K extends keyof TGlobals>(key: K, callback: (value: TGlobals[K]) => void): void;
30
29
  }
31
- type GameOptions<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType> = Array<ZylemGameConfig<Stage, Game<TGlobals>, TGlobals> | Stage | GameEntityLifeCycle | BaseNode>;
32
30
  /**
33
31
  * create a new game
34
32
  * @param options GameOptions - Array of IGameOptions, Stage, GameEntity, or BaseNode objects
@@ -38,4 +36,3 @@ type GameOptions<TGlobals extends Record<string, BasicTypes> = GlobalVariablesTy
38
36
  * @returns Game
39
37
  */
40
38
  export declare function game<TGlobals extends Record<string, BasicTypes> = GlobalVariablesType>(...options: GameOptions<TGlobals>): Game<TGlobals>;
41
- export {};
@@ -0,0 +1,133 @@
1
+ import { ZylemGame as n } from "./zylem-game.js";
2
+ import { Stage as o } from "../stage/stage.js";
3
+ import { setPaused as r } from "../debug/debug-state.js";
4
+ import { getGlobalState as g, setGlobalState as f } from "./game-state.js";
5
+ import { convertNodes as h } from "../core/utility/nodes.js";
6
+ import { resolveGameConfig as l } from "./game-config.js";
7
+ class u {
8
+ gameRef = null;
9
+ options;
10
+ pendingGlobalChangeHandlers = [];
11
+ update = () => {
12
+ };
13
+ setup = () => {
14
+ };
15
+ destroy = () => {
16
+ };
17
+ refErrorMessage = "lost reference to game";
18
+ constructor(t) {
19
+ this.options = t;
20
+ }
21
+ async start() {
22
+ const t = await this.load();
23
+ return this.gameRef = t, this.setOverrides(), t.start(), this;
24
+ }
25
+ async load() {
26
+ console.log("loading game", this.options);
27
+ const t = await h(this.options), s = l(t), e = new n({
28
+ ...t,
29
+ ...s
30
+ }, this);
31
+ return await e.loadStage(t.stages[0]), e;
32
+ }
33
+ setOverrides() {
34
+ if (!this.gameRef) {
35
+ console.error(this.refErrorMessage);
36
+ return;
37
+ }
38
+ if (this.gameRef.customSetup = this.setup, this.gameRef.customUpdate = this.update, this.gameRef.customDestroy = this.destroy, this.pendingGlobalChangeHandlers.length) {
39
+ for (const { key: t, callback: s } of this.pendingGlobalChangeHandlers)
40
+ this.gameRef.onGlobalChange(t, s);
41
+ this.pendingGlobalChangeHandlers = [];
42
+ }
43
+ }
44
+ async pause() {
45
+ r(!0);
46
+ }
47
+ async resume() {
48
+ r(!1), this.gameRef && (this.gameRef.previousTimeStamp = 0, this.gameRef.timer.reset());
49
+ }
50
+ async reset() {
51
+ if (!this.gameRef) {
52
+ console.error(this.refErrorMessage);
53
+ return;
54
+ }
55
+ await this.gameRef.loadStage(this.gameRef.stages[0]);
56
+ }
57
+ async nextStage() {
58
+ if (!this.gameRef) {
59
+ console.error(this.refErrorMessage);
60
+ return;
61
+ }
62
+ const t = this.gameRef.currentStageId, s = this.gameRef.stages.findIndex((a) => a.stageRef.uuid === t), e = this.gameRef.stages[s + 1];
63
+ if (!e) {
64
+ console.error("next stage called on last stage");
65
+ return;
66
+ }
67
+ await this.gameRef.loadStage(e);
68
+ }
69
+ async previousStage() {
70
+ if (!this.gameRef) {
71
+ console.error(this.refErrorMessage);
72
+ return;
73
+ }
74
+ const t = this.gameRef.currentStageId, s = this.gameRef.stages.findIndex((a) => a.stageRef.uuid === t), e = this.gameRef.stages[s - 1];
75
+ if (!e) {
76
+ console.error("previous stage called on first stage");
77
+ return;
78
+ }
79
+ await this.gameRef.loadStage(e);
80
+ }
81
+ async goToStage() {
82
+ }
83
+ async end() {
84
+ }
85
+ add(...t) {
86
+ for (const s of t)
87
+ if (s) {
88
+ if (s instanceof o) {
89
+ this.gameRef ? (this.gameRef.stages.push(s), this.gameRef.stageMap.set(s.stageRef.uuid, s)) : this.options.push(s);
90
+ continue;
91
+ }
92
+ if (typeof s == "function") {
93
+ try {
94
+ const e = s();
95
+ e instanceof o ? this.gameRef ? (this.gameRef.stages.push(e), this.gameRef.stageMap.set(e.stageRef.uuid, e)) : this.options.push(e) : e && typeof e.then == "function" && e.then((a) => {
96
+ a instanceof o && (this.gameRef ? (this.gameRef.stages.push(a), this.gameRef.stageMap.set(a.stageRef.uuid, a)) : this.options.push(a));
97
+ }).catch((a) => console.error("Failed to add async stage", a));
98
+ } catch (e) {
99
+ console.error("Error executing stage factory", e);
100
+ }
101
+ continue;
102
+ }
103
+ s && typeof s.then == "function" && s.then((e) => {
104
+ e instanceof o && (this.gameRef ? (this.gameRef.stages.push(e), this.gameRef.stageMap.set(e.stageRef.uuid, e)) : this.options.push(e));
105
+ }).catch((e) => console.error("Failed to add async stage", e));
106
+ }
107
+ return this;
108
+ }
109
+ getGlobal(t) {
110
+ return this.gameRef ? this.gameRef.getGlobal(t) : g(t);
111
+ }
112
+ setGlobal(t, s) {
113
+ if (this.gameRef) {
114
+ this.gameRef.setGlobal(t, s);
115
+ return;
116
+ }
117
+ f(t, s);
118
+ }
119
+ onGlobalChange(t, s) {
120
+ if (this.gameRef) {
121
+ this.gameRef.onGlobalChange(t, s);
122
+ return;
123
+ }
124
+ this.pendingGlobalChangeHandlers.push({ key: t, callback: s });
125
+ }
126
+ }
127
+ function S(...i) {
128
+ return new u(i);
129
+ }
130
+ export {
131
+ u as Game,
132
+ S as game
133
+ };