dacha 0.15.2 → 0.16.0

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 (169) hide show
  1. package/build/contrib/components/animatable/comparator-condition-component-value.d.ts +1 -1
  2. package/build/contrib/components/animatable/group-state.d.ts +1 -1
  3. package/build/contrib/components/animatable/index.d.ts +1 -1
  4. package/build/contrib/components/animatable/one-dimensional-props.d.ts +1 -1
  5. package/build/contrib/components/animatable/one-dimensional-props.js +1 -3
  6. package/build/contrib/components/animatable/state.d.ts +1 -1
  7. package/build/contrib/components/animatable/timeline.d.ts +2 -2
  8. package/build/contrib/components/animatable/transition.d.ts +1 -1
  9. package/build/contrib/components/animatable/two-dimensional-props.d.ts +1 -1
  10. package/build/contrib/components/animatable/two-dimensional-props.js +1 -3
  11. package/build/contrib/components/animatable/types.d.ts +9 -9
  12. package/build/contrib/components/bitmap-text/index.d.ts +36 -0
  13. package/build/contrib/components/bitmap-text/index.js +42 -0
  14. package/build/contrib/components/index.d.ts +3 -2
  15. package/build/contrib/components/index.js +3 -1
  16. package/build/contrib/components/keyboard-control/index.d.ts +6 -8
  17. package/build/contrib/components/keyboard-control/index.js +8 -2
  18. package/build/contrib/components/mouse-control/index.d.ts +3 -7
  19. package/build/contrib/components/mouse-control/index.js +4 -1
  20. package/build/contrib/components/pixi-view/index.d.ts +20 -0
  21. package/build/contrib/components/pixi-view/index.js +24 -0
  22. package/build/contrib/components/shape/index.d.ts +64 -0
  23. package/build/contrib/components/shape/index.js +60 -0
  24. package/build/contrib/components/sprite/index.d.ts +17 -6
  25. package/build/contrib/components/sprite/index.js +10 -4
  26. package/build/contrib/systems/animator/index.d.ts +1 -1
  27. package/build/contrib/systems/animator/index.js +9 -9
  28. package/build/contrib/systems/animator/substate-pickers/index.d.ts +2 -3
  29. package/build/contrib/systems/animator/substate-pickers/one-dimensional-picker.d.ts +1 -1
  30. package/build/contrib/systems/animator/substate-pickers/picker.d.ts +1 -1
  31. package/build/contrib/systems/animator/substate-pickers/two-dimensional-picker.d.ts +1 -1
  32. package/build/contrib/systems/animator/utils.d.ts +2 -2
  33. package/build/contrib/systems/animator/utils.js +0 -1
  34. package/build/contrib/systems/audio-system/index.d.ts +1 -1
  35. package/build/contrib/systems/audio-system/index.js +20 -18
  36. package/build/contrib/systems/audio-system/types.d.ts +6 -6
  37. package/build/contrib/systems/behavior-system/system.d.ts +2 -0
  38. package/build/contrib/systems/behavior-system/system.js +18 -5
  39. package/build/contrib/systems/camera-system/system.d.ts +1 -1
  40. package/build/contrib/systems/camera-system/system.js +16 -10
  41. package/build/contrib/systems/game-stats-meter/index.d.ts +1 -1
  42. package/build/contrib/systems/game-stats-meter/index.js +6 -6
  43. package/build/contrib/systems/index.d.ts +2 -2
  44. package/build/contrib/systems/index.js +1 -1
  45. package/build/contrib/systems/keyboard-control-system/index.d.ts +1 -1
  46. package/build/contrib/systems/keyboard-control-system/index.js +5 -7
  47. package/build/contrib/systems/keyboard-input-system/input-listener.d.ts +1 -1
  48. package/build/contrib/systems/mouse-control-system/index.d.ts +1 -1
  49. package/build/contrib/systems/mouse-control-system/index.js +5 -7
  50. package/build/contrib/systems/mouse-input-system/subsystems/input-subsystem/mouse-input-listener.d.ts +1 -1
  51. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +1 -1
  52. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +17 -16
  53. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +9 -9
  54. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.js +3 -0
  55. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +0 -1
  56. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +46 -59
  57. package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +1 -1
  58. package/build/contrib/systems/physics-system/subsystems/physics/index.js +10 -14
  59. package/build/contrib/systems/renderer/builders/bitmap-text-builder/index.d.ts +8 -0
  60. package/build/contrib/systems/renderer/builders/bitmap-text-builder/index.js +115 -0
  61. package/build/contrib/systems/renderer/builders/bitmap-text-builder/utils.d.ts +2 -0
  62. package/build/contrib/systems/renderer/builders/bitmap-text-builder/utils.js +7 -0
  63. package/build/contrib/systems/renderer/builders/builder.d.ts +7 -0
  64. package/build/contrib/systems/renderer/builders/index.d.ts +5 -0
  65. package/build/contrib/systems/renderer/builders/index.js +4 -0
  66. package/build/contrib/systems/renderer/builders/pixi-view-builder/index.d.ts +8 -0
  67. package/build/contrib/systems/renderer/builders/pixi-view-builder/index.js +31 -0
  68. package/build/contrib/systems/renderer/builders/shape-builder/index.d.ts +12 -0
  69. package/build/contrib/systems/renderer/builders/shape-builder/index.js +128 -0
  70. package/build/contrib/systems/renderer/builders/shape-builder/utils.d.ts +4 -0
  71. package/build/contrib/systems/renderer/builders/shape-builder/utils.js +85 -0
  72. package/build/contrib/systems/renderer/builders/sprite-builder/index.d.ts +19 -0
  73. package/build/contrib/systems/renderer/builders/sprite-builder/index.js +166 -0
  74. package/build/contrib/systems/renderer/builders/sprite-builder/utils.d.ts +4 -0
  75. package/build/contrib/systems/renderer/builders/sprite-builder/utils.js +16 -0
  76. package/build/contrib/systems/renderer/builders/utils.d.ts +1 -0
  77. package/build/contrib/systems/renderer/builders/utils.js +4 -0
  78. package/build/contrib/systems/renderer/consts.d.ts +5 -0
  79. package/build/contrib/systems/renderer/consts.js +12 -0
  80. package/build/contrib/systems/renderer/index.d.ts +2 -0
  81. package/build/contrib/systems/renderer/index.js +2 -0
  82. package/build/contrib/systems/renderer/renderer.d.ts +31 -0
  83. package/build/contrib/systems/renderer/renderer.js +249 -0
  84. package/build/contrib/systems/renderer/service/index.d.ts +20 -0
  85. package/build/contrib/systems/renderer/service/index.js +70 -0
  86. package/build/contrib/systems/{sprite-renderer → renderer}/sort/index.d.ts +1 -3
  87. package/build/contrib/systems/{sprite-renderer → renderer}/sort/index.js +2 -4
  88. package/build/contrib/systems/renderer/sort/sort-by-layer.d.ts +2 -0
  89. package/build/contrib/systems/renderer/sort/sort-by-layer.js +13 -0
  90. package/build/contrib/systems/renderer/sort/sort-by-x-axis.d.ts +2 -0
  91. package/build/contrib/systems/renderer/sort/sort-by-x-axis.js +9 -0
  92. package/build/contrib/systems/renderer/sort/sort-by-y-axis.d.ts +2 -0
  93. package/build/contrib/systems/renderer/sort/sort-by-y-axis.js +9 -0
  94. package/build/contrib/systems/renderer/sort/types.d.ts +2 -0
  95. package/build/contrib/systems/{sprite-renderer → renderer}/sort/utils.d.ts +1 -1
  96. package/build/contrib/systems/renderer/types.d.ts +26 -0
  97. package/build/contrib/systems/renderer/types.js +1 -0
  98. package/build/contrib/systems/renderer/utils.d.ts +5 -0
  99. package/build/contrib/systems/renderer/utils.js +42 -0
  100. package/build/contrib/types/input-events.d.ts +1 -1
  101. package/build/contrib/types/view.d.ts +1 -0
  102. package/build/contrib/types/view.js +1 -0
  103. package/build/engine/actor/actor-collection.d.ts +4 -1
  104. package/build/engine/actor/actor-collection.js +4 -1
  105. package/build/engine/actor/actor-creator.d.ts +3 -3
  106. package/build/engine/actor/actor-query.d.ts +29 -0
  107. package/build/engine/actor/actor-query.js +85 -0
  108. package/build/engine/actor/actor.d.ts +3 -4
  109. package/build/engine/actor/index.d.ts +2 -0
  110. package/build/engine/actor/index.js +1 -0
  111. package/build/engine/component/component.d.ts +2 -2
  112. package/build/engine/data-lib/cache-store.d.ts +2 -1
  113. package/build/engine/data-lib/cache-store.js +7 -1
  114. package/build/engine/engine.d.ts +28 -6
  115. package/build/engine/engine.js +35 -27
  116. package/build/engine/entity/entity.d.ts +1 -1
  117. package/build/engine/event-target/event-target.d.ts +1 -1
  118. package/build/engine/math-lib/vector/ops.d.ts +4 -4
  119. package/build/engine/math-lib/vector/ops.js +2 -3
  120. package/build/engine/resource-loader/loaders/image-loader.d.ts +1 -1
  121. package/build/engine/resource-loader/loaders/index.d.ts +2 -3
  122. package/build/engine/resource-loader/loaders/json-loader.d.ts +1 -1
  123. package/build/engine/resource-loader/loaders/loader.d.ts +1 -1
  124. package/build/engine/scene/scene-manager.js +7 -1
  125. package/build/engine/template/template-collection.d.ts +2 -2
  126. package/build/engine/template/template.d.ts +2 -2
  127. package/build/index.d.ts +2 -2
  128. package/build/index.js +1 -1
  129. package/build/types/global.d.ts +20 -0
  130. package/package.json +13 -10
  131. package/build/contrib/components/light/index.d.ts +0 -20
  132. package/build/contrib/components/light/index.js +0 -18
  133. package/build/contrib/components/renderable/index.d.ts +0 -44
  134. package/build/contrib/components/renderable/index.js +0 -65
  135. package/build/contrib/components/renderable/material.d.ts +0 -16
  136. package/build/contrib/components/renderable/material.js +0 -8
  137. package/build/contrib/components/sprite/material.d.ts +0 -16
  138. package/build/contrib/components/sprite/material.js +0 -8
  139. package/build/contrib/systems/sprite-renderer/index.d.ts +0 -2
  140. package/build/contrib/systems/sprite-renderer/index.js +0 -2
  141. package/build/contrib/systems/sprite-renderer/light-subsystem/index.d.ts +0 -13
  142. package/build/contrib/systems/sprite-renderer/light-subsystem/index.js +0 -62
  143. package/build/contrib/systems/sprite-renderer/light-subsystem/light-factory.d.ts +0 -4
  144. package/build/contrib/systems/sprite-renderer/light-subsystem/light-factory.js +0 -27
  145. package/build/contrib/systems/sprite-renderer/material-factory/index.d.ts +0 -4
  146. package/build/contrib/systems/sprite-renderer/material-factory/index.js +0 -32
  147. package/build/contrib/systems/sprite-renderer/renderer.d.ts +0 -36
  148. package/build/contrib/systems/sprite-renderer/renderer.js +0 -249
  149. package/build/contrib/systems/sprite-renderer/service/index.d.ts +0 -24
  150. package/build/contrib/systems/sprite-renderer/service/index.js +0 -52
  151. package/build/contrib/systems/sprite-renderer/sort/sort-by-fit.d.ts +0 -2
  152. package/build/contrib/systems/sprite-renderer/sort/sort-by-fit.js +0 -12
  153. package/build/contrib/systems/sprite-renderer/sort/sort-by-layer.d.ts +0 -2
  154. package/build/contrib/systems/sprite-renderer/sort/sort-by-layer.js +0 -14
  155. package/build/contrib/systems/sprite-renderer/sort/sort-by-x-axis.d.ts +0 -2
  156. package/build/contrib/systems/sprite-renderer/sort/sort-by-x-axis.js +0 -15
  157. package/build/contrib/systems/sprite-renderer/sort/sort-by-y-axis.d.ts +0 -2
  158. package/build/contrib/systems/sprite-renderer/sort/sort-by-y-axis.js +0 -15
  159. package/build/contrib/systems/sprite-renderer/sort/sort-by-z-axis.d.ts +0 -2
  160. package/build/contrib/systems/sprite-renderer/sort/sort-by-z-axis.js +0 -6
  161. package/build/contrib/systems/sprite-renderer/sort/types.d.ts +0 -2
  162. package/build/contrib/systems/sprite-renderer/sprite-cropper.d.ts +0 -8
  163. package/build/contrib/systems/sprite-renderer/sprite-cropper.js +0 -30
  164. package/build/contrib/systems/sprite-renderer/types.d.ts +0 -7
  165. package/build/contrib/systems/sprite-renderer/utils.d.ts +0 -9
  166. package/build/contrib/systems/sprite-renderer/utils.js +0 -47
  167. /package/build/contrib/systems/{sprite-renderer/sort/types.js → renderer/builders/builder.js} +0 -0
  168. /package/build/contrib/systems/{sprite-renderer → renderer/sort}/types.js +0 -0
  169. /package/build/contrib/systems/{sprite-renderer → renderer}/sort/utils.js +0 -0
@@ -0,0 +1,9 @@
1
+ export const sortByXAxis = (direction = 1) => (a, b) => {
2
+ const aComponent = a.__dacha.viewComponent;
3
+ const bComponent = b.__dacha.viewComponent;
4
+ const aX = a.__dacha.bounds.maxX;
5
+ const bX = b.__dacha.bounds.maxX;
6
+ const aOffsetX = aX + aComponent.sortCenter[0];
7
+ const bOffsetX = bX + bComponent.sortCenter[0];
8
+ return (aOffsetX - bOffsetX) * direction;
9
+ };
@@ -0,0 +1,2 @@
1
+ import type { SortFn } from './types';
2
+ export declare const sortByYAxis: (direction?: number) => SortFn;
@@ -0,0 +1,9 @@
1
+ export const sortByYAxis = (direction = 1) => (a, b) => {
2
+ const aComponent = a.__dacha.viewComponent;
3
+ const bComponent = b.__dacha.viewComponent;
4
+ const aY = a.__dacha.bounds.maxY;
5
+ const bY = b.__dacha.bounds.maxY;
6
+ const aOffsetY = aY + aComponent.sortCenter[1];
7
+ const bOffsetY = bY + bComponent.sortCenter[1];
8
+ return (aOffsetY - bOffsetY) * direction;
9
+ };
@@ -0,0 +1,2 @@
1
+ import { type ViewContainer } from 'pixi.js';
2
+ export type SortFn = (a: ViewContainer, b: ViewContainer) => number;
@@ -1,2 +1,2 @@
1
1
  import type { SortingLayer } from '../types';
2
- export declare const parseSortingLayers: (sortingLayers?: SortingLayer[]) => Array<string>;
2
+ export declare const parseSortingLayers: (sortingLayers?: SortingLayer[]) => string[];
@@ -0,0 +1,26 @@
1
+ export interface SortingLayer {
2
+ id: string;
3
+ name: string;
4
+ }
5
+ export type SortingOrder = 'bottomRight' | 'bottomLeft' | 'topLeft' | 'topRight';
6
+ export interface Sorting {
7
+ layers: SortingLayer[];
8
+ order: SortingOrder;
9
+ }
10
+ export interface Bounds {
11
+ minX: number;
12
+ minY: number;
13
+ maxX: number;
14
+ maxY: number;
15
+ width: number;
16
+ height: number;
17
+ }
18
+ export interface ViewComponent {
19
+ renderData?: {
20
+ view: {
21
+ __dacha: {
22
+ bounds: Bounds;
23
+ };
24
+ };
25
+ };
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { Actor } from '../../../engine/actor';
2
+ import type { Template } from '../../../engine/template';
3
+ export declare const loadImage: (url?: string) => Promise<HTMLImageElement | undefined>;
4
+ export declare const getAllImageSources: (actors: (Actor | Template)[]) => string[];
5
+ export declare const getAllFontSources: (actors: (Actor | Template)[]) => string[];
@@ -0,0 +1,42 @@
1
+ import { Sprite } from '../../components/sprite';
2
+ import { BitmapText } from '../../components/bitmap-text';
3
+ import { ResourceLoader } from '../../../engine/resource-loader';
4
+ import { traverseEntity } from '../../../engine/entity';
5
+ const resourceLoader = new ResourceLoader();
6
+ export const loadImage = async (url) => {
7
+ if (!url) {
8
+ return undefined;
9
+ }
10
+ try {
11
+ const image = (await resourceLoader.load(url));
12
+ return image;
13
+ }
14
+ catch (error) {
15
+ console.warn(`Can't load image by the following url: ${url}`, error);
16
+ return undefined;
17
+ }
18
+ };
19
+ export const getAllImageSources = (actors) => {
20
+ const sources = [];
21
+ actors.forEach((actor) => {
22
+ traverseEntity(actor, (entity) => {
23
+ const sprite = entity.getComponent(Sprite);
24
+ if (sprite?.src) {
25
+ sources.push(sprite.src);
26
+ }
27
+ });
28
+ });
29
+ return sources;
30
+ };
31
+ export const getAllFontSources = (actors) => {
32
+ const sources = [];
33
+ actors.forEach((actor) => {
34
+ traverseEntity(actor, (entity) => {
35
+ const text = entity.getComponent(BitmapText);
36
+ if (text?.font) {
37
+ sources.push(text.font);
38
+ }
39
+ });
40
+ });
41
+ return sources;
42
+ };
@@ -1,4 +1,4 @@
1
- export type AttributeValue = string | number | boolean | Array<string>;
1
+ export type AttributeValue = string | number | boolean | string[];
2
2
  export type InputEventAttributes = Record<string, AttributeValue>;
3
3
  export interface InputEventAttributeConfig {
4
4
  name: string;
@@ -0,0 +1 @@
1
+ export type BlendingMode = 'normal' | 'addition' | 'substract' | 'multiply';
@@ -0,0 +1 @@
1
+ export {};
@@ -6,8 +6,11 @@ import type { ComponentConstructor } from '../component';
6
6
  import { Actor } from './actor';
7
7
  type ActorCollectionListenerFn<T extends EventType> = (event: T extends keyof ActorCollectionEventMap ? ActorCollectionEventMap[T] : Event) => void;
8
8
  export interface ActorCollectionFilter {
9
- components?: Array<ComponentConstructor | string>;
9
+ components?: (ComponentConstructor | string)[];
10
10
  }
11
+ /**
12
+ * @deprecated Use `ActorQuery` instead.
13
+ */
11
14
  export declare class ActorCollection extends EventTarget {
12
15
  private components;
13
16
  private acceptedActors;
@@ -2,13 +2,16 @@ import { EventTarget } from '../event-target';
2
2
  import { AddComponent, RemoveComponent, AddActor, RemoveActor, AddChildEntity, RemoveChildEntity, } from '../events';
3
3
  import { traverseEntity } from '../entity';
4
4
  import { Actor } from './actor';
5
+ /**
6
+ * @deprecated Use `ActorQuery` instead.
7
+ */
5
8
  export class ActorCollection extends EventTarget {
6
9
  components;
7
10
  acceptedActors;
8
11
  acceptedActorsMap;
9
12
  constructor(scene, filter = {}) {
10
13
  super();
11
- const { components = [], } = filter;
14
+ const { components = [] } = filter;
12
15
  this.components = components;
13
16
  this.acceptedActorsMap = {};
14
17
  this.acceptedActors = [];
@@ -5,15 +5,15 @@ import { Actor } from './actor';
5
5
  export interface ActorOptions {
6
6
  id?: string;
7
7
  name?: string;
8
- children?: Array<ActorOptions>;
9
- components?: Array<ComponentConfig>;
8
+ children?: ActorOptions[];
9
+ components?: ComponentConfig[];
10
10
  templateId?: string;
11
11
  isNew?: boolean;
12
12
  }
13
13
  export declare class ActorCreator {
14
14
  private components;
15
15
  private templateCollection;
16
- constructor(components: Array<ComponentConstructor>, templateCollection: TemplateCollection);
16
+ constructor(components: ComponentConstructor[], templateCollection: TemplateCollection);
17
17
  private buildFromTemplate;
18
18
  private buildFromScratch;
19
19
  private build;
@@ -0,0 +1,29 @@
1
+ import { EventTarget } from '../event-target';
2
+ import type { EventType, Event } from '../event-target';
3
+ import type { ActorCollectionEventMap } from '../events';
4
+ import type { Scene } from '../scene';
5
+ import type { ComponentConstructor } from '../component';
6
+ import { Actor } from './actor';
7
+ type ActorQueryListenerFn<T extends EventType> = (event: T extends keyof ActorCollectionEventMap ? ActorCollectionEventMap[T] : Event) => void;
8
+ export type ActorQueryFilter = (ComponentConstructor | string)[] | ((actor: Actor) => boolean);
9
+ export interface ActorQueryOptions {
10
+ scene: Scene;
11
+ filter: ActorQueryFilter;
12
+ }
13
+ export declare class ActorQuery extends EventTarget {
14
+ private scene;
15
+ private filter;
16
+ private matchedActors;
17
+ constructor(options: ActorQueryOptions);
18
+ destroy(): void;
19
+ addEventListener<T extends EventType>(type: T, callback: ActorQueryListenerFn<T>): void;
20
+ removeEventListener<T extends EventType>(type: T, callback: ActorQueryListenerFn<T>): void;
21
+ private handleAddChildEntity;
22
+ private handleRemoveChildEntity;
23
+ private handleActorUpdate;
24
+ private test;
25
+ private add;
26
+ private delete;
27
+ getActors(): Set<Actor>;
28
+ }
29
+ export {};
@@ -0,0 +1,85 @@
1
+ import { EventTarget } from '../event-target';
2
+ import { AddComponent, RemoveComponent, AddActor, RemoveActor, AddChildEntity, RemoveChildEntity, } from '../events';
3
+ import { traverseEntity } from '../entity';
4
+ import { Actor } from './actor';
5
+ export class ActorQuery extends EventTarget {
6
+ scene;
7
+ filter;
8
+ matchedActors;
9
+ constructor(options) {
10
+ super();
11
+ const { scene, filter } = options;
12
+ this.scene = scene;
13
+ this.filter = filter;
14
+ this.matchedActors = new Set();
15
+ traverseEntity(scene, (entity) => {
16
+ if (entity instanceof Actor && this.test(entity)) {
17
+ this.matchedActors.add(entity);
18
+ }
19
+ });
20
+ scene.addEventListener(AddChildEntity, this.handleAddChildEntity);
21
+ scene.addEventListener(RemoveChildEntity, this.handleRemoveChildEntity);
22
+ scene.addEventListener(AddComponent, this.handleActorUpdate);
23
+ scene.addEventListener(RemoveComponent, this.handleActorUpdate);
24
+ }
25
+ destroy() {
26
+ this.scene.removeEventListener(AddChildEntity, this.handleAddChildEntity);
27
+ this.scene.removeEventListener(RemoveChildEntity, this.handleRemoveChildEntity);
28
+ this.scene.removeEventListener(AddComponent, this.handleActorUpdate);
29
+ this.scene.removeEventListener(RemoveComponent, this.handleActorUpdate);
30
+ }
31
+ addEventListener(type, callback) {
32
+ super.addEventListener(type, callback);
33
+ }
34
+ removeEventListener(type, callback) {
35
+ super.removeEventListener(type, callback);
36
+ }
37
+ handleAddChildEntity = (event) => {
38
+ traverseEntity(event.child, (entity) => {
39
+ if (entity instanceof Actor && this.test(entity)) {
40
+ this.add(entity);
41
+ }
42
+ });
43
+ };
44
+ handleRemoveChildEntity = (event) => {
45
+ traverseEntity(event.child, (entity) => {
46
+ if (entity instanceof Actor) {
47
+ this.delete(entity);
48
+ }
49
+ });
50
+ };
51
+ handleActorUpdate = (event) => {
52
+ const { target } = event;
53
+ if (this.test(target)) {
54
+ this.add(target);
55
+ }
56
+ else {
57
+ this.delete(target);
58
+ }
59
+ };
60
+ test(actor) {
61
+ if (typeof this.filter === 'function') {
62
+ return this.filter(actor);
63
+ }
64
+ return this.filter.every((component) => {
65
+ return actor.getComponent(component);
66
+ });
67
+ }
68
+ add(actor) {
69
+ if (this.matchedActors.has(actor)) {
70
+ return;
71
+ }
72
+ this.matchedActors.add(actor);
73
+ this.dispatchEventImmediately(AddActor, { actor });
74
+ }
75
+ delete(actor) {
76
+ if (!this.matchedActors.has(actor)) {
77
+ return;
78
+ }
79
+ this.matchedActors.delete(actor);
80
+ this.dispatchEventImmediately(RemoveActor, { actor });
81
+ }
82
+ getActors() {
83
+ return this.matchedActors;
84
+ }
85
+ }
@@ -10,7 +10,7 @@ export interface ActorOptions extends EntityOptions {
10
10
  }
11
11
  export declare class Actor extends Entity {
12
12
  private components;
13
- readonly children: Array<Actor>;
13
+ readonly children: Actor[];
14
14
  readonly templateId?: string;
15
15
  parent: Actor | Scene | null;
16
16
  constructor(options: ActorOptions);
@@ -23,9 +23,8 @@ export declare class Actor extends Entity {
23
23
  findChild(predicate: (child: Actor) => boolean, recursive?: boolean): Actor | undefined;
24
24
  findChildById(id: string, recursive?: boolean): Actor | undefined;
25
25
  findChildByName(name: string, recursive?: boolean): Actor | undefined;
26
- getComponents(): Array<Component>;
27
- getComponent<T extends Component = Component>(componentName: string): T;
28
- getComponent<T extends Component>(componentClass: ComponentConstructor<T>): T;
26
+ getComponents(): Component[];
27
+ getComponent<T extends Component>(classOrName: ComponentConstructor<T> | string): T;
29
28
  setComponent(component: Component): void;
30
29
  removeComponent(componentClass: ComponentConstructor): void;
31
30
  }
@@ -3,3 +3,5 @@ export { ActorCollection } from './actor-collection';
3
3
  export { ActorCreator } from './actor-creator';
4
4
  export { ActorSpawner } from './actor-spawner';
5
5
  export type { ActorCollectionFilter } from './actor-collection';
6
+ export { ActorQuery } from './actor-query';
7
+ export type { ActorQueryFilter } from './actor-query';
@@ -2,3 +2,4 @@ export { Actor } from './actor';
2
2
  export { ActorCollection } from './actor-collection';
3
3
  export { ActorCreator } from './actor-creator';
4
4
  export { ActorSpawner } from './actor-spawner';
5
+ export { ActorQuery } from './actor-query';
@@ -3,11 +3,11 @@ import type { Constructor } from '../../types/utils';
3
3
  export type ComponentConstructor<T extends Component = Component> = Constructor<T> & {
4
4
  componentName: string;
5
5
  };
6
- export declare const findParentComponent: (actor: Actor, componentClass: ComponentConstructor) => Component | void;
6
+ export declare const findParentComponent: (actor: Actor, componentClass: ComponentConstructor) => Component | undefined;
7
7
  export declare abstract class Component {
8
8
  static componentName: string;
9
9
  actor?: Actor;
10
10
  constructor();
11
- getParentComponent(): Component | void;
11
+ getParentComponent(): Component | undefined;
12
12
  abstract clone(): Component;
13
13
  }
@@ -4,8 +4,9 @@ export declare class CacheStore<T> {
4
4
  add(src: string, data: T): void;
5
5
  get(src: string): T | undefined;
6
6
  retain(src: string): void;
7
- release(src: string): void;
7
+ release(src: string, clean?: boolean): void;
8
8
  has(src: string): boolean;
9
+ get size(): number;
9
10
  cleanReleased(): void;
10
11
  clear(): void;
11
12
  }
@@ -16,15 +16,21 @@ export class CacheStore {
16
16
  entry.count += 1;
17
17
  }
18
18
  }
19
- release(src) {
19
+ release(src, clean) {
20
20
  const entry = this.cache.get(src);
21
21
  if (entry) {
22
22
  entry.count -= 1;
23
+ if (clean && entry.count <= 0) {
24
+ this.cache.delete(src);
25
+ }
23
26
  }
24
27
  }
25
28
  has(src) {
26
29
  return this.cache.has(src);
27
30
  }
31
+ get size() {
32
+ return this.cache.size;
33
+ }
28
34
  // TODO: It's hard to find a place in a system's lifecycle to call this method
29
35
  // Find another way to keep resources until scene is destroyed
30
36
  cleanReleased() {
@@ -3,20 +3,42 @@ import type { ComponentConstructor } from './component';
3
3
  import type { Config } from './types';
4
4
  export interface EngineOptions {
5
5
  config: Config;
6
- systems: Array<SystemConstructor>;
7
- components: Array<ComponentConstructor>;
6
+ systems: SystemConstructor[];
7
+ components: ComponentConstructor[];
8
8
  resources?: Record<string, unknown>;
9
9
  }
10
+ /**
11
+ * Main game engine responsible for bootstrapping scenes and systems, managing the
12
+ * game loop, and controlling lifecycle actions (play, pause, stop).
13
+ */
10
14
  export declare class Engine {
11
15
  private options;
12
16
  private gameLoop?;
13
17
  private sceneManager?;
18
+ /**
19
+ * Creates a new engine instance.
20
+ *
21
+ * @param options - Configuration, available systems and components, and optional shared resources.
22
+ */
14
23
  constructor(options: EngineOptions);
15
- private handleWindowBlur;
16
- private handleWindowFocus;
17
- private addWindowListeners;
18
- private removeWindowListeners;
24
+ /**
25
+ * Starts the engine. If the engine was already initialized, this resumes the
26
+ * game loop and re-attaches window listeners. Otherwise, it bootstraps the
27
+ * world, loads the start scene, creates the game loop, and begins execution.
28
+ *
29
+ * @returns A promise that resolves once the engine is fully started.
30
+ * @throws Error If `startSceneId` is not provided in the config.
31
+ * @throws Error If any component is missing `componentName`.
32
+ * @throws Error If any system is missing `systemName`.
33
+ */
19
34
  play(): Promise<void>;
35
+ /**
36
+ * Pauses the engine by stopping the game loop.
37
+ * The world and scene state remain in memory so it can be resumed with `play`.
38
+ */
20
39
  pause(): void;
40
+ /**
41
+ * Stops the engine completely by stopping the game loop and destroying the world.
42
+ */
21
43
  stop(): void;
22
44
  }
@@ -1,50 +1,54 @@
1
1
  import { SceneManager } from './scene/scene-manager';
2
2
  import { TemplateCollection } from './template';
3
3
  import { GameLoop } from './game-loop';
4
+ /**
5
+ * Main game engine responsible for bootstrapping scenes and systems, managing the
6
+ * game loop, and controlling lifecycle actions (play, pause, stop).
7
+ */
4
8
  export class Engine {
5
9
  options;
6
10
  gameLoop;
7
11
  sceneManager;
12
+ /**
13
+ * Creates a new engine instance.
14
+ *
15
+ * @param options - Configuration, available systems and components, and optional shared resources.
16
+ */
8
17
  constructor(options) {
9
18
  this.options = options;
10
19
  }
11
- handleWindowBlur = () => {
12
- this.gameLoop?.stop();
13
- };
14
- handleWindowFocus = () => {
15
- this.gameLoop?.run();
16
- };
17
- addWindowListeners() {
18
- window.addEventListener('blur', this.handleWindowBlur);
19
- window.addEventListener('focus', this.handleWindowFocus);
20
- }
21
- removeWindowListeners() {
22
- window.removeEventListener('blur', this.handleWindowBlur);
23
- window.removeEventListener('focus', this.handleWindowFocus);
24
- }
20
+ /**
21
+ * Starts the engine. If the engine was already initialized, this resumes the
22
+ * game loop and re-attaches window listeners. Otherwise, it bootstraps the
23
+ * world, loads the start scene, creates the game loop, and begins execution.
24
+ *
25
+ * @returns A promise that resolves once the engine is fully started.
26
+ * @throws Error If `startSceneId` is not provided in the config.
27
+ * @throws Error If any component is missing `componentName`.
28
+ * @throws Error If any system is missing `systemName`.
29
+ */
25
30
  async play() {
26
31
  if (this.sceneManager !== undefined && this.gameLoop !== undefined) {
27
32
  this.gameLoop.run();
28
- this.addWindowListeners();
29
33
  return;
30
34
  }
31
35
  const { config: { templates, scenes, systems, startSceneId, globalOptions: rawGlobalOptions, }, systems: availableSystems, components, resources = {}, } = this.options;
32
36
  if (!startSceneId) {
33
- throw new Error('Can\'t start the engine without starting scene. Please specify start scene id.');
37
+ throw new Error("Can't start the engine without starting scene. Please specify start scene id.");
34
38
  }
35
- for (let i = 0; i < components.length; i += 1) {
36
- if (components[i].componentName === undefined) {
37
- throw new Error(`Missing componentName field for ${components[i].name} component.`);
39
+ for (const component of components) {
40
+ if (component.componentName === undefined) {
41
+ throw new Error(`Missing componentName field for ${component.name} component.`);
38
42
  }
39
43
  }
40
- for (let i = 0; i < availableSystems.length; i += 1) {
41
- if (availableSystems[i].systemName === undefined) {
42
- throw new Error(`Missing systemName field for ${availableSystems[i].name} system.`);
44
+ for (const availableSystem of availableSystems) {
45
+ if (availableSystem.systemName === undefined) {
46
+ throw new Error(`Missing systemName field for ${availableSystem.name} system.`);
43
47
  }
44
48
  }
45
49
  const templateCollection = new TemplateCollection(components);
46
- for (let i = 0; i < templates.length; i += 1) {
47
- templateCollection.register(templates[i]);
50
+ for (const template of templates) {
51
+ templateCollection.register(template);
48
52
  }
49
53
  const globalOptions = rawGlobalOptions.reduce((acc, option) => {
50
54
  acc[option.name] = option.options;
@@ -63,16 +67,20 @@ export class Engine {
63
67
  await this.sceneManager.loadScene(startSceneId, true);
64
68
  this.gameLoop = new GameLoop(this.sceneManager, globalOptions.performance);
65
69
  this.gameLoop.run();
66
- this.addWindowListeners();
67
70
  }
71
+ /**
72
+ * Pauses the engine by stopping the game loop.
73
+ * The world and scene state remain in memory so it can be resumed with `play`.
74
+ */
68
75
  pause() {
69
76
  this.gameLoop?.stop();
70
- this.removeWindowListeners();
71
77
  }
78
+ /**
79
+ * Stops the engine completely by stopping the game loop and destroying the world.
80
+ */
72
81
  stop() {
73
82
  this.gameLoop?.stop();
74
83
  this.sceneManager?.destroyWorld();
75
- this.removeWindowListeners();
76
84
  this.gameLoop = undefined;
77
85
  this.sceneManager = undefined;
78
86
  }
@@ -6,7 +6,7 @@ export interface EntityOptions {
6
6
  export declare class Entity extends EventTarget {
7
7
  readonly id: string;
8
8
  readonly name: string;
9
- children: Array<Entity>;
9
+ children: Entity[];
10
10
  parent: Entity | null;
11
11
  constructor({ id, name }: EntityOptions);
12
12
  appendChild(child: Entity): void;
@@ -4,7 +4,7 @@ export declare class EventTarget {
4
4
  private listenersMap;
5
5
  constructor();
6
6
  addEventListener(type: EventType, callback: ListenerFn): void;
7
- getEventListeners(type: EventType): Array<ListenerFn> | undefined;
7
+ getEventListeners(type: EventType): ListenerFn[] | undefined;
8
8
  removeEventListener(type: EventType, callback: ListenerFn): void;
9
9
  removeAllListeners(): void;
10
10
  private handleEvent;
@@ -1,12 +1,12 @@
1
1
  import { Vector2 } from './vector2';
2
- type Point = {
2
+ interface Point {
3
3
  x: number;
4
4
  y: number;
5
- };
6
- type Edge = {
5
+ }
6
+ interface Edge {
7
7
  point1: Point;
8
8
  point2: Point;
9
- };
9
+ }
10
10
  export declare class VectorOps {
11
11
  static fixCalcError(value: number): number;
12
12
  static getVectorByAngle(angle: number): Vector2;
@@ -23,7 +23,7 @@ export class VectorOps {
23
23
  * Calculate dot product of two vectors
24
24
  */
25
25
  static dotProduct(point, vector) {
26
- return (point.x * vector.x) + (point.y * vector.y);
26
+ return point.x * vector.x + point.y * vector.y;
27
27
  }
28
28
  /**
29
29
  * Projects a point onto a given edge, returning the closest point
@@ -65,8 +65,7 @@ export class VectorOps {
65
65
  const x2 = edge.point2.x;
66
66
  const y2 = edge.point2.y;
67
67
  // https://en.wikipedia.org/wiki/Linear_equation#Determinant_form
68
- const isIntersection = (y1 > y !== y2 > y)
69
- && (x < ((x2 - x1) * (y - y1)) / (y2 - y1) + x1);
68
+ const isIntersection = y1 > y !== y2 > y && x < ((x2 - x1) * (y - y1)) / (y2 - y1) + x1;
70
69
  if (isIntersection) {
71
70
  isInside = !isInside;
72
71
  }
@@ -2,6 +2,6 @@ import type { Loader } from './loader';
2
2
  export declare class ImageLoader implements Loader {
3
3
  private supportedExtensions;
4
4
  constructor();
5
- getSupportedExtensions(): Array<string>;
5
+ getSupportedExtensions(): string[];
6
6
  load(resourceUrl: string): Promise<unknown>;
7
7
  }
@@ -1,4 +1,3 @@
1
+ import type { Constructor } from '../../../types/utils';
1
2
  import type { Loader } from './loader';
2
- export declare const loaders: Record<string, {
3
- new (): Loader;
4
- }>;
3
+ export declare const loaders: Record<string, Constructor<Loader>>;
@@ -2,6 +2,6 @@ import { Loader } from './loader';
2
2
  export declare class JsonLoader implements Loader {
3
3
  private supportedExtensions;
4
4
  constructor();
5
- getSupportedExtensions(): Array<string>;
5
+ getSupportedExtensions(): string[];
6
6
  load(resourceUrl: string): Promise<unknown>;
7
7
  }
@@ -1,4 +1,4 @@
1
1
  export interface Loader {
2
- getSupportedExtensions(): Array<string>;
2
+ getSupportedExtensions(): string[];
3
3
  load(resourceUrl: string): Promise<unknown>;
4
4
  }
@@ -5,6 +5,7 @@ import { World } from '../world';
5
5
  import { LoadScene, EnterScene, ExitScene, DestroyScene, SceneLoaded, SceneEntered, SceneExited, SceneDestroyed, } from '../events';
6
6
  import { isSubclassOf } from '../utils/is-subclass-of';
7
7
  import { Scene } from './scene';
8
+ ;
8
9
  export class SceneManager {
9
10
  sceneConfigs;
10
11
  systemConfigs;
@@ -27,7 +28,12 @@ export class SceneManager {
27
28
  acc[scene.id] = scene;
28
29
  return acc;
29
30
  }, {});
30
- this.systemConfigs = systemConfigs.filter((config) => this.availableSystems[config.name]);
31
+ this.systemConfigs = systemConfigs.filter((config) => {
32
+ if (!this.availableSystems[config.name]) {
33
+ console.warn(`System not found: ${config.name}`);
34
+ }
35
+ return this.availableSystems[config.name];
36
+ });
31
37
  this.templateCollection = templateCollection;
32
38
  this.globalOptions = globalOptions;
33
39
  this.resources = resources;