@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.
- package/README.md +38 -13
- package/dist/.vite/manifest.json +665 -2
- package/dist/actions.d.ts +4 -0
- package/dist/actions.js +10 -0
- package/dist/behaviors.d.ts +3 -0
- package/dist/behaviors.js +8 -0
- package/dist/camera.d.ts +3 -0
- package/dist/camera.js +6 -0
- package/dist/core.d.ts +5 -0
- package/dist/core.js +11 -0
- package/dist/entities.d.ts +8 -0
- package/dist/entities.js +19 -0
- package/dist/lib/actions/behaviors/actions.js +35 -0
- package/dist/lib/actions/behaviors/boundaries/boundary.d.ts +1 -1
- package/dist/lib/actions/behaviors/boundaries/boundary.js +40 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet-2d-collision.js +100 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.js +37 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet.d.ts +2 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet.js +6 -0
- package/dist/lib/actions/capabilities/moveable.js +108 -0
- package/dist/lib/actions/capabilities/rotatable.js +82 -0
- package/dist/lib/actions/capabilities/transformable.js +9 -0
- package/dist/lib/actions/global-change.js +40 -0
- package/dist/lib/camera/camera.js +19 -0
- package/dist/lib/camera/fixed-2d.js +30 -0
- package/dist/lib/camera/perspective.js +10 -0
- package/dist/lib/camera/third-person.js +42 -0
- package/dist/lib/camera/zylem-camera.js +145 -0
- package/dist/lib/collision/collision-builder.js +46 -0
- package/dist/lib/collision/collision-delegate.js +6 -0
- package/dist/lib/collision/utils.js +24 -0
- package/dist/lib/collision/world.js +77 -0
- package/dist/lib/core/base-node-life-cycle.d.ts +14 -0
- package/dist/lib/core/base-node.d.ts +6 -2
- package/dist/lib/core/base-node.js +62 -0
- package/dist/lib/core/entity-asset-loader.js +57 -0
- package/dist/lib/core/lazy-loader.d.ts +2 -2
- package/dist/lib/core/lifecycle-base.js +20 -0
- package/dist/lib/core/preset-shader.js +30 -0
- package/dist/lib/core/three-addons/Timer.js +103 -0
- package/dist/lib/core/utility/nodes.d.ts +11 -0
- package/dist/lib/core/utility/nodes.js +27 -0
- package/dist/lib/core/utility/strings.d.ts +2 -0
- package/dist/lib/core/utility/strings.js +14 -0
- package/dist/lib/core/{utility.d.ts → utility/vector.d.ts} +0 -2
- package/dist/lib/core/utility/vector.js +8 -0
- package/dist/lib/core/vessel.d.ts +3 -1
- package/dist/lib/core/vessel.js +27 -0
- package/dist/lib/debug/console/console-state.js +11 -0
- package/dist/lib/debug/debug-state.js +40 -0
- package/dist/lib/device/aspect-ratio.d.ts +37 -0
- package/dist/lib/device/aspect-ratio.js +44 -0
- package/dist/lib/entities/actor.js +125 -0
- package/dist/lib/entities/box.js +68 -0
- package/dist/lib/entities/builder.js +79 -0
- package/dist/lib/entities/create.js +31 -0
- package/dist/lib/entities/delegates/animation.js +58 -0
- package/dist/lib/entities/delegates/debug.js +72 -0
- package/dist/lib/entities/delegates/loader.js +19 -0
- package/dist/lib/entities/destroy.js +15 -0
- package/dist/lib/entities/entity.d.ts +3 -1
- package/dist/lib/entities/entity.js +120 -0
- package/dist/lib/entities/plane.js +81 -0
- package/dist/lib/entities/rect.js +160 -0
- package/dist/lib/entities/sphere.js +68 -0
- package/dist/lib/entities/sprite.js +118 -0
- package/dist/lib/entities/text.js +111 -0
- package/dist/lib/entities/zone.js +103 -0
- package/dist/lib/game/game-blueprint.d.ts +44 -0
- package/dist/lib/game/game-canvas.d.ts +34 -0
- package/dist/lib/game/game-canvas.js +57 -0
- package/dist/lib/game/game-config.d.ts +47 -0
- package/dist/lib/game/game-config.js +53 -0
- package/dist/lib/game/game-default.d.ts +18 -0
- package/dist/lib/game/game-default.js +24 -0
- package/dist/lib/game/game-state.js +17 -0
- package/dist/lib/game/game.d.ts +2 -5
- package/dist/lib/game/game.js +133 -0
- package/dist/lib/game/zylem-game.d.ts +12 -1
- package/dist/lib/game/zylem-game.js +133 -0
- package/dist/lib/graphics/geometries/XZPlaneGeometry.js +34 -0
- package/dist/lib/graphics/material.d.ts +1 -1
- package/dist/lib/graphics/material.js +64 -0
- package/dist/lib/graphics/mesh.js +14 -0
- package/dist/lib/graphics/render-pass.js +56 -0
- package/dist/lib/graphics/shaders/fragment/debug.glsl.js +23 -0
- package/dist/lib/graphics/shaders/fragment/fire.glsl.js +52 -0
- package/dist/lib/graphics/shaders/fragment/standard.glsl.js +11 -0
- package/dist/lib/graphics/shaders/fragment/stars.glsl.js +44 -0
- package/dist/lib/graphics/shaders/vertex/debug.glsl.js +15 -0
- package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +11 -0
- package/dist/lib/graphics/shaders/vertex/standard.glsl.js +9 -0
- package/dist/lib/graphics/zylem-scene.d.ts +7 -7
- package/dist/lib/graphics/zylem-scene.js +75 -0
- package/dist/lib/input/gamepad-provider.js +58 -0
- package/dist/lib/input/input-manager.js +70 -0
- package/dist/lib/input/keyboard-provider.js +120 -0
- package/dist/lib/stage/debug-entity-cursor.js +53 -0
- package/dist/lib/stage/entity-spawner.js +27 -0
- package/dist/lib/stage/stage-blueprint.d.ts +44 -0
- package/dist/lib/stage/stage-blueprint.js +56 -0
- package/dist/lib/stage/stage-debug-delegate.js +100 -0
- package/dist/lib/stage/stage-default.d.ts +9 -0
- package/dist/lib/stage/stage-default.js +42 -0
- package/dist/lib/stage/stage-state.js +36 -0
- package/dist/lib/stage/stage.d.ts +2 -2
- package/dist/lib/stage/stage.js +60 -0
- package/dist/lib/stage/zylem-stage.d.ts +4 -3
- package/dist/lib/stage/zylem-stage.js +268 -0
- package/dist/lib/systems/transformable.system.js +43 -0
- package/dist/main.d.ts +6 -15
- package/dist/main.js +56 -45933
- package/dist/stage.d.ts +6 -0
- package/dist/stage.js +22 -0
- package/dist/tests/stage/stage-blueprint.spec.d.ts +1 -0
- package/package.json +35 -1
- package/dist/lib/actions/behaviors/index.d.ts +0 -1
- package/dist/lib/core/game-canvas.d.ts +0 -4
- package/dist/main.cjs +0 -4023
|
@@ -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,44 @@
|
|
|
1
|
+
import type { Stage } from './stage';
|
|
2
|
+
import type { StageOptions, ZylemStageConfig } from './zylem-stage';
|
|
3
|
+
/**
|
|
4
|
+
* A lightweight, serializable blueprint representing the initial configuration
|
|
5
|
+
* of a `ZylemStage`. It is intentionally minimal and should not include
|
|
6
|
+
* entities, functions, or runtime references. Use blueprints only to build
|
|
7
|
+
* stages.
|
|
8
|
+
*/
|
|
9
|
+
export interface StageBlueprint {
|
|
10
|
+
id: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
config: Partial<ZylemStageConfig>;
|
|
13
|
+
}
|
|
14
|
+
export declare const stageBlueprintsState: {
|
|
15
|
+
byId: Record<string, StageBlueprint>;
|
|
16
|
+
order: string[];
|
|
17
|
+
currentId: string | null;
|
|
18
|
+
};
|
|
19
|
+
/** Reset the blueprints store back to its initial empty state. */
|
|
20
|
+
export declare function resetStageBlueprints(): void;
|
|
21
|
+
/** Create and register a new `StageBlueprint`. */
|
|
22
|
+
export declare function createStageBlueprint(config: Partial<ZylemStageConfig>, options?: {
|
|
23
|
+
id?: string;
|
|
24
|
+
name?: string;
|
|
25
|
+
setCurrent?: boolean;
|
|
26
|
+
}): StageBlueprint;
|
|
27
|
+
/** Upsert a blueprint into the store. */
|
|
28
|
+
export declare function upsertStageBlueprint(blueprint: StageBlueprint): void;
|
|
29
|
+
/** Remove a blueprint by id. */
|
|
30
|
+
export declare function removeStageBlueprint(id: string): void;
|
|
31
|
+
/** Get a blueprint by id. */
|
|
32
|
+
export declare function getStageBlueprint(id: string): StageBlueprint | undefined;
|
|
33
|
+
/** List all blueprints in insertion order. */
|
|
34
|
+
export declare function listStageBlueprints(): StageBlueprint[];
|
|
35
|
+
/** Set the current blueprint id (or clear by passing null). */
|
|
36
|
+
export declare function setCurrentStageBlueprint(id: string | null): void;
|
|
37
|
+
/** Get the current blueprint object, if any. */
|
|
38
|
+
export declare function getCurrentStageBlueprint(): StageBlueprint | null;
|
|
39
|
+
/**
|
|
40
|
+
* Build a `Stage` instance from a blueprint and optional extra `StageOptions`
|
|
41
|
+
* (e.g., entities or a camera wrapper). This does not load the stage; callers
|
|
42
|
+
* should pass the returned `Stage` to the game and call `load` as usual.
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildStageFromBlueprint(input: string | StageBlueprint, ...extras: StageOptions): Stage;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { proxy as d } from "valtio/vanilla";
|
|
2
|
+
import { deepClone as i } from "valtio/utils";
|
|
3
|
+
import { nanoid as c } from "nanoid";
|
|
4
|
+
import { stage as l } from "./stage.js";
|
|
5
|
+
const u = {
|
|
6
|
+
byId: {},
|
|
7
|
+
order: [],
|
|
8
|
+
currentId: null
|
|
9
|
+
}, e = d(i(u));
|
|
10
|
+
function m() {
|
|
11
|
+
const r = i(u);
|
|
12
|
+
Object.keys(r).forEach((t) => {
|
|
13
|
+
e[t] = r[t];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function I(r, t) {
|
|
17
|
+
const n = t?.id ?? c(), o = { id: n, name: t?.name, config: { ...r } };
|
|
18
|
+
return e.byId[n] = o, e.order.includes(n) || (e.order = [...e.order, n]), t?.setCurrent && (e.currentId = n), o;
|
|
19
|
+
}
|
|
20
|
+
function S(r) {
|
|
21
|
+
e.byId[r.id] = { ...r, config: { ...r.config } }, e.order.includes(r.id) || (e.order = [...e.order, r.id]);
|
|
22
|
+
}
|
|
23
|
+
function B(r) {
|
|
24
|
+
delete e.byId[r], e.order = e.order.filter((t) => t !== r), e.currentId === r && (e.currentId = null);
|
|
25
|
+
}
|
|
26
|
+
function f(r) {
|
|
27
|
+
return e.byId[r];
|
|
28
|
+
}
|
|
29
|
+
function b() {
|
|
30
|
+
return e.order.map((r) => e.byId[r]).filter((r) => !!r);
|
|
31
|
+
}
|
|
32
|
+
function y(r) {
|
|
33
|
+
e.currentId = r;
|
|
34
|
+
}
|
|
35
|
+
function C() {
|
|
36
|
+
const r = e.currentId;
|
|
37
|
+
return r ? e.byId[r] ?? null : null;
|
|
38
|
+
}
|
|
39
|
+
function h(r, ...t) {
|
|
40
|
+
const n = typeof r == "string" ? f(r) : r;
|
|
41
|
+
if (!n)
|
|
42
|
+
throw new Error("Stage blueprint not found");
|
|
43
|
+
return l(n.config, ...t);
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
h as buildStageFromBlueprint,
|
|
47
|
+
I as createStageBlueprint,
|
|
48
|
+
C as getCurrentStageBlueprint,
|
|
49
|
+
f as getStageBlueprint,
|
|
50
|
+
b as listStageBlueprints,
|
|
51
|
+
B as removeStageBlueprint,
|
|
52
|
+
m as resetStageBlueprints,
|
|
53
|
+
y as setCurrentStageBlueprint,
|
|
54
|
+
e as stageBlueprintsState,
|
|
55
|
+
S as upsertStageBlueprint
|
|
56
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StageOptions, ZylemStageConfig } from './zylem-stage';
|
|
2
|
+
export declare const stageDefaultsState: Partial<ZylemStageConfig>;
|
|
3
|
+
/** Replace multiple defaults at once (shallow merge). */
|
|
4
|
+
export declare function setStageDefaults(partial: Partial<ZylemStageConfig>): void;
|
|
5
|
+
/** Reset defaults back to library defaults. */
|
|
6
|
+
export declare function resetStageDefaults(): void;
|
|
7
|
+
export declare function getStageOptions(options: StageOptions): StageOptions;
|
|
8
|
+
/** Get a plain object copy of the current defaults. */
|
|
9
|
+
export declare function getStageDefaultConfig(): Partial<ZylemStageConfig>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { proxy as i } from "valtio/vanilla";
|
|
2
|
+
import { Vector3 as r } from "three";
|
|
3
|
+
import { ZylemBlueColor as g } from "../core/utility/vector.js";
|
|
4
|
+
const o = {
|
|
5
|
+
backgroundColor: g,
|
|
6
|
+
backgroundImage: null,
|
|
7
|
+
inputs: {
|
|
8
|
+
p1: ["gamepad-1", "keyboard"],
|
|
9
|
+
p2: ["gamepad-2", "keyboard"]
|
|
10
|
+
},
|
|
11
|
+
gravity: new r(0, 0, 0),
|
|
12
|
+
variables: {}
|
|
13
|
+
}, t = i({
|
|
14
|
+
...o
|
|
15
|
+
});
|
|
16
|
+
function b(a) {
|
|
17
|
+
Object.assign(t, a);
|
|
18
|
+
}
|
|
19
|
+
function d() {
|
|
20
|
+
Object.assign(t, o);
|
|
21
|
+
}
|
|
22
|
+
function m(a) {
|
|
23
|
+
const n = u();
|
|
24
|
+
let e = {};
|
|
25
|
+
return typeof a[0] == "object" && (e = a.shift() ?? {}), [{ ...n, ...e }, ...a];
|
|
26
|
+
}
|
|
27
|
+
function u() {
|
|
28
|
+
return {
|
|
29
|
+
backgroundColor: t.backgroundColor,
|
|
30
|
+
backgroundImage: t.backgroundImage ?? null,
|
|
31
|
+
inputs: t.inputs ? { ...t.inputs } : void 0,
|
|
32
|
+
gravity: t.gravity,
|
|
33
|
+
variables: t.variables ? { ...t.variables } : void 0
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
u as getStageDefaultConfig,
|
|
38
|
+
m as getStageOptions,
|
|
39
|
+
d as resetStageDefaults,
|
|
40
|
+
b as setStageDefaults,
|
|
41
|
+
t as stageDefaultsState
|
|
42
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseNode } from '../core/base-node';
|
|
2
2
|
import { DestroyFunction, SetupContext, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';
|
|
3
|
-
import { StageOptions, ZylemStage } from './zylem-stage';
|
|
3
|
+
import { StageOptionItem, StageOptions, ZylemStage } from './zylem-stage';
|
|
4
4
|
import { ZylemCamera } from '../camera/zylem-camera';
|
|
5
5
|
import { CameraWrapper } from '../camera/camera';
|
|
6
6
|
type NodeLike = {
|
|
@@ -10,7 +10,7 @@ type AnyNode = NodeLike | Promise<NodeLike>;
|
|
|
10
10
|
type EntityInput = AnyNode | (() => AnyNode) | (() => Promise<any>);
|
|
11
11
|
export declare class Stage {
|
|
12
12
|
stageRef: ZylemStage;
|
|
13
|
-
options:
|
|
13
|
+
options: StageOptionItem[];
|
|
14
14
|
update: UpdateFunction<ZylemStage>;
|
|
15
15
|
setup: SetupFunction<ZylemStage>;
|
|
16
16
|
destroy: DestroyFunction<ZylemStage>;
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
import { getStageOptions as f } from "./stage-default.js";
|
|
5
|
+
class d {
|
|
6
|
+
stageRef;
|
|
7
|
+
options = [];
|
|
8
|
+
update = () => {
|
|
9
|
+
};
|
|
10
|
+
setup = () => {
|
|
11
|
+
};
|
|
12
|
+
destroy = () => {
|
|
13
|
+
};
|
|
14
|
+
constructor(t) {
|
|
15
|
+
this.options = t, this.stageRef = new n(this.options);
|
|
16
|
+
}
|
|
17
|
+
async load(t, e) {
|
|
18
|
+
this.stageRef.wrapperRef = this;
|
|
19
|
+
const s = e instanceof r ? e.cameraRef : e;
|
|
20
|
+
await this.stageRef.load(t, s);
|
|
21
|
+
}
|
|
22
|
+
async addEntities(t) {
|
|
23
|
+
this.options.push(...t), this.stageRef.enqueue(...t);
|
|
24
|
+
}
|
|
25
|
+
add(...t) {
|
|
26
|
+
this.stageRef.enqueue(...t);
|
|
27
|
+
}
|
|
28
|
+
start(t) {
|
|
29
|
+
this.stageRef?.nodeSetup(t), this.stageRef.onEntityAdded((e) => {
|
|
30
|
+
const s = this.stageRef.buildEntityState(e);
|
|
31
|
+
i.entities = [...i.entities, s];
|
|
32
|
+
}, { replayExisting: !0 });
|
|
33
|
+
}
|
|
34
|
+
onUpdate(...t) {
|
|
35
|
+
this.stageRef.update = (e) => {
|
|
36
|
+
const s = { ...e, stage: this };
|
|
37
|
+
t.forEach((o) => o(s));
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
onSetup(t) {
|
|
41
|
+
this.stageRef.setup = t;
|
|
42
|
+
}
|
|
43
|
+
onDestroy(t) {
|
|
44
|
+
this.stageRef.destroy = t;
|
|
45
|
+
}
|
|
46
|
+
setVariable(t, e) {
|
|
47
|
+
g(t, e);
|
|
48
|
+
}
|
|
49
|
+
getVariable(t) {
|
|
50
|
+
return p(t);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function l(...a) {
|
|
54
|
+
const t = f(a);
|
|
55
|
+
return new d([...t]);
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
d as Stage,
|
|
59
|
+
l as stage
|
|
60
|
+
};
|
|
@@ -12,7 +12,7 @@ import { StageDebugDelegate } from './stage-debug-delegate';
|
|
|
12
12
|
import { BaseEntityInterface } from '../types/entity-types';
|
|
13
13
|
export interface ZylemStageConfig {
|
|
14
14
|
inputs: Record<string, string[]>;
|
|
15
|
-
backgroundColor: Color;
|
|
15
|
+
backgroundColor: Color | string;
|
|
16
16
|
backgroundImage: string | null;
|
|
17
17
|
gravity: Vector3;
|
|
18
18
|
variables: Record<string, any>;
|
|
@@ -21,8 +21,9 @@ export interface ZylemStageConfig {
|
|
|
21
21
|
type NodeLike = {
|
|
22
22
|
create: Function;
|
|
23
23
|
};
|
|
24
|
-
type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);
|
|
25
|
-
export type
|
|
24
|
+
export type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);
|
|
25
|
+
export type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;
|
|
26
|
+
export type StageOptions = [] | [Partial<ZylemStageConfig>, ...StageOptionItem[]];
|
|
26
27
|
export type StageState = ZylemStageConfig & {
|
|
27
28
|
entities: GameEntityInterface[];
|
|
28
29
|
};
|