@zylem/game-lib 0.3.14 → 0.3.16

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 (104) hide show
  1. package/README.md +17 -14
  2. package/dist/.vite/manifest.json +595 -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.d.ts +10 -0
  24. package/dist/lib/actions/global-change.js +40 -0
  25. package/dist/lib/camera/camera.js +19 -0
  26. package/dist/lib/camera/fixed-2d.js +30 -0
  27. package/dist/lib/camera/perspective.js +10 -0
  28. package/dist/lib/camera/third-person.js +42 -0
  29. package/dist/lib/camera/zylem-camera.js +145 -0
  30. package/dist/lib/collision/collision-builder.d.ts +0 -2
  31. package/dist/lib/collision/collision-builder.js +46 -0
  32. package/dist/lib/collision/collision-delegate.js +6 -0
  33. package/dist/lib/collision/collision-group.d.ts +0 -17
  34. package/dist/lib/collision/utils.js +24 -0
  35. package/dist/lib/collision/world.js +77 -0
  36. package/dist/lib/core/base-node.js +58 -0
  37. package/dist/lib/core/entity-asset-loader.js +57 -0
  38. package/dist/lib/core/lazy-loader.d.ts +0 -2
  39. package/dist/lib/core/lifecycle-base.js +20 -0
  40. package/dist/lib/core/preset-shader.d.ts +2 -1
  41. package/dist/lib/core/preset-shader.js +30 -0
  42. package/dist/lib/core/three-addons/Timer.js +103 -0
  43. package/dist/lib/core/utility.js +20 -0
  44. package/dist/lib/core/vessel.js +23 -0
  45. package/dist/lib/debug/console/console-state.js +11 -0
  46. package/dist/lib/debug/debug-state.js +40 -0
  47. package/dist/lib/entities/actor.js +125 -0
  48. package/dist/lib/entities/box.js +68 -0
  49. package/dist/lib/entities/builder.js +79 -0
  50. package/dist/lib/entities/create.js +31 -0
  51. package/dist/lib/entities/delegates/animation.js +58 -0
  52. package/dist/lib/entities/delegates/debug.js +72 -0
  53. package/dist/lib/entities/delegates/loader.js +19 -0
  54. package/dist/lib/entities/destroy.js +15 -0
  55. package/dist/lib/entities/entity.d.ts +0 -2
  56. package/dist/lib/entities/entity.js +116 -0
  57. package/dist/lib/entities/plane.js +81 -0
  58. package/dist/lib/entities/rect.js +160 -0
  59. package/dist/lib/entities/sphere.js +68 -0
  60. package/dist/lib/entities/sprite.js +118 -0
  61. package/dist/lib/entities/text.js +111 -0
  62. package/dist/lib/entities/zone.js +103 -0
  63. package/dist/lib/game/game-state.js +17 -0
  64. package/dist/lib/game/game.js +157 -0
  65. package/dist/lib/game/zylem-game.d.ts +2 -0
  66. package/dist/lib/game/zylem-game.js +107 -0
  67. package/dist/lib/graphics/geometries/XZPlaneGeometry.js +34 -0
  68. package/dist/lib/graphics/material.js +64 -0
  69. package/dist/lib/graphics/mesh.js +14 -0
  70. package/dist/lib/graphics/render-pass.js +56 -0
  71. package/dist/lib/graphics/shaders/fragment/debug.glsl.js +23 -0
  72. package/dist/lib/graphics/shaders/fragment/fire.glsl.js +52 -0
  73. package/dist/lib/graphics/shaders/fragment/standard.glsl.js +11 -0
  74. package/dist/lib/graphics/shaders/fragment/stars.glsl.js +44 -0
  75. package/dist/lib/graphics/shaders/vertex/debug.glsl.js +15 -0
  76. package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +11 -0
  77. package/dist/lib/graphics/shaders/vertex/standard.glsl.js +9 -0
  78. package/dist/lib/graphics/zylem-scene.d.ts +2 -2
  79. package/dist/lib/graphics/zylem-scene.js +89 -0
  80. package/dist/lib/input/gamepad-provider.js +58 -0
  81. package/dist/lib/input/input-manager.js +70 -0
  82. package/dist/lib/input/keyboard-provider.js +120 -0
  83. package/dist/lib/stage/debug-entity-cursor.js +53 -0
  84. package/dist/lib/stage/entity-spawner.js +27 -0
  85. package/dist/lib/stage/stage-debug-delegate.js +100 -0
  86. package/dist/lib/stage/stage-state.d.ts +5 -1
  87. package/dist/lib/stage/stage-state.js +36 -0
  88. package/dist/lib/stage/stage.d.ts +0 -1
  89. package/dist/lib/stage/stage.js +58 -0
  90. package/dist/lib/stage/zylem-stage.d.ts +1 -3
  91. package/dist/lib/stage/zylem-stage.js +279 -0
  92. package/dist/lib/systems/transformable.system.js +43 -0
  93. package/dist/main.d.ts +5 -15
  94. package/dist/main.js +54 -35581
  95. package/dist/stage.d.ts +3 -0
  96. package/dist/stage.js +6 -0
  97. package/package.json +51 -17
  98. package/dist/assets/bounce.wav +0 -0
  99. package/dist/assets/coin-sound.mp3 +0 -0
  100. package/dist/lib/actions/behaviors/index.d.ts +0 -1
  101. package/dist/lib/collision/physics.d.ts +0 -4
  102. package/dist/lib/entities/object.d.ts +0 -1
  103. package/dist/lib/interfaces/game.d.ts +0 -19
  104. package/dist/main.cjs +0 -3980
@@ -0,0 +1,89 @@
1
+ import { Scene as r, Color as n, TextureLoader as o, AmbientLight as m, DirectionalLight as d, Vector3 as h, GridHelper as l } from "three";
2
+ import { debugState as c } from "../debug/debug-state.js";
3
+ import { getGlobalState as p } from "../game/game-state.js";
4
+ class y {
5
+ type = "Scene";
6
+ _setup;
7
+ scene;
8
+ zylemCamera;
9
+ containerElement = null;
10
+ constructor(e, t, a) {
11
+ const i = new r();
12
+ if (i.background = new n(a.backgroundColor), a.backgroundImage) {
13
+ const s = new o().load(a.backgroundImage);
14
+ i.background = s;
15
+ }
16
+ this.scene = i, this.zylemCamera = t, this.setupContainer(e), this.setupLighting(i), this.setupCamera(i, t), c.on && this.debugScene();
17
+ }
18
+ /**
19
+ * Setup the container element and append camera's renderer
20
+ */
21
+ setupContainer(e) {
22
+ let t = document.getElementById(e);
23
+ if (!t) {
24
+ console.warn(`Could not find element with id: ${e}`);
25
+ const a = document.createElement("main");
26
+ a.setAttribute("id", e), document.body.appendChild(a), t = a;
27
+ }
28
+ t?.firstChild && t.removeChild(t.firstChild), this.containerElement = t, t?.appendChild(this.zylemCamera.getDomElement());
29
+ }
30
+ setup() {
31
+ this._setup && this._setup({ me: this, camera: this.zylemCamera, globals: p() });
32
+ }
33
+ destroy() {
34
+ if (this.containerElement && this.zylemCamera)
35
+ try {
36
+ const e = this.zylemCamera.getDomElement();
37
+ e && e.parentElement === this.containerElement && this.containerElement.removeChild(e);
38
+ } catch {
39
+ }
40
+ this.zylemCamera && this.zylemCamera.destroy && this.zylemCamera.destroy(), this.scene && this.scene.traverse((e) => {
41
+ e.geometry && e.geometry.dispose?.(), e.material && (Array.isArray(e.material) ? e.material.forEach((t) => t.dispose?.()) : e.material.dispose?.());
42
+ });
43
+ }
44
+ update({ delta: e }) {
45
+ }
46
+ /**
47
+ * Setup camera with the scene
48
+ */
49
+ setupCamera(e, t) {
50
+ e.add(t.cameraRig), t.setup(e);
51
+ }
52
+ /**
53
+ * Setup scene lighting
54
+ */
55
+ setupLighting(e) {
56
+ const t = new m(16777215, 2);
57
+ e.add(t);
58
+ const a = new d(16777215, 2);
59
+ a.name = "Light", a.position.set(0, 100, 0), a.castShadow = !0, a.shadow.camera.near = 0.1, a.shadow.camera.far = 2e3, a.shadow.camera.left = -100, a.shadow.camera.right = 100, a.shadow.camera.top = 100, a.shadow.camera.bottom = -100, a.shadow.mapSize.width = 2048, a.shadow.mapSize.height = 2048, e.add(a);
60
+ }
61
+ /**
62
+ * Update renderer size - delegates to camera
63
+ */
64
+ updateRenderer(e, t) {
65
+ this.zylemCamera.resize(e, t);
66
+ }
67
+ /**
68
+ * Add object to scene
69
+ */
70
+ add(e, t = new h(0, 0, 0)) {
71
+ e.position.set(t.x, t.y, t.z), this.scene.add(e);
72
+ }
73
+ /**
74
+ * Add game entity to scene
75
+ */
76
+ addEntity(e) {
77
+ e.group ? this.add(e.group, e.options.position) : e.mesh && this.add(e.mesh, e.options.position);
78
+ }
79
+ /**
80
+ * Add debug helpers to scene
81
+ */
82
+ debugScene() {
83
+ const a = new l(1e3, 100);
84
+ this.scene.add(a);
85
+ }
86
+ }
87
+ export {
88
+ y as ZylemScene
89
+ };
@@ -0,0 +1,58 @@
1
+ class h {
2
+ gamepadIndex;
3
+ connected = !1;
4
+ buttonStates = {};
5
+ constructor(t) {
6
+ this.gamepadIndex = t, window.addEventListener("gamepadconnected", (e) => {
7
+ e.gamepad.index === this.gamepadIndex && (this.connected = !0);
8
+ }), window.addEventListener("gamepaddisconnected", (e) => {
9
+ e.gamepad.index === this.gamepadIndex && (this.connected = !1);
10
+ });
11
+ }
12
+ handleButtonState(t, e, a) {
13
+ const s = e.buttons[t].pressed;
14
+ let n = this.buttonStates[t];
15
+ return n || (n = { pressed: !1, released: !1, held: 0 }, this.buttonStates[t] = n), s ? (n.held === 0 ? n.pressed = !0 : n.pressed = !1, n.held += a, n.released = !1) : (n.held > 0 ? (n.released = !0, n.held = 0) : n.released = !1, n.pressed = !1), n;
16
+ }
17
+ handleAnalogState(t, e, a) {
18
+ return { value: e.axes[t], held: a };
19
+ }
20
+ getInput(t) {
21
+ const e = navigator.getGamepads()[this.gamepadIndex];
22
+ return e ? {
23
+ buttons: {
24
+ A: this.handleButtonState(0, e, t),
25
+ B: this.handleButtonState(1, e, t),
26
+ X: this.handleButtonState(2, e, t),
27
+ Y: this.handleButtonState(3, e, t),
28
+ Start: this.handleButtonState(9, e, t),
29
+ Select: this.handleButtonState(8, e, t),
30
+ L: this.handleButtonState(4, e, t),
31
+ R: this.handleButtonState(5, e, t)
32
+ },
33
+ directions: {
34
+ Up: this.handleButtonState(12, e, t),
35
+ Down: this.handleButtonState(13, e, t),
36
+ Left: this.handleButtonState(14, e, t),
37
+ Right: this.handleButtonState(15, e, t)
38
+ },
39
+ axes: {
40
+ Horizontal: this.handleAnalogState(0, e, t),
41
+ Vertical: this.handleAnalogState(1, e, t)
42
+ },
43
+ shoulders: {
44
+ LTrigger: this.handleButtonState(6, e, t),
45
+ RTrigger: this.handleButtonState(7, e, t)
46
+ }
47
+ } : {};
48
+ }
49
+ getName() {
50
+ return `gamepad-${this.gamepadIndex + 1}`;
51
+ }
52
+ isConnected() {
53
+ return this.connected;
54
+ }
55
+ }
56
+ export {
57
+ h as GamepadProvider
58
+ };
@@ -0,0 +1,70 @@
1
+ import { KeyboardProvider as s } from "./keyboard-provider.js";
2
+ import { GamepadProvider as r } from "./gamepad-provider.js";
3
+ class B {
4
+ inputMap = /* @__PURE__ */ new Map();
5
+ currentInputs = {};
6
+ previousInputs = {};
7
+ constructor(t) {
8
+ t?.p1?.key ? this.addInputProvider(1, new s(t.p1.key, { includeDefaultBase: !1 })) : this.addInputProvider(1, new s()), this.addInputProvider(1, new r(0)), t?.p2?.key && this.addInputProvider(2, new s(t.p2.key, { includeDefaultBase: !1 })), this.addInputProvider(2, new r(1)), t?.p3?.key && this.addInputProvider(3, new s(t.p3.key, { includeDefaultBase: !1 })), this.addInputProvider(3, new r(2)), t?.p4?.key && this.addInputProvider(4, new s(t.p4.key, { includeDefaultBase: !1 })), this.addInputProvider(4, new r(3)), t?.p5?.key && this.addInputProvider(5, new s(t.p5.key, { includeDefaultBase: !1 })), this.addInputProvider(5, new r(4)), t?.p6?.key && this.addInputProvider(6, new s(t.p6.key, { includeDefaultBase: !1 })), this.addInputProvider(6, new r(5)), t?.p7?.key && this.addInputProvider(7, new s(t.p7.key, { includeDefaultBase: !1 })), this.addInputProvider(7, new r(6)), t?.p8?.key && this.addInputProvider(8, new s(t.p8.key, { includeDefaultBase: !1 })), this.addInputProvider(8, new r(7));
9
+ }
10
+ addInputProvider(t, e) {
11
+ this.inputMap.has(t) || this.inputMap.set(t, []), this.inputMap.get(t)?.push(e);
12
+ }
13
+ getInputs(t) {
14
+ const e = {};
15
+ return this.inputMap.forEach((i, n) => {
16
+ const u = `p${n}`, d = i.reduce((a, o) => {
17
+ const p = o.getInput(t);
18
+ return this.mergeInputs(a, p);
19
+ }, {});
20
+ e[u] = {
21
+ playerNumber: n,
22
+ ...d
23
+ };
24
+ }), e;
25
+ }
26
+ mergeButtonState(t, e) {
27
+ return {
28
+ pressed: t?.pressed || e?.pressed || !1,
29
+ released: t?.released || e?.released || !1,
30
+ held: (t?.held || 0) + (e?.held || 0)
31
+ };
32
+ }
33
+ mergeAnalogState(t, e) {
34
+ return {
35
+ value: (t?.value || 0) + (e?.value || 0),
36
+ held: (t?.held || 0) + (e?.held || 0)
37
+ };
38
+ }
39
+ mergeInputs(t, e) {
40
+ return {
41
+ buttons: {
42
+ A: this.mergeButtonState(t.buttons?.A, e.buttons?.A),
43
+ B: this.mergeButtonState(t.buttons?.B, e.buttons?.B),
44
+ X: this.mergeButtonState(t.buttons?.X, e.buttons?.X),
45
+ Y: this.mergeButtonState(t.buttons?.Y, e.buttons?.Y),
46
+ Start: this.mergeButtonState(t.buttons?.Start, e.buttons?.Start),
47
+ Select: this.mergeButtonState(t.buttons?.Select, e.buttons?.Select),
48
+ L: this.mergeButtonState(t.buttons?.L, e.buttons?.L),
49
+ R: this.mergeButtonState(t.buttons?.R, e.buttons?.R)
50
+ },
51
+ directions: {
52
+ Up: this.mergeButtonState(t.directions?.Up, e.directions?.Up),
53
+ Down: this.mergeButtonState(t.directions?.Down, e.directions?.Down),
54
+ Left: this.mergeButtonState(t.directions?.Left, e.directions?.Left),
55
+ Right: this.mergeButtonState(t.directions?.Right, e.directions?.Right)
56
+ },
57
+ axes: {
58
+ Horizontal: this.mergeAnalogState(t.axes?.Horizontal, e.axes?.Horizontal),
59
+ Vertical: this.mergeAnalogState(t.axes?.Vertical, e.axes?.Vertical)
60
+ },
61
+ shoulders: {
62
+ LTrigger: this.mergeButtonState(t.shoulders?.LTrigger, e.shoulders?.LTrigger),
63
+ RTrigger: this.mergeButtonState(t.shoulders?.RTrigger, e.shoulders?.RTrigger)
64
+ }
65
+ };
66
+ }
67
+ }
68
+ export {
69
+ B as InputManager
70
+ };
@@ -0,0 +1,120 @@
1
+ class p {
2
+ keyStates = /* @__PURE__ */ new Map();
3
+ keyButtonStates = /* @__PURE__ */ new Map();
4
+ mapping = null;
5
+ includeDefaultBase = !0;
6
+ constructor(t, s) {
7
+ this.mapping = t ?? null, this.includeDefaultBase = s?.includeDefaultBase ?? !0, window.addEventListener("keydown", ({ key: e }) => this.keyStates.set(e, !0)), window.addEventListener("keyup", ({ key: e }) => this.keyStates.set(e, !1));
8
+ }
9
+ isKeyPressed(t) {
10
+ return this.keyStates.get(t) || !1;
11
+ }
12
+ handleButtonState(t, s) {
13
+ let e = this.keyButtonStates.get(t);
14
+ const o = this.isKeyPressed(t);
15
+ return e || (e = { pressed: !1, released: !1, held: 0 }, this.keyButtonStates.set(t, e)), o ? (e.held === 0 ? e.pressed = !0 : e.pressed = !1, e.held += s, e.released = !1) : (e.held > 0 ? (e.released = !0, e.held = 0) : e.released = !1, e.pressed = !1), e;
16
+ }
17
+ handleAnalogState(t, s, e) {
18
+ return { value: this.getAxisValue(t, s), held: e };
19
+ }
20
+ mergeButtonState(t, s) {
21
+ return {
22
+ pressed: t?.pressed || s?.pressed || !1,
23
+ released: t?.released || s?.released || !1,
24
+ held: (t?.held || 0) + (s?.held || 0)
25
+ };
26
+ }
27
+ applyCustomMapping(t, s) {
28
+ if (!this.mapping)
29
+ return t;
30
+ for (const [e, o] of Object.entries(this.mapping)) {
31
+ if (!o || o.length === 0)
32
+ continue;
33
+ const a = this.handleButtonState(e, s);
34
+ for (const c of o) {
35
+ const [u, l] = (c || "").split(".");
36
+ if (!u || !l)
37
+ continue;
38
+ const i = u.toLowerCase(), h = l.toLowerCase();
39
+ if (i === "buttons") {
40
+ const n = {
41
+ a: "A",
42
+ b: "B",
43
+ x: "X",
44
+ y: "Y",
45
+ start: "Start",
46
+ select: "Select",
47
+ l: "L",
48
+ r: "R"
49
+ }[h];
50
+ if (!n)
51
+ continue;
52
+ const r = t.buttons || {};
53
+ r[n] = this.mergeButtonState(r[n], a), t.buttons = r;
54
+ continue;
55
+ }
56
+ if (i === "directions") {
57
+ const n = {
58
+ up: "Up",
59
+ down: "Down",
60
+ left: "Left",
61
+ right: "Right"
62
+ }[h];
63
+ if (!n)
64
+ continue;
65
+ const r = t.directions || {};
66
+ r[n] = this.mergeButtonState(r[n], a), t.directions = r;
67
+ continue;
68
+ }
69
+ if (i === "shoulders") {
70
+ const n = {
71
+ ltrigger: "LTrigger",
72
+ rtrigger: "RTrigger"
73
+ }[h];
74
+ if (!n)
75
+ continue;
76
+ const r = t.shoulders || {};
77
+ r[n] = this.mergeButtonState(r[n], a), t.shoulders = r;
78
+ continue;
79
+ }
80
+ }
81
+ }
82
+ return t;
83
+ }
84
+ getInput(t) {
85
+ const s = {};
86
+ return this.includeDefaultBase && (s.buttons = {
87
+ A: this.handleButtonState("z", t),
88
+ B: this.handleButtonState("x", t),
89
+ X: this.handleButtonState("a", t),
90
+ Y: this.handleButtonState("s", t),
91
+ Start: this.handleButtonState(" ", t),
92
+ Select: this.handleButtonState("Enter", t),
93
+ L: this.handleButtonState("q", t),
94
+ R: this.handleButtonState("e", t)
95
+ }, s.directions = {
96
+ Up: this.handleButtonState("ArrowUp", t),
97
+ Down: this.handleButtonState("ArrowDown", t),
98
+ Left: this.handleButtonState("ArrowLeft", t),
99
+ Right: this.handleButtonState("ArrowRight", t)
100
+ }, s.axes = {
101
+ Horizontal: this.handleAnalogState("ArrowLeft", "ArrowRight", t),
102
+ Vertical: this.handleAnalogState("ArrowUp", "ArrowDown", t)
103
+ }, s.shoulders = {
104
+ LTrigger: this.handleButtonState("Q", t),
105
+ RTrigger: this.handleButtonState("E", t)
106
+ }), this.applyCustomMapping(s, t);
107
+ }
108
+ getName() {
109
+ return "keyboard";
110
+ }
111
+ getAxisValue(t, s) {
112
+ return (this.isKeyPressed(s) ? 1 : 0) - (this.isKeyPressed(t) ? 1 : 0);
113
+ }
114
+ isConnected() {
115
+ return !0;
116
+ }
117
+ }
118
+ export {
119
+ p as KeyboardProvider
120
+ };
@@ -0,0 +1,53 @@
1
+ import { Color as r, Box3 as h, Vector3 as s, BoxGeometry as n, Mesh as a, MeshBasicMaterial as l, EdgesGeometry as o, LineSegments as c, LineBasicMaterial as d, Group as m } from "three";
2
+ class u {
3
+ scene;
4
+ container;
5
+ fillMesh;
6
+ edgeLines;
7
+ currentColor = new r(65280);
8
+ bbox = new h();
9
+ size = new s();
10
+ center = new s();
11
+ constructor(e) {
12
+ this.scene = e;
13
+ const i = new n(1, 1, 1);
14
+ this.fillMesh = new a(i, new l({
15
+ color: this.currentColor,
16
+ transparent: !0,
17
+ opacity: 0.12,
18
+ depthWrite: !1
19
+ }));
20
+ const t = new o(i);
21
+ this.edgeLines = new c(t, new d({ color: this.currentColor, linewidth: 1 })), this.container = new m(), this.container.name = "DebugEntityCursor", this.container.add(this.fillMesh), this.container.add(this.edgeLines), this.container.visible = !1, this.scene.add(this.container);
22
+ }
23
+ setColor(e) {
24
+ this.currentColor.set(e), this.fillMesh.material.color.set(this.currentColor), this.edgeLines.material.color.set(this.currentColor);
25
+ }
26
+ /**
27
+ * Update the cursor to enclose the provided Object3D using a world-space AABB.
28
+ */
29
+ updateFromObject(e) {
30
+ if (!e) {
31
+ this.hide();
32
+ return;
33
+ }
34
+ if (this.bbox.setFromObject(e), !isFinite(this.bbox.min.x) || !isFinite(this.bbox.max.x)) {
35
+ this.hide();
36
+ return;
37
+ }
38
+ this.bbox.getSize(this.size), this.bbox.getCenter(this.center);
39
+ const i = new n(Math.max(this.size.x, 1e-6), Math.max(this.size.y, 1e-6), Math.max(this.size.z, 1e-6));
40
+ this.fillMesh.geometry.dispose(), this.fillMesh.geometry = i;
41
+ const t = new o(i);
42
+ this.edgeLines.geometry.dispose(), this.edgeLines.geometry = t, this.container.position.copy(this.center), this.container.visible = !0;
43
+ }
44
+ hide() {
45
+ this.container.visible = !1;
46
+ }
47
+ dispose() {
48
+ this.scene.remove(this.container), this.fillMesh.geometry.dispose(), this.fillMesh.material.dispose(), this.edgeLines.geometry.dispose(), this.edgeLines.material.dispose();
49
+ }
50
+ }
51
+ export {
52
+ u as DebugEntityCursor
53
+ };
@@ -0,0 +1,27 @@
1
+ import { Vector2 as l, Quaternion as m, Euler as p } from "three";
2
+ function b(s) {
3
+ return {
4
+ spawn: async (n, r, t) => {
5
+ const e = await Promise.resolve(s(r, t));
6
+ return n.add(e), e;
7
+ },
8
+ spawnRelative: async (n, r, t = new l(0, 1)) => {
9
+ if (!n.body) {
10
+ console.warn("body missing for entity during spawnRelative");
11
+ return;
12
+ }
13
+ const { x: e, y: c, z: u } = n.body.translation();
14
+ let a = n._rotation2DAngle ?? 0;
15
+ try {
16
+ const o = n.body.rotation(), d = new m(o.x, o.y, o.z, o.w);
17
+ a = new p().setFromQuaternion(d, "XYZ").z;
18
+ } catch {
19
+ }
20
+ const w = Math.sin(-a) * (t.x ?? 0), y = Math.cos(-a) * (t.y ?? 0), i = await Promise.resolve(s(e + w, c + y));
21
+ return r.add(i), i;
22
+ }
23
+ };
24
+ }
25
+ export {
26
+ b as entitySpawner
27
+ };
@@ -0,0 +1,100 @@
1
+ import { Ray as b } from "@dimforge/rapier3d-compat";
2
+ import { Vector2 as E, Raycaster as f, LineSegments as L, BufferGeometry as p, LineBasicMaterial as w, BufferAttribute as m } from "three";
3
+ import { debugState as C, getDebugTool as y, setHoveredEntity as D, resetHoveredEntity as v, getHoveredEntity as R, DebugTools as d, setSelectedEntity as T } from "../debug/debug-state.js";
4
+ import { DebugEntityCursor as O } from "./debug-entity-cursor.js";
5
+ const F = 2293538, x = 16724787;
6
+ class A {
7
+ stage;
8
+ options;
9
+ mouseNdc = new E(-2, -2);
10
+ raycaster = new f();
11
+ isMouseDown = !1;
12
+ disposeFns = [];
13
+ debugCursor = null;
14
+ debugLines = null;
15
+ constructor(e, s) {
16
+ this.stage = e, this.options = {
17
+ maxRayDistance: s?.maxRayDistance ?? 5e3,
18
+ addEntityFactory: s?.addEntityFactory ?? null
19
+ }, this.stage.scene && (this.debugLines = new L(new p(), new w({ vertexColors: !0 })), this.stage.scene.scene.add(this.debugLines), this.debugLines.visible = !0, this.debugCursor = new O(this.stage.scene.scene)), this.attachDomListeners();
20
+ }
21
+ update() {
22
+ if (!C.on || !this.stage.scene || !this.stage.world || !this.stage.cameraRef)
23
+ return;
24
+ const { world: e, cameraRef: s } = this.stage;
25
+ if (this.debugLines) {
26
+ const { vertices: l, colors: c } = e.world.debugRender();
27
+ this.debugLines.geometry.setAttribute("position", new m(l, 3)), this.debugLines.geometry.setAttribute("color", new m(c, 4));
28
+ }
29
+ const i = y(), n = i === d.SELECT || i === d.DELETE;
30
+ this.raycaster.setFromCamera(this.mouseNdc, s.camera);
31
+ const t = this.raycaster.ray.origin.clone(), o = this.raycaster.ray.direction.clone().normalize(), r = new b({ x: t.x, y: t.y, z: t.z }, { x: o.x, y: o.y, z: o.z }), a = e.world.castRay(r, this.options.maxRayDistance, !0);
32
+ if (a && n) {
33
+ const c = a.collider?._parent?.userData?.uuid;
34
+ c ? D(c) : v(), this.isMouseDown && this.handleActionOnHit(c ?? null, t, o, a.toi);
35
+ }
36
+ this.isMouseDown = !1;
37
+ const u = R();
38
+ if (!u) {
39
+ this.debugCursor?.hide();
40
+ return;
41
+ }
42
+ const h = this.stage._debugMap.get(`${u}`), g = h?.group ?? h?.mesh ?? null;
43
+ if (!g) {
44
+ this.debugCursor?.hide();
45
+ return;
46
+ }
47
+ switch (i) {
48
+ case d.SELECT:
49
+ this.debugCursor?.setColor(F);
50
+ break;
51
+ case d.DELETE:
52
+ this.debugCursor?.setColor(x);
53
+ break;
54
+ default:
55
+ this.debugCursor?.setColor(16777215);
56
+ break;
57
+ }
58
+ this.debugCursor?.updateFromObject(g);
59
+ }
60
+ dispose() {
61
+ this.disposeFns.forEach((e) => e()), this.disposeFns = [], this.debugCursor?.dispose(), this.debugLines && this.stage.scene && (this.stage.scene.scene.remove(this.debugLines), this.debugLines.geometry.dispose(), this.debugLines.material.dispose(), this.debugLines = null);
62
+ }
63
+ handleActionOnHit(e, s, i, n) {
64
+ switch (y()) {
65
+ case "SELECT": {
66
+ e && T(e);
67
+ break;
68
+ }
69
+ case "DELETE": {
70
+ e && this.stage.removeEntityByUuid(e);
71
+ break;
72
+ }
73
+ case "ADD": {
74
+ if (!this.options.addEntityFactory)
75
+ break;
76
+ const o = s.clone().add(i.clone().multiplyScalar(n)), r = this.options.addEntityFactory({ position: o });
77
+ r && Promise.resolve(r).then((a) => {
78
+ a && this.stage.spawnEntity(a);
79
+ }).catch(() => {
80
+ });
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ attachDomListeners() {
86
+ const e = this.stage.cameraRef?.renderer.domElement ?? this.stage.scene?.zylemCamera.renderer.domElement;
87
+ if (!e)
88
+ return;
89
+ const s = (n) => {
90
+ const t = e.getBoundingClientRect(), o = (n.clientX - t.left) / t.width * 2 - 1, r = -((n.clientY - t.top) / t.height * 2 - 1);
91
+ this.mouseNdc.set(o, r);
92
+ }, i = (n) => {
93
+ this.isMouseDown = !0;
94
+ };
95
+ e.addEventListener("mousemove", s), e.addEventListener("mousedown", i), this.disposeFns.push(() => e.removeEventListener("mousemove", s)), this.disposeFns.push(() => e.removeEventListener("mousedown", i));
96
+ }
97
+ }
98
+ export {
99
+ A as StageDebugDelegate
100
+ };
@@ -8,5 +8,9 @@ declare const setStageBackgroundImage: (value: string | null) => void;
8
8
  declare const setEntitiesToStage: (entities: Partial<BaseEntityInterface>[]) => void;
9
9
  declare const setStageVariable: (key: string, value: any) => void;
10
10
  declare const getStageVariable: (key: string) => any;
11
+ /** Replace the entire stage variables object (used on stage load). */
12
+ declare const setStageVariables: (variables: Record<string, any>) => void;
13
+ /** Reset all stage variables (used on stage unload). */
14
+ declare const resetStageVariables: () => void;
11
15
  declare const stageStateToString: (state: StageStateInterface) => string;
12
- export { stageState, setStageState, setStageBackgroundColor, setStageBackgroundImage, setEntitiesToStage, stageStateToString, setStageVariable, getStageVariable, };
16
+ export { stageState, setStageState, setStageBackgroundColor, setStageBackgroundImage, setEntitiesToStage, stageStateToString, setStageVariable, getStageVariable, setStageVariables, resetStageVariables, };
@@ -0,0 +1,36 @@
1
+ import { Vector3 as t, Color as r } from "three";
2
+ import { proxy as s } from "valtio/vanilla";
3
+ const e = s({
4
+ backgroundColor: new r(r.NAMES.cornflowerblue),
5
+ backgroundImage: null,
6
+ inputs: {
7
+ p1: ["gamepad-1", "keyboard-1"],
8
+ p2: ["gamepad-2", "keyboard-2"]
9
+ },
10
+ variables: {},
11
+ gravity: new t(0, 0, 0),
12
+ entities: []
13
+ }), l = (a) => {
14
+ e.backgroundColor = a;
15
+ }, b = (a) => {
16
+ e.backgroundImage = a;
17
+ }, i = (a, o) => {
18
+ e.variables[a] = o;
19
+ }, c = (a) => {
20
+ if (e.variables.hasOwnProperty(a))
21
+ return e.variables[a];
22
+ console.warn(`Stage variable ${a} not found`);
23
+ }, d = (a) => {
24
+ e.variables = { ...a };
25
+ }, u = () => {
26
+ e.variables = {};
27
+ };
28
+ export {
29
+ c as getStageVariable,
30
+ u as resetStageVariables,
31
+ l as setStageBackgroundColor,
32
+ b as setStageBackgroundImage,
33
+ i as setStageVariable,
34
+ d as setStageVariables,
35
+ e as stageState
36
+ };
@@ -24,7 +24,6 @@ export declare class Stage {
24
24
  onDestroy(callback: DestroyFunction<ZylemStage>): void;
25
25
  setVariable(key: string, value: any): void;
26
26
  getVariable(key: string): any;
27
- watchVariable(key: string, callback: (value: any) => void): void;
28
27
  }
29
28
  /**
30
29
  * Create a stage with optional camera
@@ -0,0 +1,58 @@
1
+ import { ZylemStage as n } from "./zylem-stage.js";
2
+ import { CameraWrapper as r } from "../camera/camera.js";
3
+ import { stageState as i, setStageVariable as g, getStageVariable as p } from "./stage-state.js";
4
+ class f {
5
+ stageRef;
6
+ options = [];
7
+ update = () => {
8
+ };
9
+ setup = () => {
10
+ };
11
+ destroy = () => {
12
+ };
13
+ constructor(t) {
14
+ this.options = t, this.stageRef = new n(this.options);
15
+ }
16
+ async load(t, e) {
17
+ this.stageRef.wrapperRef = this;
18
+ const s = e instanceof r ? e.cameraRef : e;
19
+ await this.stageRef.load(t, s);
20
+ }
21
+ async addEntities(t) {
22
+ this.options.push(...t), this.stageRef.enqueue(...t);
23
+ }
24
+ add(...t) {
25
+ this.stageRef.enqueue(...t);
26
+ }
27
+ start(t) {
28
+ this.stageRef?.nodeSetup(t), this.stageRef.onEntityAdded((e) => {
29
+ const s = this.stageRef.buildEntityState(e);
30
+ i.entities = [...i.entities, s];
31
+ }, { replayExisting: !0 });
32
+ }
33
+ onUpdate(...t) {
34
+ this.stageRef.update = (e) => {
35
+ const s = { ...e, stage: this };
36
+ t.forEach((o) => o(s));
37
+ };
38
+ }
39
+ onSetup(t) {
40
+ this.stageRef.setup = t;
41
+ }
42
+ onDestroy(t) {
43
+ this.stageRef.destroy = t;
44
+ }
45
+ setVariable(t, e) {
46
+ g(t, e);
47
+ }
48
+ getVariable(t) {
49
+ return p(t);
50
+ }
51
+ }
52
+ function R(...a) {
53
+ return new f(a);
54
+ }
55
+ export {
56
+ f as Stage,
57
+ R as stage
58
+ };
@@ -1,7 +1,6 @@
1
1
  import { Color, Vector3 } from 'three';
2
2
  import { ZylemWorld } from '../collision/world';
3
3
  import { ZylemScene } from '../graphics/zylem-scene';
4
- import { Conditions } from '../interfaces/game';
5
4
  import { GameEntityInterface } from '../types/entity-types';
6
5
  import { SetupContext, UpdateContext, DestroyContext } from '../core/base-node-life-cycle';
7
6
  import { LifeCycleBase } from '../core/lifecycle-base';
@@ -17,7 +16,6 @@ export interface ZylemStageConfig {
17
16
  backgroundImage: string | null;
18
17
  gravity: Vector3;
19
18
  variables: Record<string, any>;
20
- conditions?: Conditions<any>[];
21
19
  stageRef?: Stage;
22
20
  }
23
21
  type NodeLike = {
@@ -44,7 +42,6 @@ export declare class ZylemStage extends LifeCycleBase<ZylemStage> {
44
42
  gravity: Vector3;
45
43
  world: ZylemWorld | null;
46
44
  scene: ZylemScene | null;
47
- conditions: Conditions<any>[];
48
45
  children: Array<BaseNode>;
49
46
  _childrenMap: Map<number, BaseNode>;
50
47
  _removalMap: Map<number, BaseNode>;
@@ -85,6 +82,7 @@ export declare class ZylemStage extends LifeCycleBase<ZylemStage> {
85
82
  private createDefaultCamera;
86
83
  protected _setup(params: SetupContext<ZylemStage>): void;
87
84
  protected _update(params: UpdateContext<ZylemStage>): void;
85
+ outOfLoop(): void;
88
86
  /** Update debug overlays and helpers if enabled. */
89
87
  debugUpdate(): void;
90
88
  /** Cleanup owned resources when the stage is destroyed. */