@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,11 @@
1
+ import { proxy as s } from "valtio/vanilla";
2
+ const o = s({
3
+ messages: []
4
+ }), n = (t) => {
5
+ const e = `[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ${t}`;
6
+ o.messages.push(e);
7
+ };
8
+ export {
9
+ o as consoleState,
10
+ n as printToConsole
11
+ };
@@ -0,0 +1,40 @@
1
+ import { proxy as s } from "valtio/vanilla";
2
+ import { printToConsole as t } from "./console/console-state.js";
3
+ const n = {
4
+ NONE: "NONE",
5
+ SELECT: "SELECT",
6
+ DELETE: "DELETE"
7
+ }, o = s({
8
+ on: !1,
9
+ paused: !1,
10
+ configuration: {
11
+ showCollisionBounds: !1,
12
+ showModelBounds: !1,
13
+ showSpriteBounds: !1
14
+ },
15
+ hovered: null,
16
+ selected: [],
17
+ tool: n.NONE
18
+ }), r = (e = !1) => {
19
+ o.on = e;
20
+ }, u = (e) => {
21
+ o.selected.push(e);
22
+ }, E = () => o.tool, a = (e) => {
23
+ o.hovered = e;
24
+ }, c = () => {
25
+ o.hovered = null;
26
+ }, i = () => o.hovered, f = (e) => {
27
+ o.paused = e, t(e ? "Paused" : "Resumed");
28
+ }, p = () => o.paused;
29
+ export {
30
+ n as DebugTools,
31
+ o as debugState,
32
+ E as getDebugTool,
33
+ i as getHoveredEntity,
34
+ p as isPaused,
35
+ c as resetHoveredEntity,
36
+ r as setDebugFlag,
37
+ a as setHoveredEntity,
38
+ f as setPaused,
39
+ u as setSelectedEntity
40
+ };
@@ -0,0 +1,125 @@
1
+ import { ColliderDesc as l, ActiveCollisionTypes as m } from "@dimforge/rapier3d-compat";
2
+ import { Vector3 as r, Group as d, SkinnedMesh as u } from "three";
3
+ import { GameEntity as p } from "./entity.js";
4
+ import { createEntity as g } from "./create.js";
5
+ import { EntityAssetLoader as y } from "../core/entity-asset-loader.js";
6
+ import { AnimationDelegate as f } from "./delegates/animation.js";
7
+ import { EntityCollisionBuilder as b, EntityBuilder as _ } from "./builder.js";
8
+ const c = {
9
+ position: { x: 0, y: 0, z: 0 },
10
+ collision: {
11
+ static: !1,
12
+ size: new r(0.5, 0.5, 0.5),
13
+ position: new r(0, 0, 0)
14
+ },
15
+ material: {
16
+ shader: "standard"
17
+ },
18
+ animations: [],
19
+ models: []
20
+ };
21
+ class j extends b {
22
+ height = 1;
23
+ objectModel = null;
24
+ constructor(t) {
25
+ super(), this.objectModel = t.objectModel;
26
+ }
27
+ createColliderFromObjectModel(t) {
28
+ if (!t)
29
+ return l.capsule(1, 1);
30
+ const e = t.children.find((s) => s instanceof u).geometry;
31
+ if (e && (e.computeBoundingBox(), e.boundingBox)) {
32
+ const s = e.boundingBox.max.y, h = e.boundingBox.min.y;
33
+ this.height = s - h;
34
+ }
35
+ this.height = 1;
36
+ let o = l.capsule(this.height / 2, 1);
37
+ return o.setSensor(!1), o.setTranslation(0, this.height + 0.5, 0), o.activeCollisionTypes = m.DEFAULT, o;
38
+ }
39
+ collider(t) {
40
+ return this.createColliderFromObjectModel(this.objectModel);
41
+ }
42
+ }
43
+ class C extends _ {
44
+ createEntity(t) {
45
+ return new a(t);
46
+ }
47
+ }
48
+ const D = Symbol("Actor");
49
+ class a extends p {
50
+ static type = D;
51
+ _object = null;
52
+ _animationDelegate = null;
53
+ _modelFileNames = [];
54
+ _assetLoader = new y();
55
+ controlledRotation = !1;
56
+ constructor(t) {
57
+ super(), this.options = { ...c, ...t }, this.lifeCycleDelegate = {
58
+ update: [this.actorUpdate.bind(this)]
59
+ }, this.controlledRotation = !0;
60
+ }
61
+ async load() {
62
+ this._modelFileNames = this.options.models || [], await this.loadModels(), this._object && (this._animationDelegate = new f(this._object), await this._animationDelegate.loadAnimations(this.options.animations || []));
63
+ }
64
+ async data() {
65
+ return {
66
+ animations: this._animationDelegate?.animations,
67
+ objectModel: this._object
68
+ };
69
+ }
70
+ async actorUpdate(t) {
71
+ this._animationDelegate?.update(t.delta);
72
+ }
73
+ async loadModels() {
74
+ if (this._modelFileNames.length === 0)
75
+ return;
76
+ const t = this._modelFileNames.map((e) => this._assetLoader.loadFile(e)), i = await Promise.all(t);
77
+ i[0]?.object && (this._object = i[0].object), this._object && (this.group = new d(), this.group.attach(this._object), this.group.scale.set(this.options.scale?.x || 1, this.options.scale?.y || 1, this.options.scale?.z || 1));
78
+ }
79
+ playAnimation(t) {
80
+ this._animationDelegate?.playAnimation(t);
81
+ }
82
+ get object() {
83
+ return this._object;
84
+ }
85
+ /**
86
+ * Provide custom debug information for the actor
87
+ * This will be merged with the default debug information
88
+ */
89
+ getDebugInfo() {
90
+ const t = {
91
+ type: "Actor",
92
+ models: this._modelFileNames.length > 0 ? this._modelFileNames : "none",
93
+ modelLoaded: !!this._object,
94
+ scale: this.options.scale ? `${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` : "1, 1, 1"
95
+ };
96
+ if (this._animationDelegate && (t.currentAnimation = this._animationDelegate.currentAnimationKey || "none", t.animationsCount = this.options.animations?.length || 0), this._object) {
97
+ let i = 0, e = 0;
98
+ this._object.traverse((o) => {
99
+ if (o.isMesh) {
100
+ i++;
101
+ const s = o.geometry;
102
+ s && s.attributes.position && (e += s.attributes.position.count);
103
+ }
104
+ }), t.meshCount = i, t.vertexCount = e;
105
+ }
106
+ return t;
107
+ }
108
+ }
109
+ async function T(...n) {
110
+ return await g({
111
+ args: n,
112
+ defaultConfig: c,
113
+ EntityClass: a,
114
+ BuilderClass: C,
115
+ CollisionBuilderClass: j,
116
+ entityType: a.type
117
+ });
118
+ }
119
+ export {
120
+ D as ACTOR_TYPE,
121
+ C as ActorBuilder,
122
+ j as ActorCollisionBuilder,
123
+ a as ZylemActor,
124
+ T as actor
125
+ };
@@ -0,0 +1,68 @@
1
+ import { ColliderDesc as a } from "@dimforge/rapier3d-compat";
2
+ import { Color as d, Vector3 as n, BoxGeometry as u } from "three";
3
+ import { GameEntity as y } from "./entity.js";
4
+ import { EntityCollisionBuilder as f, EntityBuilder as x, EntityMeshBuilder as m } from "./builder.js";
5
+ import { DebugDelegate as p } from "./delegates/debug.js";
6
+ import { createEntity as z } from "./create.js";
7
+ const l = {
8
+ size: new n(1, 1, 1),
9
+ position: new n(0, 0, 0),
10
+ collision: {
11
+ static: !1
12
+ },
13
+ material: {
14
+ color: new d("#ffffff"),
15
+ shader: "standard"
16
+ }
17
+ };
18
+ class B extends f {
19
+ collider(t) {
20
+ const e = t.size || new n(1, 1, 1), s = { x: e.x / 2, y: e.y / 2, z: e.z / 2 };
21
+ return a.cuboid(s.x, s.y, s.z);
22
+ }
23
+ }
24
+ class b extends m {
25
+ build(t) {
26
+ const e = t.size ?? new n(1, 1, 1);
27
+ return new u(e.x, e.y, e.z);
28
+ }
29
+ }
30
+ class C extends x {
31
+ createEntity(t) {
32
+ return new i(t);
33
+ }
34
+ }
35
+ const h = Symbol("Box");
36
+ class i extends y {
37
+ static type = h;
38
+ constructor(t) {
39
+ super(), this.options = { ...l, ...t };
40
+ }
41
+ buildInfo() {
42
+ const e = new p(this).buildDebugInfo(), { x: s, y: r, z: c } = this.options.size ?? { x: 1, y: 1, z: 1 };
43
+ return {
44
+ ...e,
45
+ type: String(i.type),
46
+ size: `${s}, ${r}, ${c}`
47
+ };
48
+ }
49
+ }
50
+ async function $(...o) {
51
+ return z({
52
+ args: o,
53
+ defaultConfig: l,
54
+ EntityClass: i,
55
+ BuilderClass: C,
56
+ MeshBuilderClass: b,
57
+ CollisionBuilderClass: B,
58
+ entityType: i.type
59
+ });
60
+ }
61
+ export {
62
+ h as BOX_TYPE,
63
+ C as BoxBuilder,
64
+ B as BoxCollisionBuilder,
65
+ b as BoxMeshBuilder,
66
+ i as ZylemBox,
67
+ $ as box
68
+ };
@@ -0,0 +1,79 @@
1
+ import { Mesh as l, Color as n, BufferGeometry as u } from "three";
2
+ import { CollisionBuilder as h } from "../collision/collision-builder.js";
3
+ import { MeshBuilder as m } from "../graphics/mesh.js";
4
+ import { MaterialBuilder as d } from "../graphics/material.js";
5
+ class y extends h {
6
+ }
7
+ class b extends m {
8
+ build(i) {
9
+ return new u();
10
+ }
11
+ postBuild() {
12
+ }
13
+ }
14
+ class M {
15
+ meshBuilder;
16
+ collisionBuilder;
17
+ materialBuilder;
18
+ options;
19
+ entity;
20
+ constructor(i, s, t, e) {
21
+ this.options = i, this.entity = s, this.meshBuilder = t, this.collisionBuilder = e, this.materialBuilder = new d();
22
+ const o = {
23
+ meshBuilder: this.meshBuilder,
24
+ collisionBuilder: this.collisionBuilder,
25
+ materialBuilder: this.materialBuilder
26
+ };
27
+ this.options._builders = o;
28
+ }
29
+ withPosition(i) {
30
+ return this.options.position = i, this;
31
+ }
32
+ async withMaterial(i, s) {
33
+ return this.materialBuilder && await this.materialBuilder.build(i, s), this;
34
+ }
35
+ applyMaterialToGroup(i, s) {
36
+ i.traverse((t) => {
37
+ t instanceof l && t.type === "SkinnedMesh" && s[0] && !t.material.map && (t.material = s[0]), t.castShadow = !0, t.receiveShadow = !0;
38
+ });
39
+ }
40
+ async build() {
41
+ const i = this.entity;
42
+ if (this.materialBuilder && (i.materials = this.materialBuilder.materials), this.meshBuilder && i.materials) {
43
+ const s = this.meshBuilder.build(this.options);
44
+ i.mesh = this.meshBuilder._build(this.options, s, i.materials), this.meshBuilder.postBuild();
45
+ }
46
+ if (i.group && i.materials && this.applyMaterialToGroup(i.group, i.materials), this.collisionBuilder) {
47
+ this.collisionBuilder.withCollision(this.options?.collision || {});
48
+ const [s, t] = this.collisionBuilder.build(this.options);
49
+ i.bodyDesc = s, i.colliderDesc = t;
50
+ const { x: e, y: o, z: a } = this.options.position || { x: 0, y: 0, z: 0 };
51
+ i.bodyDesc.setTranslation(e, o, a);
52
+ }
53
+ if (this.options.collisionType && (i.collisionType = this.options.collisionType), this.options.color instanceof n) {
54
+ const s = (t) => {
55
+ const e = t;
56
+ e && e.color && e.color.set && e.color.set(this.options.color);
57
+ };
58
+ if (i.materials?.length)
59
+ for (const t of i.materials)
60
+ s(t);
61
+ if (i.mesh && i.mesh.material) {
62
+ const t = i.mesh.material;
63
+ Array.isArray(t) ? t.forEach(s) : s(t);
64
+ }
65
+ i.group && i.group.traverse((t) => {
66
+ if (t instanceof l && t.material) {
67
+ const e = t.material;
68
+ Array.isArray(e) ? e.forEach(s) : s(e);
69
+ }
70
+ });
71
+ }
72
+ return i;
73
+ }
74
+ }
75
+ export {
76
+ M as EntityBuilder,
77
+ y as EntityCollisionBuilder,
78
+ b as EntityMeshBuilder
79
+ };
@@ -0,0 +1,31 @@
1
+ import { BaseNode as s } from "../core/base-node.js";
2
+ import { isLoadable as p, EntityLoader as C } from "./delegates/loader.js";
3
+ async function E(w) {
4
+ const { args: n, defaultConfig: l, EntityClass: g, BuilderClass: y, entityType: c, MeshBuilderClass: f, CollisionBuilderClass: d } = w;
5
+ let e = null, r;
6
+ const u = n.findIndex((i) => !(i instanceof s));
7
+ u !== -1 && (r = n.splice(u, 1).find((t) => !(t instanceof s)));
8
+ const m = r ? { ...l, ...r } : l;
9
+ n.push(m);
10
+ for (const i of n) {
11
+ if (i instanceof s)
12
+ continue;
13
+ let t = null;
14
+ const a = new g(i);
15
+ try {
16
+ if (p(a)) {
17
+ const o = new C(a);
18
+ await o.load(), t = await o.data();
19
+ }
20
+ } catch (o) {
21
+ console.error("Error creating entity with loader:", o);
22
+ }
23
+ e = new y(i, a, f ? new f(t) : null, d ? new d(t) : null), i.material && await e.withMaterial(i.material, c);
24
+ }
25
+ if (!e)
26
+ throw new Error(`missing options for ${String(c)}, builder is not initialized.`);
27
+ return await e.build();
28
+ }
29
+ export {
30
+ E as createEntity
31
+ };
@@ -0,0 +1,58 @@
1
+ import { AnimationMixer as u, LoopOnce as c, LoopRepeat as h } from "three";
2
+ import { EntityAssetLoader as _ } from "../../core/entity-asset-loader.js";
3
+ class d {
4
+ target;
5
+ _mixer = null;
6
+ _actions = {};
7
+ _animations = [];
8
+ _currentAction = null;
9
+ _pauseAtPercentage = 0;
10
+ _isPaused = !1;
11
+ _queuedKey = null;
12
+ _fadeDuration = 0.5;
13
+ _currentKey = "";
14
+ _assetLoader = new _();
15
+ constructor(e) {
16
+ this.target = e;
17
+ }
18
+ async loadAnimations(e) {
19
+ if (!e.length)
20
+ return;
21
+ const i = await Promise.all(e.map((t) => this._assetLoader.loadFile(t.path)));
22
+ this._animations = i.filter((t) => !!t.animation).map((t) => t.animation), this._animations.length && (this._mixer = new u(this.target), this._animations.forEach((t, n) => {
23
+ const a = e[n].key || n.toString();
24
+ this._actions[a] = this._mixer.clipAction(t);
25
+ }), this.playAnimation({ key: Object.keys(this._actions)[0] }));
26
+ }
27
+ update(e) {
28
+ if (!this._mixer || !this._currentAction)
29
+ return;
30
+ this._mixer.update(e);
31
+ const i = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);
32
+ if (!this._isPaused && this._pauseAtPercentage > 0 && this._currentAction.time >= i && (this._currentAction.time = i, this._currentAction.paused = !0, this._isPaused = !0, this._queuedKey !== null)) {
33
+ const t = this._actions[this._queuedKey];
34
+ t.reset().play(), this._currentAction.crossFadeTo(t, this._fadeDuration, !1), this._currentAction = t, this._currentKey = this._queuedKey, this._queuedKey = null;
35
+ }
36
+ }
37
+ playAnimation(e) {
38
+ if (!this._mixer)
39
+ return;
40
+ const { key: i, pauseAtPercentage: t = 0, pauseAtEnd: n = !1, fadeToKey: a, fadeDuration: o = 0.5 } = e;
41
+ if (i === this._currentKey)
42
+ return;
43
+ this._queuedKey = a || null, this._fadeDuration = o, this._pauseAtPercentage = n ? 100 : t, this._isPaused = !1;
44
+ const r = this._currentAction;
45
+ r && r.stop();
46
+ const s = this._actions[i];
47
+ s && (this._pauseAtPercentage > 0 ? (s.setLoop(c, 1 / 0), s.clampWhenFinished = !0) : (s.setLoop(h, 1 / 0), s.clampWhenFinished = !1), r && r.crossFadeTo(s, o, !1), s.reset().play(), this._currentAction = s, this._currentKey = i);
48
+ }
49
+ get currentAnimationKey() {
50
+ return this._currentKey;
51
+ }
52
+ get animations() {
53
+ return this._animations;
54
+ }
55
+ }
56
+ export {
57
+ d as AnimationDelegate
58
+ };
@@ -0,0 +1,72 @@
1
+ import { MeshStandardMaterial as c, MeshBasicMaterial as u, MeshPhongMaterial as f } from "three";
2
+ function g(o) {
3
+ return o && typeof o.getDebugInfo == "function";
4
+ }
5
+ class d {
6
+ entity;
7
+ constructor(t) {
8
+ this.entity = t;
9
+ }
10
+ /**
11
+ * Get formatted position string
12
+ */
13
+ getPositionString() {
14
+ if (this.entity.mesh) {
15
+ const { x: n, y: s, z: r } = this.entity.mesh.position;
16
+ return `${n.toFixed(2)}, ${s.toFixed(2)}, ${r.toFixed(2)}`;
17
+ }
18
+ const { x: t, y: i, z: e } = this.entity.options.position || { x: 0, y: 0, z: 0 };
19
+ return `${t.toFixed(2)}, ${i.toFixed(2)}, ${e.toFixed(2)}`;
20
+ }
21
+ /**
22
+ * Get formatted rotation string (in degrees)
23
+ */
24
+ getRotationString() {
25
+ if (this.entity.mesh) {
26
+ const { x: s, y: r, z: y } = this.entity.mesh.rotation, a = (h) => (h * 180 / Math.PI).toFixed(1);
27
+ return `${a(s)}°, ${a(r)}°, ${a(y)}°`;
28
+ }
29
+ const { x: t, y: i, z: e } = this.entity.options.rotation || { x: 0, y: 0, z: 0 }, n = (s) => (s * 180 / Math.PI).toFixed(1);
30
+ return `${n(t)}°, ${n(i)}°, ${n(e)}°`;
31
+ }
32
+ /**
33
+ * Get material information
34
+ */
35
+ getMaterialInfo() {
36
+ if (!this.entity.mesh || !this.entity.mesh.material)
37
+ return { type: "none" };
38
+ const t = Array.isArray(this.entity.mesh.material) ? this.entity.mesh.material[0] : this.entity.mesh.material, i = {
39
+ type: t.type
40
+ };
41
+ return (t instanceof c || t instanceof u || t instanceof f) && (i.color = `#${t.color.getHexString()}`, i.opacity = t.opacity, i.transparent = t.transparent), "roughness" in t && (i.roughness = t.roughness), "metalness" in t && (i.metalness = t.metalness), i;
42
+ }
43
+ getPhysicsInfo() {
44
+ if (!this.entity.body)
45
+ return null;
46
+ const t = {
47
+ type: this.entity.body.bodyType(),
48
+ mass: this.entity.body.mass(),
49
+ isEnabled: this.entity.body.isEnabled(),
50
+ isSleeping: this.entity.body.isSleeping()
51
+ }, i = this.entity.body.linvel();
52
+ return t.velocity = `${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}`, t;
53
+ }
54
+ buildDebugInfo() {
55
+ const t = {
56
+ name: this.entity.name || this.entity.uuid,
57
+ uuid: this.entity.uuid,
58
+ position: this.getPositionString(),
59
+ rotation: this.getRotationString(),
60
+ material: this.getMaterialInfo()
61
+ }, i = this.getPhysicsInfo();
62
+ if (i && (t.physics = i), this.entity.behaviors.length > 0 && (t.behaviors = this.entity.behaviors.map((e) => e.constructor.name)), g(this.entity)) {
63
+ const e = this.entity.getDebugInfo();
64
+ return { ...t, ...e };
65
+ }
66
+ return t;
67
+ }
68
+ }
69
+ export {
70
+ d as DebugDelegate,
71
+ g as hasDebugInfo
72
+ };
@@ -0,0 +1,19 @@
1
+ function n(e) {
2
+ return typeof e?.load == "function" && typeof e?.data == "function";
3
+ }
4
+ class a {
5
+ entityReference;
6
+ constructor(t) {
7
+ this.entityReference = t;
8
+ }
9
+ async load() {
10
+ this.entityReference.load && await this.entityReference.load();
11
+ }
12
+ async data() {
13
+ return this.entityReference.data ? this.entityReference.data() : null;
14
+ }
15
+ }
16
+ export {
17
+ a as EntityLoader,
18
+ n as isLoadable
19
+ };
@@ -0,0 +1,15 @@
1
+ import { getGlobalState as n } from "../game/game-state.js";
2
+ function r(o, t, e) {
3
+ e({
4
+ me: o,
5
+ globals: t
6
+ });
7
+ }
8
+ function d(o, t) {
9
+ const e = t ?? n();
10
+ r(o, e, o.nodeDestroy.bind(o));
11
+ }
12
+ export {
13
+ d as destroy,
14
+ r as destroyEntity
15
+ };
@@ -2,7 +2,6 @@ import { Mesh, Material, ShaderMaterial, Group, Color } from "three";
2
2
  import { Collider, ColliderDesc, RigidBody, RigidBodyDesc } from "@dimforge/rapier3d-compat";
3
3
  import { Vec3 } from "../core/vector";
4
4
  import { MaterialBuilder, MaterialOptions } from "../graphics/material";
5
- import { PhysicsOptions } from "../collision/physics";
6
5
  import { CollisionOptions } from "../collision/collision";
7
6
  import { BaseNode } from "../core/base-node";
8
7
  import { DestroyContext, SetupContext, UpdateContext } from "../core/base-node-life-cycle";
@@ -39,7 +38,6 @@ export type GameEntityOptions = {
39
38
  position?: Vec3;
40
39
  batched?: boolean;
41
40
  collision?: Partial<CollisionOptions>;
42
- physics?: Partial<PhysicsOptions>;
43
41
  material?: Partial<MaterialOptions>;
44
42
  custom?: {
45
43
  [key: string]: any;
@@ -0,0 +1,116 @@
1
+ import { ShaderMaterial as s } from "three";
2
+ import { position as o, scale as a, rotation as n } from "../systems/transformable.system.js";
3
+ import { BaseNode as c } from "../core/base-node.js";
4
+ class d extends c {
5
+ group;
6
+ mesh;
7
+ materials;
8
+ bodyDesc = null;
9
+ body = null;
10
+ colliderDesc;
11
+ collider;
12
+ custom = {};
13
+ debugInfo = {};
14
+ debugMaterial;
15
+ lifeCycleDelegate = {
16
+ setup: [],
17
+ update: [],
18
+ destroy: []
19
+ };
20
+ collisionDelegate = {
21
+ collision: []
22
+ };
23
+ collisionType;
24
+ behaviorCallbackMap = {
25
+ setup: [],
26
+ update: [],
27
+ destroy: [],
28
+ collision: []
29
+ };
30
+ constructor() {
31
+ super();
32
+ }
33
+ create() {
34
+ const { position: e } = this.options, { x: t, y: i, z: l } = e || { x: 0, y: 0, z: 0 };
35
+ return this.behaviors = [
36
+ { component: o, values: { x: t, y: i, z: l } },
37
+ { component: a, values: { x: 0, y: 0, z: 0 } },
38
+ { component: n, values: { x: 0, y: 0, z: 0, w: 0 } }
39
+ ], this.name = this.options.name || "", this;
40
+ }
41
+ onSetup(...e) {
42
+ const t = [...this.lifeCycleDelegate.setup ?? [], ...e];
43
+ return this.lifeCycleDelegate = {
44
+ ...this.lifeCycleDelegate,
45
+ setup: t
46
+ }, this;
47
+ }
48
+ onUpdate(...e) {
49
+ const t = [...this.lifeCycleDelegate.update ?? [], ...e];
50
+ return this.lifeCycleDelegate = {
51
+ ...this.lifeCycleDelegate,
52
+ update: t
53
+ }, this;
54
+ }
55
+ onDestroy(...e) {
56
+ return this.lifeCycleDelegate = {
57
+ ...this.lifeCycleDelegate,
58
+ destroy: e.length > 0 ? e : void 0
59
+ }, this;
60
+ }
61
+ onCollision(...e) {
62
+ return this.collisionDelegate = {
63
+ collision: e.length > 0 ? e : void 0
64
+ }, this;
65
+ }
66
+ _setup(e) {
67
+ this.behaviorCallbackMap.setup.forEach((t) => {
68
+ t({ ...e, me: this });
69
+ }), this.lifeCycleDelegate.setup?.length && this.lifeCycleDelegate.setup.forEach((i) => {
70
+ i({ ...e, me: this });
71
+ });
72
+ }
73
+ _update(e) {
74
+ this.updateMaterials(e), this.lifeCycleDelegate.update?.length && this.lifeCycleDelegate.update.forEach((i) => {
75
+ i({ ...e, me: this });
76
+ }), this.behaviorCallbackMap.update.forEach((t) => {
77
+ t({ ...e, me: this });
78
+ });
79
+ }
80
+ _destroy(e) {
81
+ this.lifeCycleDelegate.destroy?.length && this.lifeCycleDelegate.destroy.forEach((i) => {
82
+ i({ ...e, me: this });
83
+ }), this.behaviorCallbackMap.destroy.forEach((t) => {
84
+ t({ ...e, me: this });
85
+ });
86
+ }
87
+ _collision(e, t) {
88
+ this.collisionDelegate.collision?.length && this.collisionDelegate.collision.forEach((l) => {
89
+ l({ entity: this, other: e, globals: t });
90
+ }), this.behaviorCallbackMap.collision.forEach((i) => {
91
+ i({ entity: this, other: e, globals: t });
92
+ });
93
+ }
94
+ addBehavior(e) {
95
+ const t = e.handler;
96
+ return t && this.behaviorCallbackMap[e.type].push(t), this;
97
+ }
98
+ addBehaviors(e) {
99
+ return e.forEach((t) => {
100
+ const i = t.handler;
101
+ i && this.behaviorCallbackMap[t.type].push(i);
102
+ }), this;
103
+ }
104
+ updateMaterials(e) {
105
+ if (this.materials?.length)
106
+ for (const t of this.materials)
107
+ t instanceof s && t.uniforms && t.uniforms.iTime && (t.uniforms.iTime.value += e.delta);
108
+ }
109
+ buildInfo() {
110
+ const e = {};
111
+ return e.name = this.name, e.uuid = this.uuid, e.eid = this.eid.toString(), e;
112
+ }
113
+ }
114
+ export {
115
+ d as GameEntity
116
+ };