dacha 0.15.0 → 0.15.2

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 (48) hide show
  1. package/build/contrib/components/collider/index.d.ts +19 -0
  2. package/build/contrib/components/collider/index.js +29 -0
  3. package/build/contrib/components/index.d.ts +2 -2
  4. package/build/contrib/components/index.js +1 -1
  5. package/build/contrib/systems/audio-system/index.d.ts +2 -3
  6. package/build/contrib/systems/audio-system/index.js +17 -24
  7. package/build/contrib/systems/audio-system/utils.d.ts +3 -2
  8. package/build/contrib/systems/audio-system/utils.js +6 -6
  9. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/index.js +2 -2
  10. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +2 -2
  11. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +3 -3
  12. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +2 -2
  13. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +2 -2
  14. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +2 -2
  15. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.js +2 -2
  16. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +19 -19
  17. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.js +2 -2
  18. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +6 -6
  19. package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.d.ts +2 -2
  20. package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.js +3 -5
  21. package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +1 -1
  22. package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +4 -4
  23. package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +1 -1
  24. package/build/contrib/systems/physics-system/subsystems/physics/index.js +5 -5
  25. package/build/contrib/systems/physics-system/types.d.ts +1 -1
  26. package/build/contrib/systems/sprite-renderer/renderer.d.ts +2 -3
  27. package/build/contrib/systems/sprite-renderer/renderer.js +18 -24
  28. package/build/contrib/systems/sprite-renderer/utils.d.ts +3 -2
  29. package/build/contrib/systems/sprite-renderer/utils.js +8 -8
  30. package/build/engine/scene/scene-manager.d.ts +1 -1
  31. package/build/engine/scene/scene-manager.js +41 -33
  32. package/build/engine/scene/tests/mocks/scene-config.mock.d.ts +2 -0
  33. package/build/engine/scene/tests/mocks/scene-config.mock.js +5 -0
  34. package/build/engine/scene/tests/mocks/system-config.mock.d.ts +2 -0
  35. package/build/engine/scene/tests/mocks/system-config.mock.js +4 -0
  36. package/build/engine/scene/tests/mocks/system.mock.d.ts +22 -0
  37. package/build/engine/scene/tests/mocks/system.mock.js +48 -0
  38. package/build/engine/system/index.d.ts +1 -1
  39. package/build/engine/utils/is-subclass-of.d.ts +1 -0
  40. package/build/engine/utils/is-subclass-of.js +10 -0
  41. package/build/index.d.ts +1 -1
  42. package/package.json +1 -1
  43. package/build/contrib/components/collider-container/box-collider.d.ts +0 -7
  44. package/build/contrib/components/collider-container/box-collider.js +0 -12
  45. package/build/contrib/components/collider-container/circle-collider.d.ts +0 -6
  46. package/build/contrib/components/collider-container/circle-collider.js +0 -10
  47. package/build/contrib/components/collider-container/index.d.ts +0 -13
  48. package/build/contrib/components/collider-container/index.js +0 -28
@@ -0,0 +1,19 @@
1
+ import { Component } from '../../../engine/component';
2
+ export interface ColliderConfig {
3
+ type: 'box' | 'circle';
4
+ centerX: number;
5
+ centerY: number;
6
+ sizeX?: number;
7
+ sizeY?: number;
8
+ radius?: number;
9
+ }
10
+ export declare class Collider extends Component {
11
+ type: 'box' | 'circle';
12
+ centerX: number;
13
+ centerY: number;
14
+ sizeX?: number;
15
+ sizeY?: number;
16
+ radius?: number;
17
+ constructor(config: ColliderConfig);
18
+ clone(): Collider;
19
+ }
@@ -0,0 +1,29 @@
1
+ import { Component } from '../../../engine/component';
2
+ export class Collider extends Component {
3
+ type;
4
+ centerX;
5
+ centerY;
6
+ sizeX;
7
+ sizeY;
8
+ radius;
9
+ constructor(config) {
10
+ super();
11
+ this.type = config.type;
12
+ this.centerX = config.centerX;
13
+ this.centerY = config.centerY;
14
+ this.sizeX = config.sizeX;
15
+ this.sizeY = config.sizeY;
16
+ this.radius = config.radius;
17
+ }
18
+ clone() {
19
+ return new Collider({
20
+ type: this.type,
21
+ centerX: this.centerX,
22
+ centerY: this.centerY,
23
+ sizeX: this.sizeX,
24
+ sizeY: this.sizeY,
25
+ radius: this.radius,
26
+ });
27
+ }
28
+ }
29
+ Collider.componentName = 'Collider';
@@ -2,8 +2,8 @@ export { Camera } from './camera';
2
2
  export type { CameraConfig } from './camera';
3
3
  export { KeyboardControl } from './keyboard-control';
4
4
  export type { KeyboardControlConfig } from './keyboard-control';
5
- export { ColliderContainer } from './collider-container';
6
- export type { ColliderContainerConfig } from './collider-container';
5
+ export { Collider } from './collider';
6
+ export type { ColliderConfig } from './collider';
7
7
  export { RigidBody } from './rigid-body';
8
8
  export type { RigidBodyConfig } from './rigid-body';
9
9
  export { Animatable } from './animatable';
@@ -1,6 +1,6 @@
1
1
  export { Camera } from './camera';
2
2
  export { KeyboardControl } from './keyboard-control';
3
- export { ColliderContainer } from './collider-container';
3
+ export { Collider } from './collider';
4
4
  export { RigidBody } from './rigid-body';
5
5
  export { Animatable } from './animatable';
6
6
  export { Sprite } from './sprite';
@@ -4,16 +4,15 @@ import type { WorldSystemOptions } from '../../../engine/system';
4
4
  export declare class AudioSystem extends WorldSystem {
5
5
  private templateCollection;
6
6
  private world;
7
- private scene?;
8
7
  private audioContext;
9
8
  private audioGroups;
10
9
  private audioStore;
11
10
  private audioState;
12
- private actorCollections;
11
+ private actorCollection?;
13
12
  constructor(options: WorldSystemOptions);
14
13
  onSceneLoad(scene: Scene): Promise<void>;
15
14
  onSceneEnter(scene: Scene): void;
16
- onSceneExit(scene: Scene): void;
15
+ onSceneExit(): void;
17
16
  onSceneDestroy(scene: Scene): void;
18
17
  onWorldDestroy(): void;
19
18
  private loadAudio;
@@ -4,18 +4,17 @@ import { AddActor, RemoveActor } from '../../../engine/events';
4
4
  import { CacheStore } from '../../../engine/data-lib';
5
5
  import { AudioSource } from '../../components';
6
6
  import { PlayAudio, StopAudio, SetAudioVolume, } from '../../../events';
7
- import { getAllTemplateSources, loadAudio } from './utils';
7
+ import { getAllSources, loadAudio } from './utils';
8
8
  const MASTER_GROUP = 'master';
9
9
  const VOLUME_TOLERANCE = 0.001;
10
10
  export class AudioSystem extends WorldSystem {
11
11
  templateCollection;
12
12
  world;
13
- scene;
14
13
  audioContext;
15
14
  audioGroups;
16
15
  audioStore;
17
16
  audioState;
18
- actorCollections;
17
+ actorCollection;
19
18
  constructor(options) {
20
19
  super();
21
20
  const { world, globalOptions, templateCollection } = options;
@@ -38,7 +37,6 @@ export class AudioSystem extends WorldSystem {
38
37
  }, { [MASTER_GROUP]: masterAudioGroup });
39
38
  this.audioStore = new CacheStore();
40
39
  this.audioState = new Map();
41
- this.actorCollections = {};
42
40
  this.world.addEventListener(PlayAudio, this.handlePlayAudio);
43
41
  this.world.addEventListener(StopAudio, this.handleStopAudio);
44
42
  this.world.addEventListener(SetAudioVolume, this.handleSetAudioVolume);
@@ -47,12 +45,9 @@ export class AudioSystem extends WorldSystem {
47
45
  window.addEventListener('touchstart', this.resumeIfSuspended, { once: true });
48
46
  }
49
47
  async onSceneLoad(scene) {
50
- this.actorCollections[scene.id] = new ActorCollection(scene, {
51
- components: [AudioSource],
52
- });
53
48
  const allSources = [
54
- ...getAllTemplateSources(this.templateCollection),
55
- ...this.actorCollections[scene.id].map((actor) => actor.getComponent(AudioSource).src),
49
+ ...getAllSources(this.templateCollection.getAll()),
50
+ ...getAllSources(scene.children),
56
51
  ];
57
52
  const uniqueSources = [...new Set(allSources)];
58
53
  const audioBuffers = await Promise.all(uniqueSources.map((src) => {
@@ -66,27 +61,28 @@ export class AudioSystem extends WorldSystem {
66
61
  allSources.forEach((src) => this.audioStore.retain(src));
67
62
  }
68
63
  onSceneEnter(scene) {
69
- this.scene = scene;
70
- this.actorCollections[scene.id]?.forEach((actor) => this.initAudio(actor));
71
- this.actorCollections[scene.id]?.addEventListener(AddActor, this.handleActorAdd);
72
- this.actorCollections[scene.id]?.addEventListener(RemoveActor, this.handleActorRemove);
64
+ this.actorCollection = new ActorCollection(scene, {
65
+ components: [AudioSource],
66
+ });
67
+ this.actorCollection.forEach((actor) => this.initAudio(actor));
68
+ this.actorCollection.addEventListener(AddActor, this.handleActorAdd);
69
+ this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
73
70
  }
74
- onSceneExit(scene) {
71
+ onSceneExit() {
75
72
  this.audioState.forEach((audioState) => {
76
73
  audioState.sourceNode.stop();
77
74
  });
78
- this.actorCollections[scene.id]?.removeEventListener(AddActor, this.handleActorAdd);
79
- this.actorCollections[scene.id]?.removeEventListener(RemoveActor, this.handleActorRemove);
80
- this.scene = undefined;
75
+ this.actorCollection?.removeEventListener(AddActor, this.handleActorAdd);
76
+ this.actorCollection?.removeEventListener(RemoveActor, this.handleActorRemove);
77
+ this.actorCollection = undefined;
81
78
  }
82
79
  onSceneDestroy(scene) {
83
80
  const allSources = [
84
- ...getAllTemplateSources(this.templateCollection),
85
- ...this.actorCollections[scene.id].map((actor) => actor.getComponent(AudioSource).src),
81
+ ...getAllSources(this.templateCollection.getAll()),
82
+ ...getAllSources(scene.children),
86
83
  ];
87
84
  allSources.forEach((src) => this.audioStore.release(src));
88
85
  this.audioStore.cleanReleased();
89
- delete this.actorCollections[scene.id];
90
86
  }
91
87
  onWorldDestroy() {
92
88
  void this.audioContext.close();
@@ -215,10 +211,7 @@ export class AudioSystem extends WorldSystem {
215
211
  }
216
212
  }
217
213
  update() {
218
- if (!this.scene) {
219
- return;
220
- }
221
- this.actorCollections[this.scene.id]?.forEach((actor) => {
214
+ this.actorCollection?.forEach((actor) => {
222
215
  const audioSource = actor.getComponent(AudioSource);
223
216
  const audioState = this.audioState.get(actor.id);
224
217
  if (audioSource.playing && audioState) {
@@ -1,3 +1,4 @@
1
- import type { TemplateCollection } from '../../../engine/template';
2
- export declare const getAllTemplateSources: (templateCollection: TemplateCollection) => string[];
1
+ import type { Actor } from '../../../engine/actor';
2
+ import type { Template } from '../../../engine/template';
3
+ export declare const getAllSources: (actors: (Actor | Template)[]) => string[];
3
4
  export declare const loadAudio: (url: string) => Promise<ArrayBuffer>;
@@ -1,16 +1,16 @@
1
1
  import { AudioSource } from '../../components';
2
2
  import { traverseEntity } from '../../../engine/entity';
3
- export const getAllTemplateSources = (templateCollection) => {
4
- const templateSources = [];
5
- templateCollection.getAll().forEach((template) => {
6
- traverseEntity(template, (entity) => {
3
+ export const getAllSources = (actors) => {
4
+ const sources = [];
5
+ actors.forEach((actor) => {
6
+ traverseEntity(actor, (entity) => {
7
7
  const audioSource = entity.getComponent(AudioSource);
8
8
  if (audioSource?.src) {
9
- templateSources.push(audioSource.src);
9
+ sources.push(audioSource.src);
10
10
  }
11
11
  });
12
12
  });
13
- return templateSources;
13
+ return sources;
14
14
  };
15
15
  export const loadAudio = async (url) => {
16
16
  const response = await fetch(url);
@@ -1,6 +1,6 @@
1
1
  import { buildBoxAABB } from './build-box-aabb';
2
2
  import { buildCircleAABB } from './build-circle-aabb';
3
3
  export const aabbBuilders = {
4
- boxCollider: buildBoxAABB,
5
- circleCollider: buildCircleAABB,
4
+ box: buildBoxAABB,
5
+ circle: buildCircleAABB,
6
6
  };
@@ -1,3 +1,3 @@
1
- import type { ColliderContainer, Transform } from '../../../../../components';
1
+ import type { Collider, Transform } from '../../../../../components';
2
2
  import type { BoxGeometry } from '../types';
3
- export declare const buildBoxGeometry: (container: ColliderContainer, transform: Transform) => BoxGeometry;
3
+ export declare const buildBoxGeometry: (collider: Collider, transform: Transform) => BoxGeometry;
@@ -1,8 +1,8 @@
1
1
  import { VectorOps } from '../../../../../../engine/math-lib';
2
- export const buildBoxGeometry = (container, transform) => {
2
+ export const buildBoxGeometry = (collider, transform) => {
3
3
  const { offsetX, offsetY, scaleX, scaleY, rotation, } = transform;
4
- let { centerX, centerY } = container.collider;
5
- const { sizeX, sizeY } = container.collider;
4
+ let { centerX, centerY } = collider;
5
+ const { sizeX, sizeY } = collider;
6
6
  const x1 = -(sizeX / 2);
7
7
  const x2 = (sizeX / 2);
8
8
  const y1 = -(sizeY / 2);
@@ -1,3 +1,3 @@
1
- import type { ColliderContainer, Transform } from '../../../../../components';
1
+ import type { Collider, Transform } from '../../../../../components';
2
2
  import type { CircleGeometry } from '../types';
3
- export declare const buildCircleGeometry: (container: ColliderContainer, transform: Transform) => CircleGeometry;
3
+ export declare const buildCircleGeometry: (collider: Collider, transform: Transform) => CircleGeometry;
@@ -1,6 +1,6 @@
1
- export const buildCircleGeometry = (container, transform) => {
1
+ export const buildCircleGeometry = (collider, transform) => {
2
2
  const { offsetX, offsetY, scaleX, scaleY, } = transform;
3
- const { centerX, centerY, radius } = container.collider;
3
+ const { centerX, centerY, radius } = collider;
4
4
  const center = {
5
5
  x: centerX + offsetX,
6
6
  y: centerY + offsetY,
@@ -1,4 +1,4 @@
1
- import type { ColliderContainer, Transform } from '../../../../../components';
1
+ import type { Collider, Transform } from '../../../../../components';
2
2
  import type { Geometry } from '../types';
3
- export type BuildGeometryFn = (container: ColliderContainer, transform: Transform) => Geometry;
3
+ export type BuildGeometryFn = (collider: Collider, transform: Transform) => Geometry;
4
4
  export declare const geometryBuilders: Record<string, BuildGeometryFn>;
@@ -1,6 +1,6 @@
1
1
  import { buildBoxGeometry } from './build-box-geometry';
2
2
  import { buildCircleGeometry } from './build-circle-geometry';
3
3
  export const geometryBuilders = {
4
- boxCollider: buildBoxGeometry,
5
- circleCollider: buildCircleGeometry,
4
+ box: buildBoxGeometry,
5
+ circle: buildCircleGeometry,
6
6
  };
@@ -1,5 +1,5 @@
1
1
  import { ActorCollection } from '../../../../../engine/actor';
2
- import { Transform, ColliderContainer, RigidBody, } from '../../../../components';
2
+ import { Transform, Collider, RigidBody, } from '../../../../components';
3
3
  import { AddActor, RemoveActor } from '../../../../../engine/events';
4
4
  import { Collision } from '../../../../events';
5
5
  import { insertionSort } from '../../../../../engine/data-lib';
@@ -18,7 +18,7 @@ export class CollisionDetectionSubsystem {
18
18
  constructor(options) {
19
19
  this.actorCollection = new ActorCollection(options.scene, {
20
20
  components: [
21
- ColliderContainer,
21
+ Collider,
22
22
  Transform,
23
23
  ],
24
24
  });
@@ -56,14 +56,14 @@ export class CollisionDetectionSubsystem {
56
56
  return true;
57
57
  }
58
58
  const transform = actor.getComponent(Transform);
59
- const colliderContainer = actor.getComponent(ColliderContainer);
59
+ const collider = actor.getComponent(Collider);
60
60
  const transformOld = entry.orientationData.transform;
61
61
  const colliderOld = entry.orientationData.collider;
62
- return checkTransform(transform, transformOld) || checkCollider(colliderContainer, colliderOld);
62
+ return checkTransform(transform, transformOld) || checkCollider(collider, colliderOld);
63
63
  }
64
64
  getOrientationData(actor) {
65
65
  const transform = actor.getComponent(Transform);
66
- const colliderContainer = actor.getComponent(ColliderContainer);
66
+ const collider = actor.getComponent(Collider);
67
67
  return {
68
68
  transform: {
69
69
  offsetX: transform.offsetX,
@@ -73,20 +73,20 @@ export class CollisionDetectionSubsystem {
73
73
  scaleY: transform.scaleY,
74
74
  },
75
75
  collider: {
76
- type: colliderContainer.type,
77
- centerX: colliderContainer.collider.centerX,
78
- centerY: colliderContainer.collider.centerY,
79
- sizeX: colliderContainer.collider.sizeX,
80
- sizeY: colliderContainer.collider.sizeY,
81
- radius: colliderContainer.collider.radius,
76
+ type: collider.type,
77
+ centerX: collider.centerX,
78
+ centerY: collider.centerY,
79
+ sizeX: collider.sizeX,
80
+ sizeY: collider.sizeY,
81
+ radius: collider.radius,
82
82
  },
83
83
  };
84
84
  }
85
85
  addCollisionEntry(actor) {
86
86
  const transform = actor.getComponent(Transform);
87
- const colliderContainer = actor.getComponent(ColliderContainer);
88
- const geometry = geometryBuilders[colliderContainer.type](colliderContainer, transform);
89
- const aabb = aabbBuilders[colliderContainer.type](geometry);
87
+ const collider = actor.getComponent(Collider);
88
+ const geometry = geometryBuilders[collider.type](collider, transform);
89
+ const aabb = aabbBuilders[collider.type](geometry);
90
90
  const entry = {
91
91
  actor,
92
92
  aabb,
@@ -101,9 +101,9 @@ export class CollisionDetectionSubsystem {
101
101
  }
102
102
  updateCollisionEntry(actor) {
103
103
  const transform = actor.getComponent(Transform);
104
- const colliderContainer = actor.getComponent(ColliderContainer);
105
- const geometry = geometryBuilders[colliderContainer.type](colliderContainer, transform);
106
- const aabb = aabbBuilders[colliderContainer.type](geometry);
104
+ const collider = actor.getComponent(Collider);
105
+ const geometry = geometryBuilders[collider.type](collider, transform);
106
+ const aabb = aabbBuilders[collider.type](geometry);
107
107
  const entry = this.entriesMap.get(actor.id);
108
108
  const prevAABB = entry.aabb;
109
109
  entry.aabb = aabb;
@@ -181,8 +181,8 @@ export class CollisionDetectionSubsystem {
181
181
  }
182
182
  checkOnIntersection(pair) {
183
183
  const [arg1, arg2] = pair;
184
- const type1 = arg1.actor.getComponent(ColliderContainer).type;
185
- const type2 = arg2.actor.getComponent(ColliderContainer).type;
184
+ const type1 = arg1.actor.getComponent(Collider).type;
185
+ const type2 = arg2.actor.getComponent(Collider).type;
186
186
  return intersectionCheckers[type1][type2](arg1, arg2);
187
187
  }
188
188
  sendCollisionEvent(actor1, actor2, intersection) {
@@ -1,4 +1,4 @@
1
- import { ColliderContainer } from '../../../../../components';
1
+ import { Collider } from '../../../../../components';
2
2
  import { MathOps, Vector2, VectorOps } from '../../../../../../engine/math-lib';
3
3
  const getMtvs = (axis, overlap, point1, point2) => {
4
4
  axis.multiplyNumber((1 / axis.magnitude) * overlap);
@@ -28,7 +28,7 @@ const getMtvs = (axis, overlap, point1, point2) => {
28
28
  export const checkBoxAndCircleIntersection = (arg1, arg2) => {
29
29
  let box;
30
30
  let circle;
31
- if (arg1.actor.getComponent(ColliderContainer).type === 'boxCollider') {
31
+ if (arg1.actor.getComponent(Collider).type === 'box') {
32
32
  box = arg1.geometry;
33
33
  circle = arg2.geometry;
34
34
  }
@@ -2,12 +2,12 @@ import { checkBoxAndCircleIntersection } from './check-box-and-circle-intersecti
2
2
  import { checkBoxesIntersection } from './check-boxes-intersection';
3
3
  import { checkCirclesIntersection } from './check-circles-intersection';
4
4
  export const intersectionCheckers = {
5
- boxCollider: {
6
- boxCollider: checkBoxesIntersection,
7
- circleCollider: checkBoxAndCircleIntersection,
5
+ box: {
6
+ box: checkBoxesIntersection,
7
+ circle: checkBoxAndCircleIntersection,
8
8
  },
9
- circleCollider: {
10
- circleCollider: checkCirclesIntersection,
11
- boxCollider: checkBoxAndCircleIntersection,
9
+ circle: {
10
+ circle: checkCirclesIntersection,
11
+ box: checkBoxAndCircleIntersection,
12
12
  },
13
13
  };
@@ -1,3 +1,3 @@
1
- import type { ColliderContainer } from '../../../../../components';
1
+ import type { Collider } from '../../../../../components';
2
2
  import type { OrientationData } from '../types';
3
- export declare const checkCollider: (colliderContainer: ColliderContainer, colliderOld: OrientationData['collider']) => boolean;
3
+ export declare const checkCollider: (collider: Collider, colliderOld: OrientationData['collider']) => boolean;
@@ -1,15 +1,13 @@
1
- export const checkCollider = (colliderContainer, colliderOld) => {
2
- if (colliderContainer.type !== colliderOld.type) {
1
+ export const checkCollider = (collider, colliderOld) => {
2
+ if (collider.type !== colliderOld.type) {
3
3
  return true;
4
4
  }
5
- if (colliderContainer.type === 'boxCollider') {
6
- const collider = colliderContainer.collider;
5
+ if (collider.type === 'box') {
7
6
  return collider.centerX !== colliderOld.centerX
8
7
  || collider.centerY !== colliderOld.centerY
9
8
  || collider.sizeX !== colliderOld.sizeX
10
9
  || collider.sizeY !== colliderOld.sizeY;
11
10
  }
12
- const collider = colliderContainer.collider;
13
11
  return collider.centerX !== colliderOld.centerX
14
12
  || collider.centerY !== colliderOld.centerY
15
13
  || collider.radius !== colliderOld.radius;
@@ -1,7 +1,7 @@
1
1
  import type { SceneSystemOptions } from '../../../../../engine/system';
2
2
  export declare class CollisionSolver {
3
3
  private scene;
4
- private gravitationalAcceleration;
4
+ private gravity;
5
5
  constructor(options: SceneSystemOptions);
6
6
  destroy(): void;
7
7
  private handleCollision;
@@ -6,11 +6,11 @@ const REACTION_FORCE_VECTOR_X = 0;
6
6
  const REACTION_FORCE_VECTOR_Y = -1;
7
7
  export class CollisionSolver {
8
8
  scene;
9
- gravitationalAcceleration;
9
+ gravity;
10
10
  constructor(options) {
11
- const { scene, gravitationalAcceleration } = options;
11
+ const { scene, gravity } = options;
12
12
  this.scene = scene;
13
- this.gravitationalAcceleration = gravitationalAcceleration;
13
+ this.gravity = gravity;
14
14
  this.scene.addEventListener(Collision, this.handleCollision);
15
15
  }
16
16
  destroy() {
@@ -40,7 +40,7 @@ export class CollisionSolver {
40
40
  const { useGravity, mass } = rigidBody;
41
41
  if (useGravity && mtv.y && Math.sign(mtv.y) === -1 && !mtv.x) {
42
42
  const reactionForce = new Vector2(REACTION_FORCE_VECTOR_X, REACTION_FORCE_VECTOR_Y);
43
- reactionForce.multiplyNumber(mass * this.gravitationalAcceleration);
43
+ reactionForce.multiplyNumber(mass * this.gravity);
44
44
  actor.dispatchEventImmediately(AddForce, {
45
45
  value: reactionForce,
46
46
  });
@@ -2,7 +2,7 @@ import type { SceneSystemOptions, UpdateOptions } from '../../../../../engine/sy
2
2
  export declare class PhysicsSubsystem {
3
3
  private scene;
4
4
  private actorCollection;
5
- private gravitationalAcceleration;
5
+ private gravity;
6
6
  private actorVectors;
7
7
  constructor(options: SceneSystemOptions);
8
8
  destroy(): void;
@@ -13,10 +13,10 @@ const DIRECTION_VECTOR = {
13
13
  export class PhysicsSubsystem {
14
14
  scene;
15
15
  actorCollection;
16
- gravitationalAcceleration;
16
+ gravity;
17
17
  actorVectors;
18
18
  constructor(options) {
19
- const { gravitationalAcceleration, scene, } = options;
19
+ const { gravity, scene, } = options;
20
20
  this.scene = scene;
21
21
  this.actorCollection = new ActorCollection(scene, {
22
22
  components: [
@@ -24,7 +24,7 @@ export class PhysicsSubsystem {
24
24
  Transform,
25
25
  ],
26
26
  });
27
- this.gravitationalAcceleration = gravitationalAcceleration;
27
+ this.gravity = gravity;
28
28
  this.actorVectors = {};
29
29
  this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
30
30
  this.scene.addEventListener(StopMovement, this.handleStopMovement);
@@ -77,7 +77,7 @@ export class PhysicsSubsystem {
77
77
  }
78
78
  const velocitySignX = Math.sign(velocity.x);
79
79
  const velocitySignY = Math.sign(velocity.y);
80
- const reactionForceValue = mass * this.gravitationalAcceleration;
80
+ const reactionForceValue = mass * this.gravity;
81
81
  const dragForceValue = -1 * drag * reactionForceValue;
82
82
  const forceToVelocityMultiplier = deltaTime / mass;
83
83
  const slowdownValue = dragForceValue * forceToVelocityMultiplier;
@@ -94,7 +94,7 @@ export class PhysicsSubsystem {
94
94
  const gravityVector = new Vector2(0, 0);
95
95
  if (useGravity) {
96
96
  gravityVector.add(DIRECTION_VECTOR.DOWN);
97
- gravityVector.multiplyNumber(mass * this.gravitationalAcceleration);
97
+ gravityVector.multiplyNumber(mass * this.gravity);
98
98
  }
99
99
  return gravityVector;
100
100
  }
@@ -1,4 +1,4 @@
1
1
  import type { SceneSystemOptions } from '../../../engine/system';
2
2
  export interface PhysicsSystemOptions extends SceneSystemOptions {
3
- gravitationalAcceleration: number;
3
+ gravity: number;
4
4
  }
@@ -2,8 +2,7 @@ import { WorldSystem } from '../../../engine/system';
2
2
  import type { WorldSystemOptions } from '../../../engine/system';
3
3
  import type { Scene } from '../../../engine/scene';
4
4
  export declare class SpriteRenderer extends WorldSystem {
5
- private scene?;
6
- private actorCollections;
5
+ private actorCollection?;
7
6
  private window;
8
7
  private renderScene;
9
8
  private currentCamera;
@@ -21,7 +20,7 @@ export declare class SpriteRenderer extends WorldSystem {
21
20
  constructor(options: WorldSystemOptions);
22
21
  onSceneLoad(scene: Scene): Promise<void>;
23
22
  onSceneEnter(scene: Scene): void;
24
- onSceneExit(scene: Scene): void;
23
+ onSceneExit(): void;
25
24
  onSceneDestroy(scene: Scene): void;
26
25
  onWorldDestroy(): void;
27
26
  private handleActorAdd;
@@ -14,10 +14,9 @@ import { composeSort, createSortByLayer, sortByYAxis, sortByXAxis, sortByZAxis,
14
14
  import { parseSortingLayers } from './sort/utils';
15
15
  import { LightSubsystem } from './light-subsystem';
16
16
  import { createMaterial, updateMaterial } from './material-factory';
17
- import { loadImage, prepareSprite, getAllTemplateSources, getTextureMapKey, cloneTexture, } from './utils';
17
+ import { loadImage, prepareSprite, getAllSources, getTextureMapKey, cloneTexture, } from './utils';
18
18
  export class SpriteRenderer extends WorldSystem {
19
- scene;
20
- actorCollections;
19
+ actorCollection;
21
20
  window;
22
21
  renderScene;
23
22
  currentCamera;
@@ -35,7 +34,6 @@ export class SpriteRenderer extends WorldSystem {
35
34
  constructor(options) {
36
35
  super();
37
36
  const { globalOptions, windowNodeId, backgroundColor, backgroundAlpha, templateCollection, world, } = options;
38
- this.actorCollections = {};
39
37
  this.templateCollection = templateCollection;
40
38
  this.window = getWindowNode(windowNodeId);
41
39
  this.sortFn = composeSort([
@@ -71,12 +69,9 @@ export class SpriteRenderer extends WorldSystem {
71
69
  this.window.appendChild(this.renderer.domElement);
72
70
  }
73
71
  async onSceneLoad(scene) {
74
- this.actorCollections[scene.id] = new ActorCollection(scene, {
75
- components: [Sprite, Transform],
76
- });
77
72
  const allSources = [
78
- ...getAllTemplateSources(this.templateCollection),
79
- ...this.actorCollections[scene.id].map((actor) => actor.getComponent(Sprite).src),
73
+ ...getAllSources(this.templateCollection.getAll()),
74
+ ...getAllSources(scene.children),
80
75
  ];
81
76
  const uniqueSources = [...new Set(allSources)];
82
77
  const images = await Promise.all(uniqueSources.map((src) => {
@@ -90,30 +85,31 @@ export class SpriteRenderer extends WorldSystem {
90
85
  allSources.forEach((src) => this.imageStore.retain(src));
91
86
  }
92
87
  onSceneEnter(scene) {
93
- this.scene = scene;
88
+ this.actorCollection = new ActorCollection(scene, {
89
+ components: [Sprite, Transform],
90
+ });
94
91
  this.handleWindowResize();
95
92
  this.lightSubsystem.onSceneEnter(scene);
96
- this.actorCollections[scene.id]?.addEventListener(AddActor, this.handleActorAdd);
97
- this.actorCollections[scene.id]?.addEventListener(RemoveActor, this.handleActorRemove);
93
+ this.actorCollection.addEventListener(AddActor, this.handleActorAdd);
94
+ this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
98
95
  }
99
- onSceneExit(scene) {
100
- this.actorCollections[scene.id]?.removeEventListener(AddActor, this.handleActorAdd);
101
- this.actorCollections[scene.id]?.removeEventListener(RemoveActor, this.handleActorRemove);
96
+ onSceneExit() {
97
+ this.actorCollection?.removeEventListener(AddActor, this.handleActorAdd);
98
+ this.actorCollection?.removeEventListener(RemoveActor, this.handleActorRemove);
102
99
  this.lightSubsystem.onSceneExit();
103
100
  this.actorsMap.clear();
104
101
  this.spriteCache.clear();
105
102
  this.textureMap.clear();
106
103
  this.renderScene.clear();
107
- this.scene = undefined;
104
+ this.actorCollection = undefined;
108
105
  }
109
106
  onSceneDestroy(scene) {
110
107
  const allSources = [
111
- ...getAllTemplateSources(this.templateCollection),
112
- ...this.actorCollections[scene.id].map((actor) => actor.getComponent(Sprite).src),
108
+ ...getAllSources(this.templateCollection.getAll()),
109
+ ...getAllSources(scene.children),
113
110
  ];
114
111
  allSources.forEach((src) => this.imageStore.release(src));
115
112
  this.imageStore.cleanReleased();
116
- delete this.actorCollections[scene.id];
117
113
  }
118
114
  onWorldDestroy() {
119
115
  window.removeEventListener('resize', this.handleWindowResize);
@@ -218,7 +214,7 @@ export class SpriteRenderer extends WorldSystem {
218
214
  this.currentCamera.updateProjectionMatrix();
219
215
  }
220
216
  updateActors() {
221
- this.actorCollections[this.scene.id].forEach((actor, index) => {
217
+ this.actorCollection?.forEach((actor, index) => {
222
218
  const transform = actor.getComponent(Transform);
223
219
  const sprite = actor.getComponent(Sprite);
224
220
  if (!this.actorsMap.has(actor.id)) {
@@ -245,10 +241,8 @@ export class SpriteRenderer extends WorldSystem {
245
241
  update() {
246
242
  this.updateCamera();
247
243
  this.lightSubsystem.update();
248
- if (this.scene) {
249
- this.actorCollections[this.scene.id].sort(this.sortFn);
250
- this.updateActors();
251
- }
244
+ this.actorCollection?.sort(this.sortFn);
245
+ this.updateActors();
252
246
  this.renderer.render(this.renderScene, this.currentCamera);
253
247
  }
254
248
  }
@@ -1,8 +1,9 @@
1
1
  import { Texture } from 'three/src/Three';
2
2
  import { Sprite } from '../../components/sprite';
3
- import type { TemplateCollection } from '../../../engine/template';
3
+ import type { Actor } from '../../../engine/actor';
4
+ import type { Template } from '../../../engine/template';
4
5
  export declare const loadImage: (spriteSourcePath: string) => Promise<HTMLImageElement>;
5
6
  export declare const prepareSprite: (image: HTMLImageElement, sprite: Sprite) => Texture[];
6
- export declare const getAllTemplateSources: (templateCollection: TemplateCollection) => string[];
7
+ export declare const getAllSources: (actors: (Actor | Template)[]) => string[];
7
8
  export declare const getTextureMapKey: ({ slice, fit, width, height, src, }: Sprite) => string;
8
9
  export declare const cloneTexture: (sprite: Sprite, texture: Texture) => Texture;
@@ -15,17 +15,17 @@ export const prepareSprite = (image, sprite) => {
15
15
  });
16
16
  return textures;
17
17
  };
18
- export const getAllTemplateSources = (templateCollection) => {
19
- const templateSources = [];
20
- templateCollection.getAll().forEach((template) => {
21
- traverseEntity(template, (entity) => {
22
- const audioSource = entity.getComponent(Sprite);
23
- if (audioSource?.src) {
24
- templateSources.push(audioSource.src);
18
+ export const getAllSources = (actors) => {
19
+ const sources = [];
20
+ actors.forEach((actor) => {
21
+ traverseEntity(actor, (entity) => {
22
+ const sprite = entity.getComponent(Sprite);
23
+ if (sprite?.src) {
24
+ sources.push(sprite.src);
25
25
  }
26
26
  });
27
27
  });
28
- return templateSources;
28
+ return sources;
29
29
  };
30
30
  export const getTextureMapKey = ({ slice, fit, width = 0, height = 0, src, }) => `${slice}_${fit}_${width}_${height}_${src}`;
31
31
  export const cloneTexture = (sprite, texture) => {
@@ -23,8 +23,8 @@ export declare class SceneManager {
23
23
  private actorCreator;
24
24
  private actorSpawner;
25
25
  private world;
26
+ private worldSystems;
26
27
  private loadedScenes;
27
- private systems;
28
28
  private activeSceneId?;
29
29
  constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, }: SceneManagerOptions);
30
30
  loadWorld(): Promise<void>;
@@ -3,6 +3,7 @@ import { ActorCreator, ActorSpawner } from '../actor';
3
3
  import { SceneSystem, WorldSystem } from '../system';
4
4
  import { World } from '../world';
5
5
  import { LoadScene, EnterScene, ExitScene, DestroyScene, SceneLoaded, SceneEntered, SceneExited, SceneDestroyed, } from '../events';
6
+ import { isSubclassOf } from '../utils/is-subclass-of';
6
7
  import { Scene } from './scene';
7
8
  export class SceneManager {
8
9
  sceneConfigs;
@@ -14,8 +15,8 @@ export class SceneManager {
14
15
  actorCreator;
15
16
  actorSpawner;
16
17
  world;
18
+ worldSystems;
17
19
  loadedScenes;
18
- systems;
19
20
  activeSceneId;
20
21
  constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, }) {
21
22
  this.availableSystems = availableSystems.reduce((acc, AvailableSystem) => {
@@ -33,12 +34,12 @@ export class SceneManager {
33
34
  this.actorCreator = new ActorCreator(components, templateCollection);
34
35
  this.actorSpawner = new ActorSpawner(this.actorCreator);
35
36
  this.world = new World({ id: uuid(), name: 'world' });
37
+ this.worldSystems = new Map();
36
38
  this.loadedScenes = new Map();
37
- this.systems = new Map();
38
39
  this.activeSceneId = undefined;
39
40
  this.systemConfigs.forEach((config) => {
40
41
  const SystemClass = this.availableSystems[config.name];
41
- if (Object.getPrototypeOf(SystemClass) === WorldSystem) {
42
+ if (isSubclassOf(SystemClass, WorldSystem)) {
42
43
  const options = {
43
44
  ...config.options,
44
45
  templateCollection: this.templateCollection,
@@ -47,10 +48,7 @@ export class SceneManager {
47
48
  globalOptions: this.globalOptions,
48
49
  world: this.world,
49
50
  };
50
- this.systems.set(config.name, new SystemClass(options));
51
- }
52
- if (Object.getPrototypeOf(SystemClass) === SceneSystem) {
53
- this.systems.set(config.name, new Map());
51
+ this.worldSystems.set(config.name, new SystemClass(options));
54
52
  }
55
53
  });
56
54
  this.world.addEventListener(LoadScene, this.handleLoadScene);
@@ -65,15 +63,14 @@ export class SceneManager {
65
63
  }
66
64
  destroyWorld() {
67
65
  this.exitActiveScene();
68
- this.loadedScenes.forEach((scene) => {
69
- this.destroyScene(scene.id);
66
+ this.loadedScenes.forEach((entry) => {
67
+ this.destroyScene(entry.scene.id);
70
68
  });
71
69
  this.getSystems().forEach((system) => {
72
70
  if (system instanceof WorldSystem) {
73
71
  system.onWorldDestroy?.(this.world);
74
72
  }
75
73
  });
76
- this.systems.clear();
77
74
  this.world.removeEventListener(LoadScene, this.handleLoadScene);
78
75
  this.world.removeEventListener(EnterScene, this.handleEnterScene);
79
76
  this.world.removeEventListener(ExitScene, this.handleExitScene);
@@ -98,17 +95,15 @@ export class SceneManager {
98
95
  if (!this.activeSceneId) {
99
96
  return undefined;
100
97
  }
101
- return this.world.findChildById(this.activeSceneId, false);
98
+ return this.loadedScenes.get(this.activeSceneId)?.scene;
102
99
  }
103
100
  getSystems(scene) {
104
101
  scene ??= this.getActiveScene();
102
+ const sceneSystems = scene ? this.loadedScenes.get(scene.id)?.systems : undefined;
105
103
  return this.systemConfigs.reduce((acc, config) => {
106
- const entry = this.systems.get(config.name);
107
- if (entry instanceof WorldSystem) {
108
- acc.push(entry);
109
- }
110
- if (entry instanceof Map && scene && entry.has(scene.id)) {
111
- acc.push(entry.get(scene.id));
104
+ const system = this.worldSystems.get(config.name) ?? sceneSystems?.get(config.name);
105
+ if (system) {
106
+ acc.push(system);
112
107
  }
113
108
  return acc;
114
109
  }, []);
@@ -117,14 +112,23 @@ export class SceneManager {
117
112
  if (!this.sceneConfigs[id]) {
118
113
  throw new Error(`Error while loading scene. Not found scene with id: ${id}`);
119
114
  }
115
+ if (this.loadedScenes.get(id)?.isLoading) {
116
+ return;
117
+ }
118
+ if (this.loadedScenes.has(id) && !this.loadedScenes.get(id)?.isLoading) {
119
+ if (id === this.activeSceneId) {
120
+ this.exitActiveScene();
121
+ }
122
+ this.destroyScene(id);
123
+ }
120
124
  const scene = new Scene({
121
125
  ...this.sceneConfigs[id],
122
126
  actorCreator: this.actorCreator,
123
127
  templateCollection: this.templateCollection,
124
128
  });
125
- this.systemConfigs.forEach((config) => {
129
+ const sceneSystems = this.systemConfigs.reduce((acc, config) => {
126
130
  const SystemClass = this.availableSystems[config.name];
127
- if (Object.getPrototypeOf(SystemClass) === SceneSystem) {
131
+ if (isSubclassOf(SystemClass, SceneSystem)) {
128
132
  const options = {
129
133
  ...config.options,
130
134
  templateCollection: this.templateCollection,
@@ -134,23 +138,32 @@ export class SceneManager {
134
138
  scene,
135
139
  world: this.world,
136
140
  };
137
- const sceneSystems = this.systems.get(config.name);
138
- sceneSystems.set(scene.id, new SystemClass(options));
141
+ acc.set(config.name, new SystemClass(options));
139
142
  }
140
- });
143
+ return acc;
144
+ }, new Map());
145
+ const loadEntry = { scene, systems: sceneSystems, isLoading: true };
146
+ this.loadedScenes.set(scene.id, loadEntry);
141
147
  await Promise.all(this.getSystems(scene).map((system) => system.onSceneLoad?.(scene)));
142
- this.loadedScenes.set(scene.id, scene);
148
+ loadEntry.isLoading = false;
143
149
  this.world.dispatchEvent(SceneLoaded, { scene });
144
150
  if (autoEnter) {
145
151
  this.enterScene(id, autoDestroy);
146
152
  }
147
153
  }
148
154
  enterScene(id, autoDestroy) {
149
- const scene = this.loadedScenes.get(id);
150
- if (!scene) {
155
+ const entry = this.loadedScenes.get(id);
156
+ if (!entry) {
151
157
  throw new Error(`Error while entering scene. Not found scene with same id: ${id}`);
152
158
  }
159
+ if (entry.isLoading) {
160
+ throw new Error(`Error while entering scene. Scene with id: ${id} is still loading`);
161
+ }
162
+ if (id === this.activeSceneId) {
163
+ return;
164
+ }
153
165
  this.exitActiveScene(autoDestroy);
166
+ const { scene } = entry;
154
167
  this.world.appendChild(scene);
155
168
  this.getSystems(scene).forEach((system) => system.onSceneEnter?.(scene));
156
169
  this.activeSceneId = id;
@@ -170,20 +183,15 @@ export class SceneManager {
170
183
  }
171
184
  }
172
185
  destroyScene(id) {
173
- const scene = this.loadedScenes.get(id);
174
- if (!scene) {
186
+ const entry = this.loadedScenes.get(id);
187
+ if (!entry) {
175
188
  return;
176
189
  }
190
+ const { scene } = entry;
177
191
  if (scene.id === this.activeSceneId) {
178
192
  throw new Error('Error while destroying scene. Cannot destroy active scene. You should exit first.');
179
193
  }
180
194
  this.getSystems(scene).forEach((system) => system.onSceneDestroy?.(scene));
181
- this.systemConfigs.forEach((config) => {
182
- const entry = this.systems.get(config.name);
183
- if (entry instanceof Map && entry.has(scene.id)) {
184
- entry.delete(scene.id);
185
- }
186
- });
187
195
  this.loadedScenes.delete(id);
188
196
  this.world.dispatchEvent(SceneDestroyed, { scene });
189
197
  }
@@ -0,0 +1,2 @@
1
+ import type { SceneConfig } from '../../../types';
2
+ export declare const getSceneConfigMock: (id: string) => SceneConfig;
@@ -0,0 +1,5 @@
1
+ export const getSceneConfigMock = (id) => ({
2
+ id,
3
+ name: id,
4
+ actors: [],
5
+ });
@@ -0,0 +1,2 @@
1
+ import type { SystemConfig } from '../../../types';
2
+ export declare const getSystemConfigMock: (name: string) => SystemConfig;
@@ -0,0 +1,4 @@
1
+ export const getSystemConfigMock = (name) => ({
2
+ name,
3
+ options: {},
4
+ });
@@ -0,0 +1,22 @@
1
+ import { Scene } from '../..';
2
+ import { World } from '../../../world';
3
+ import { WorldSystem, SceneSystem, WorldSystemOptions, SceneSystemOptions } from '../../../system';
4
+ export declare class SceneSystemMock extends SceneSystem {
5
+ private fns?;
6
+ constructor(options: SceneSystemOptions);
7
+ onSceneLoad(scene: Scene): Promise<void>;
8
+ onSceneEnter(scene: Scene): void;
9
+ onSceneExit(scene: Scene): void;
10
+ onSceneDestroy(scene: Scene): void;
11
+ }
12
+ export declare class WorldSystemMock extends WorldSystem {
13
+ private fns?;
14
+ constructor(options: WorldSystemOptions);
15
+ onWorldLoad(world: World): Promise<void>;
16
+ onWorldReady(world: World): void;
17
+ onWorldDestroy(world: World): void;
18
+ onSceneLoad(scene: Scene): Promise<void>;
19
+ onSceneEnter(scene: Scene): void;
20
+ onSceneExit(scene: Scene): void;
21
+ onSceneDestroy(scene: Scene): void;
22
+ }
@@ -0,0 +1,48 @@
1
+ import { WorldSystem, SceneSystem, } from '../../../system';
2
+ export class SceneSystemMock extends SceneSystem {
3
+ fns;
4
+ constructor(options) {
5
+ super();
6
+ this.fns = options.resources;
7
+ }
8
+ async onSceneLoad(scene) {
9
+ await this.fns?.loadSceneFn(scene);
10
+ }
11
+ onSceneEnter(scene) {
12
+ this.fns?.enterSceneFn(scene);
13
+ }
14
+ onSceneExit(scene) {
15
+ this.fns?.exitSceneFn(scene);
16
+ }
17
+ onSceneDestroy(scene) {
18
+ this.fns?.destroySceneFn(scene);
19
+ }
20
+ }
21
+ export class WorldSystemMock extends WorldSystem {
22
+ fns;
23
+ constructor(options) {
24
+ super();
25
+ this.fns = options.resources;
26
+ }
27
+ async onWorldLoad(world) {
28
+ await this.fns?.loadWorldFn(world);
29
+ }
30
+ onWorldReady(world) {
31
+ this.fns?.readyWorldFn(world);
32
+ }
33
+ onWorldDestroy(world) {
34
+ this.fns?.destroyWorldFn(world);
35
+ }
36
+ async onSceneLoad(scene) {
37
+ await this.fns?.loadSceneFn(scene);
38
+ }
39
+ onSceneEnter(scene) {
40
+ this.fns?.enterSceneFn(scene);
41
+ }
42
+ onSceneExit(scene) {
43
+ this.fns?.exitSceneFn(scene);
44
+ }
45
+ onSceneDestroy(scene) {
46
+ this.fns?.destroySceneFn(scene);
47
+ }
48
+ }
@@ -1,2 +1,2 @@
1
1
  export { SceneSystem, WorldSystem } from './system';
2
- export type { SystemConstructor, SceneSystemOptions, WorldSystemOptions, UpdateOptions, } from './system';
2
+ export type { System, SystemConstructor, SceneSystemOptions, WorldSystemOptions, UpdateOptions, } from './system';
@@ -0,0 +1 @@
1
+ export declare const isSubclassOf: (subclass: unknown, superclass: unknown) => boolean;
@@ -0,0 +1,10 @@
1
+ export const isSubclassOf = (subclass, superclass) => {
2
+ let proto = Object.getPrototypeOf(subclass);
3
+ while (proto) {
4
+ if (proto === superclass) {
5
+ return true;
6
+ }
7
+ proto = Object.getPrototypeOf(proto);
8
+ }
9
+ return false;
10
+ };
package/build/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { VectorOps, MathOps, Vector2 } from './engine/math-lib';
4
4
  export * from './engine/consts';
5
5
  export * from './engine/types';
6
6
  export { WorldSystem, SceneSystem } from './engine/system';
7
- export type { WorldSystemOptions, SceneSystemOptions, UpdateOptions, } from './engine/system';
7
+ export type { System, WorldSystemOptions, SceneSystemOptions, UpdateOptions, } from './engine/system';
8
8
  export type { ActorCollectionFilter, ActorSpawner, } from './engine/actor';
9
9
  export type { EventTarget, Event, EventType, EventPayload, ListenerFn, } from './engine/event-target';
10
10
  export type { Scene } from './engine/scene';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacha",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "exports": {
@@ -1,7 +0,0 @@
1
- export declare class BoxCollider {
2
- sizeX: number;
3
- sizeY: number;
4
- centerX: number;
5
- centerY: number;
6
- constructor(config: Record<string, number>);
7
- }
@@ -1,12 +0,0 @@
1
- export class BoxCollider {
2
- sizeX;
3
- sizeY;
4
- centerX;
5
- centerY;
6
- constructor(config) {
7
- this.sizeX = config.sizeX;
8
- this.sizeY = config.sizeY;
9
- this.centerX = config.centerX;
10
- this.centerY = config.centerY;
11
- }
12
- }
@@ -1,6 +0,0 @@
1
- export declare class CircleCollider {
2
- radius: number;
3
- centerX: number;
4
- centerY: number;
5
- constructor(config: Record<string, number>);
6
- }
@@ -1,10 +0,0 @@
1
- export class CircleCollider {
2
- radius;
3
- centerX;
4
- centerY;
5
- constructor(config) {
6
- this.radius = config.radius;
7
- this.centerX = config.centerX;
8
- this.centerY = config.centerY;
9
- }
10
- }
@@ -1,13 +0,0 @@
1
- import { Component } from '../../../engine/component';
2
- import { BoxCollider } from './box-collider';
3
- import { CircleCollider } from './circle-collider';
4
- export interface ColliderContainerConfig {
5
- type: 'boxCollider' | 'circleCollider';
6
- collider: Record<string, number>;
7
- }
8
- export declare class ColliderContainer extends Component {
9
- type: 'boxCollider' | 'circleCollider';
10
- collider: BoxCollider | CircleCollider;
11
- constructor(config: ColliderContainerConfig);
12
- clone(): ColliderContainer;
13
- }
@@ -1,28 +0,0 @@
1
- import { Component } from '../../../engine/component';
2
- import { BoxCollider } from './box-collider';
3
- import { CircleCollider } from './circle-collider';
4
- const COLLIDER_MAP = {
5
- boxCollider: BoxCollider,
6
- circleCollider: CircleCollider,
7
- };
8
- export class ColliderContainer extends Component {
9
- type;
10
- collider;
11
- constructor(config) {
12
- super();
13
- const colliderContainerConfig = config;
14
- this.type = colliderContainerConfig.type;
15
- if (!COLLIDER_MAP[this.type]) {
16
- throw new Error(`Not found collider with same type: ${this.type}`);
17
- }
18
- const Collider = COLLIDER_MAP[this.type];
19
- this.collider = new Collider(colliderContainerConfig.collider);
20
- }
21
- clone() {
22
- return new ColliderContainer({
23
- type: this.type,
24
- collider: this.collider,
25
- });
26
- }
27
- }
28
- ColliderContainer.componentName = 'ColliderContainer';