dacha 0.17.2 → 0.18.0-alpha.1

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 (132) hide show
  1. package/build/contrib/components/collider/index.d.ts +17 -4
  2. package/build/contrib/components/collider/index.js +30 -2
  3. package/build/contrib/components/rigid-body/index.d.ts +29 -17
  4. package/build/contrib/components/rigid-body/index.js +64 -21
  5. package/build/contrib/components/shape/index.d.ts +17 -2
  6. package/build/contrib/components/shape/index.js +16 -0
  7. package/build/contrib/events/index.d.ts +10 -75
  8. package/build/contrib/events/index.js +0 -36
  9. package/build/contrib/systems/camera-system/{service.d.ts → api.d.ts} +4 -4
  10. package/build/contrib/systems/camera-system/{service.js → api.js} +2 -2
  11. package/build/contrib/systems/camera-system/index.d.ts +1 -1
  12. package/build/contrib/systems/camera-system/index.js +1 -1
  13. package/build/contrib/systems/camera-system/system.d.ts +1 -1
  14. package/build/contrib/systems/camera-system/system.js +5 -4
  15. package/build/contrib/systems/index.d.ts +3 -3
  16. package/build/contrib/systems/index.js +3 -3
  17. package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.d.ts +0 -1
  18. package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.js +4 -5
  19. package/build/contrib/systems/physics-system/api.d.ts +58 -0
  20. package/build/contrib/systems/physics-system/api.js +67 -0
  21. package/build/contrib/systems/physics-system/index.d.ts +2 -21
  22. package/build/contrib/systems/physics-system/index.js +2 -40
  23. package/build/contrib/systems/physics-system/physics-system.d.ts +24 -0
  24. package/build/contrib/systems/physics-system/physics-system.js +47 -0
  25. package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.d.ts +5 -3
  26. package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.js +7 -5
  27. package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.d.ts +4 -6
  28. package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.js +20 -17
  29. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-circle-aabb.js +1 -2
  30. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.d.ts +2 -0
  31. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.js +7 -0
  32. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.d.ts +2 -0
  33. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.js +9 -0
  34. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.d.ts +2 -0
  35. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.js +14 -0
  36. package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/index.js +6 -0
  37. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +3 -1
  38. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +52 -16
  39. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +3 -1
  40. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +32 -7
  41. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.d.ts +3 -0
  42. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.js +5 -0
  43. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.d.ts +3 -0
  44. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.js +7 -0
  45. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.d.ts +3 -0
  46. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.js +33 -0
  47. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +12 -1
  48. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.js +6 -0
  49. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +21 -9
  50. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +177 -92
  51. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.d.ts +10 -0
  52. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.js +36 -0
  53. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.d.ts +17 -0
  54. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.js +126 -0
  55. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.d.ts +9 -0
  56. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.js +46 -0
  57. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.d.ts +10 -0
  58. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.js +28 -0
  59. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.d.ts +19 -0
  60. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.js +76 -0
  61. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.d.ts +12 -0
  62. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.js +47 -0
  63. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.d.ts +10 -0
  64. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.js +33 -0
  65. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.d.ts +2 -2
  66. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +27 -3
  67. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.d.ts +9 -0
  68. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.js +36 -0
  69. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.d.ts +9 -0
  70. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.js +33 -0
  71. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.d.ts +9 -0
  72. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.js +26 -0
  73. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.d.ts +11 -0
  74. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.js +69 -0
  75. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.d.ts +10 -0
  76. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.js +45 -0
  77. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.d.ts +16 -0
  78. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.js +51 -0
  79. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.d.ts +2 -0
  80. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.js +4 -0
  81. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.d.ts +20 -0
  82. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.js +69 -0
  83. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.d.ts +9 -0
  84. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.js +23 -0
  85. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +10 -0
  86. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +63 -0
  87. package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.js +17 -8
  88. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +41 -11
  89. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.js +0 -3
  90. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +7 -10
  91. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +117 -79
  92. package/build/contrib/systems/physics-system/subsystems/index.d.ts +0 -1
  93. package/build/contrib/systems/physics-system/subsystems/index.js +0 -1
  94. package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +3 -9
  95. package/build/contrib/systems/physics-system/subsystems/physics/index.js +57 -93
  96. package/build/contrib/systems/physics-system/types.d.ts +37 -0
  97. package/build/contrib/systems/renderer/actor-render-tree.js +1 -2
  98. package/build/contrib/systems/renderer/{service → api}/index.d.ts +6 -6
  99. package/build/contrib/systems/renderer/{service → api}/index.js +14 -16
  100. package/build/contrib/systems/renderer/api/utils.d.ts +4 -0
  101. package/build/contrib/systems/renderer/{service → api}/utils.js +5 -0
  102. package/build/contrib/systems/renderer/builders/shape-builder/index.js +9 -1
  103. package/build/contrib/systems/renderer/builders/shape-builder/utils.js +16 -0
  104. package/build/contrib/systems/renderer/index.d.ts +1 -1
  105. package/build/contrib/systems/renderer/index.js +1 -1
  106. package/build/contrib/systems/renderer/renderer.d.ts +2 -1
  107. package/build/contrib/systems/renderer/renderer.js +9 -7
  108. package/build/engine/actor/actor-creator.js +6 -4
  109. package/build/engine/math-lib/math/ops.d.ts +1 -2
  110. package/build/engine/math-lib/math/ops.js +3 -3
  111. package/build/engine/math-lib/vector/ops.d.ts +18 -3
  112. package/build/engine/math-lib/vector/ops.js +28 -5
  113. package/build/engine/math-lib/vector/vector2.d.ts +22 -7
  114. package/build/engine/math-lib/vector/vector2.js +29 -5
  115. package/build/engine/template/template-collection.js +1 -1
  116. package/build/engine/world/index.d.ts +4 -24
  117. package/build/engine/world/index.js +5 -33
  118. package/build/engine/world/system-api-registry.d.ts +17 -0
  119. package/build/engine/world/system-api-registry.js +34 -0
  120. package/build/events/index.d.ts +2 -2
  121. package/build/events/index.js +1 -1
  122. package/build/types/global.d.ts +4 -0
  123. package/package.json +4 -1
  124. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.d.ts +0 -16
  125. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.js +0 -80
  126. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.d.ts +0 -6
  127. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.js +0 -72
  128. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.d.ts +0 -11
  129. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.js +0 -39
  130. package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +0 -10
  131. package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +0 -50
  132. package/build/contrib/systems/renderer/service/utils.d.ts +0 -3
@@ -51,7 +51,11 @@ export class ShapeBuilder {
51
51
  shape.height !== meta.height ||
52
52
  shape.radius !== meta.radius ||
53
53
  shape.radiusX !== meta.radiusX ||
54
- shape.radiusY !== meta.radiusY) {
54
+ shape.radiusY !== meta.radiusY ||
55
+ shape.point1X !== meta.point1X ||
56
+ shape.point1Y !== meta.point1Y ||
57
+ shape.point2X !== meta.point2X ||
58
+ shape.point2Y !== meta.point2Y) {
55
59
  view.label = shape.type;
56
60
  this.updateGraphicsContext(shape);
57
61
  meta.type = shape.type;
@@ -63,6 +67,10 @@ export class ShapeBuilder {
63
67
  meta.radius = shape.radius;
64
68
  meta.radiusX = shape.radiusX;
65
69
  meta.radiusY = shape.radiusY;
70
+ meta.point1X = shape.point1X;
71
+ meta.point1Y = shape.point1Y;
72
+ meta.point2X = shape.point2X;
73
+ meta.point2Y = shape.point2Y;
66
74
  }
67
75
  const graphicsContext = this.getGraphicsContext(shape);
68
76
  view.context = graphicsContext;
@@ -61,6 +61,18 @@ export const getGraphicsContext = (shape) => {
61
61
  }
62
62
  return ellipse;
63
63
  }
64
+ case 'line': {
65
+ const { point1X, point1Y, point2X, point2Y, strokeWidth, strokeColor, strokeAlignment, pixelLine, } = shape;
66
+ return new GraphicsContext()
67
+ .moveTo(point1X, point1Y)
68
+ .lineTo(point2X, point2Y)
69
+ .stroke({
70
+ width: strokeWidth,
71
+ alignment: strokeAlignment,
72
+ color: strokeColor,
73
+ pixelLine,
74
+ });
75
+ }
64
76
  }
65
77
  };
66
78
  export const getGraphicsContextKey = (shape) => {
@@ -81,5 +93,9 @@ export const getGraphicsContextKey = (shape) => {
81
93
  const { type, radiusX, radiusY, strokeWidth, strokeColor, strokeAlignment, fill, pixelLine, } = shape;
82
94
  return `${type}_${radiusX}_${radiusY}_${strokeWidth}_${strokeColor}_${strokeAlignment}_${fill}_${pixelLine}`;
83
95
  }
96
+ case 'line': {
97
+ const { type, point1X, point1Y, point2X, point2Y, strokeWidth, strokeColor, strokeAlignment, pixelLine, } = shape;
98
+ return `${type}_${point1X}_${point1Y}_${point2X}_${point2Y}_${strokeWidth}_${strokeColor}_${strokeAlignment}_${pixelLine}`;
99
+ }
84
100
  }
85
101
  };
@@ -1,4 +1,4 @@
1
1
  export { Renderer } from './renderer';
2
- export { RendererService } from './service';
2
+ export { RendererAPI } from './api';
3
3
  export { FilterEffect } from './filters/filter-effect';
4
4
  export { Shader } from './material/shader';
@@ -1,4 +1,4 @@
1
1
  export { Renderer } from './renderer';
2
- export { RendererService } from './service';
2
+ export { RendererAPI } from './api';
3
3
  export { FilterEffect } from './filters/filter-effect';
4
4
  export { Shader } from './material/shader';
@@ -14,13 +14,14 @@ export declare class Renderer extends WorldSystem {
14
14
  private sortingLayers;
15
15
  private sortFn;
16
16
  private backgroundColor;
17
- private cameraService;
17
+ private cameraApi;
18
18
  private assets;
19
19
  private actorRenderTree?;
20
20
  private filterSystem;
21
21
  private materialSystem;
22
22
  private resources?;
23
23
  private time;
24
+ private rendererApi;
24
25
  constructor(options: WorldSystemOptions);
25
26
  onWorldLoad(): Promise<void>;
26
27
  onWorldDestroy(): void;
@@ -2,9 +2,9 @@ import { Application, Container, Color, RenderLayer, } from 'pixi.js';
2
2
  import { WorldSystem, } from '../../../engine/system';
3
3
  import { Transform } from '../../components/transform';
4
4
  import { Camera } from '../../components/camera';
5
- import { CameraService } from '../camera-system';
5
+ import { CameraAPI } from '../camera-system';
6
6
  import { getWindowNode } from '../../utils/get-window-node';
7
- import { RendererService } from './service';
7
+ import { RendererAPI } from './api';
8
8
  import { composeSort, createSortByLayer, sortByYAxis, sortByXAxis, } from './sort';
9
9
  import { parseSortingLayers } from './sort/utils';
10
10
  import { Assets } from './assets';
@@ -26,13 +26,14 @@ export class Renderer extends WorldSystem {
26
26
  sortingLayers;
27
27
  sortFn;
28
28
  backgroundColor;
29
- cameraService;
29
+ cameraApi;
30
30
  assets;
31
31
  actorRenderTree;
32
32
  filterSystem;
33
33
  materialSystem;
34
34
  resources;
35
35
  time;
36
+ rendererApi;
36
37
  constructor(options) {
37
38
  super();
38
39
  const { globalOptions, windowNodeId, backgroundColor, templateCollection, world, resources, filterEffects, } = options;
@@ -66,15 +67,16 @@ export class Renderer extends WorldSystem {
66
67
  filterEffects,
67
68
  availableFilterEffects: this.resources?.filterEffects,
68
69
  });
69
- this.cameraService = world.getService(CameraService);
70
- world.addService(new RendererService({
70
+ this.cameraApi = world.systemApi.get(CameraAPI);
71
+ this.rendererApi = new RendererAPI({
71
72
  application: this.application,
72
73
  worldContainer: this.worldContainer,
73
74
  getViewEntries: () => this.actorRenderTree?.viewEntries,
74
75
  sortFn: this.sortFn,
75
76
  filterSystem: this.filterSystem,
76
77
  materialSystem: this.materialSystem,
77
- }));
78
+ });
79
+ world.systemApi.register(this.rendererApi);
78
80
  }
79
81
  async onWorldLoad() {
80
82
  await this.application.init({
@@ -125,7 +127,7 @@ export class Renderer extends WorldSystem {
125
127
  this.assets.unload(scene);
126
128
  }
127
129
  updateCamera() {
128
- const currentCamera = this.cameraService.getCurrentCamera();
130
+ const currentCamera = this.cameraApi.getCurrentCamera();
129
131
  const transform = currentCamera?.getComponent(Transform);
130
132
  const camera = currentCamera?.getComponent(Camera);
131
133
  const x = transform?.world.position.x ?? 0;
@@ -15,10 +15,12 @@ export class ActorCreator {
15
15
  let { id, name } = options;
16
16
  id = id || uuid();
17
17
  name = name || id;
18
- const template = templateId ? this.templateCollection.get(templateId) : undefined;
18
+ const template = templateId
19
+ ? this.templateCollection.get(templateId)
20
+ : undefined;
19
21
  if (!template) {
20
- throw new Error(`Can't create actor ${name} from template. `
21
- + `The template with id ${String(templateId)} is null.`);
22
+ throw new Error(`Can't create actor ${name} from template. ` +
23
+ `The template with id ${String(templateId)} is null.`);
22
24
  }
23
25
  const actor = new Actor({
24
26
  id,
@@ -52,7 +54,7 @@ export class ActorCreator {
52
54
  return actor;
53
55
  }
54
56
  buildFromScratch(options) {
55
- const { name, components = [], children = [], } = options;
57
+ const { name, components = [], children = [] } = options;
56
58
  let { id } = options;
57
59
  id = id || uuid();
58
60
  const actor = new Actor({
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * A point in 2D space with x and y coordinates.
3
3
  */
4
- interface Point {
4
+ export interface Point {
5
5
  /** X coordinate of the point */
6
6
  x: number;
7
7
  /** Y coordinate of the point */
@@ -119,4 +119,3 @@ export declare class MathOps {
119
119
  */
120
120
  static clamp(value: number, min: number, max: number): number;
121
121
  }
122
- export {};
@@ -26,7 +26,7 @@ export class MathOps {
26
26
  * ```
27
27
  */
28
28
  static random(min, max) {
29
- return Math.floor(min + (Math.random() * (max + 1 - min)));
29
+ return Math.floor(min + Math.random() * (max + 1 - min));
30
30
  }
31
31
  /**
32
32
  * Convert radians to degrees
@@ -108,8 +108,8 @@ export class MathOps {
108
108
  static getLinePoint(angle, x, y, length) {
109
109
  const angleInRad = this.degToRad(angle);
110
110
  return {
111
- x: x - (length * Math.cos(angleInRad)),
112
- y: y - (length * Math.sin(angleInRad)),
111
+ x: x - length * Math.cos(angleInRad),
112
+ y: y - length * Math.sin(angleInRad),
113
113
  };
114
114
  }
115
115
  /**
@@ -89,7 +89,22 @@ export declare class VectorOps {
89
89
  */
90
90
  static dotProduct(point: Point, vector: Vector2): number;
91
91
  /**
92
- * Projects a point onto a given edge, returning the closest point
92
+ * Calculates the cross product of two points.
93
+ *
94
+ * @param point1 - First point to use in the cross product
95
+ * @param point2 - Second point to use in the cross product
96
+ * @returns Scalar value representing the cross product of the two points
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const point1 = { x: 3, y: 4 };
101
+ * const point2 = { x: 1, y: 2 };
102
+ * const cross = VectorOps.crossProduct(point1, point2);
103
+ * ```
104
+ */
105
+ static crossProduct(point1: Point, point2: Point): number;
106
+ /**
107
+ * Returns the closest point on an edge segment to the given point.
93
108
  *
94
109
  * @param {Point} point - Point to project. Should have properties `x` and `y`.
95
110
  * @param {Edge} edge - Edge to project onto, defined by two endpoints `point1` and `point2`.
@@ -100,10 +115,10 @@ export declare class VectorOps {
100
115
  * ```typescript
101
116
  * const point = { x: 3, y: 4 };
102
117
  * const edge = { point1: { x: 0, y: 0 }, point2: { x: 10, y: 0 } };
103
- * const projected = VectorOps.projectPointToEdge(point, edge);
118
+ * const projected = VectorOps.getClosestPointOnEdge(point, edge);
104
119
  * ```
105
120
  */
106
- static projectPointToEdge(point: Point, edge: Edge): Point;
121
+ static getClosestPointOnEdge(point: Point, edge: Edge): Point;
107
122
  /**
108
123
  * Determines if a point is inside a polygon.
109
124
  *
@@ -65,6 +65,9 @@ export class VectorOps {
65
65
  * ```
66
66
  */
67
67
  static getNormal(x1, x2, y1, y2) {
68
+ if (x1 === x2 && y1 === y2) {
69
+ return VectorOps.getVectorByAngle(0);
70
+ }
68
71
  const normal = new Vector2(y1 - y2, x2 - x1);
69
72
  normal.multiplyNumber(1 / normal.magnitude);
70
73
  return normal;
@@ -87,7 +90,24 @@ export class VectorOps {
87
90
  return point.x * vector.x + point.y * vector.y;
88
91
  }
89
92
  /**
90
- * Projects a point onto a given edge, returning the closest point
93
+ * Calculates the cross product of two points.
94
+ *
95
+ * @param point1 - First point to use in the cross product
96
+ * @param point2 - Second point to use in the cross product
97
+ * @returns Scalar value representing the cross product of the two points
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const point1 = { x: 3, y: 4 };
102
+ * const point2 = { x: 1, y: 2 };
103
+ * const cross = VectorOps.crossProduct(point1, point2);
104
+ * ```
105
+ */
106
+ static crossProduct(point1, point2) {
107
+ return point1.x * point2.y - point1.y * point2.x;
108
+ }
109
+ /**
110
+ * Returns the closest point on an edge segment to the given point.
91
111
  *
92
112
  * @param {Point} point - Point to project. Should have properties `x` and `y`.
93
113
  * @param {Edge} edge - Edge to project onto, defined by two endpoints `point1` and `point2`.
@@ -98,15 +118,18 @@ export class VectorOps {
98
118
  * ```typescript
99
119
  * const point = { x: 3, y: 4 };
100
120
  * const edge = { point1: { x: 0, y: 0 }, point2: { x: 10, y: 0 } };
101
- * const projected = VectorOps.projectPointToEdge(point, edge);
121
+ * const projected = VectorOps.getClosestPointOnEdge(point, edge);
102
122
  * ```
103
123
  */
104
- static projectPointToEdge(point, edge) {
124
+ static getClosestPointOnEdge(point, edge) {
105
125
  const abVector = new Vector2(edge.point2.x - edge.point1.x, edge.point2.y - edge.point1.y);
106
126
  const apVector = new Vector2(point.x - edge.point1.x, point.y - edge.point1.y);
107
- const dotProduct = VectorOps.dotProduct(apVector, abVector);
108
127
  const lengthSquared = abVector.x * abVector.x + abVector.y * abVector.y;
109
- const t = dotProduct / lengthSquared;
128
+ if (lengthSquared === 0) {
129
+ return edge.point1;
130
+ }
131
+ const dotProduct = VectorOps.dotProduct(apVector, abVector);
132
+ const t = Math.max(0, Math.min(1, dotProduct / lengthSquared));
110
133
  return {
111
134
  x: edge.point1.x + t * abVector.x,
112
135
  y: edge.point1.y + t * abVector.y,
@@ -15,28 +15,43 @@ export declare class Vector2 {
15
15
  */
16
16
  constructor(x: number, y: number);
17
17
  /**
18
- * Calculates the magnitude of the vector.
18
+ * Returns the Euclidean length of the vector.
19
+ *
19
20
  * @returns Magnitude of the vector
20
21
  */
21
22
  get magnitude(): number;
22
23
  /**
23
- * Adds the given vector to the current vector.
24
+ * Adds another vector to the current vector in place.
25
+ *
24
26
  * @param vector - Vector to add
27
+ * @returns The current vector after the addition
25
28
  */
26
- add(vector: Vector2): void;
29
+ add(vector: Vector2): Vector2;
27
30
  /**
28
- * Multiplies the current vector by the given number.
31
+ * Multiplies the current vector by a scalar in place.
32
+ *
29
33
  * @param number - Number to multiply by
34
+ * @returns The current vector after scaling
30
35
  */
31
- multiplyNumber(number: number): void;
36
+ multiplyNumber(number: number): Vector2;
32
37
  /**
33
- * Checks if the current vector is equal to the given vector.
38
+ * Normalizes the current vector to unit length in place.
39
+ *
40
+ * If the vector magnitude is zero, it remains unchanged.
41
+ *
42
+ * @returns The current vector after normalization
43
+ */
44
+ normalize(): Vector2;
45
+ /**
46
+ * Checks whether another vector has the same coordinates.
47
+ *
34
48
  * @param vector - Vector to compare with
35
49
  * @returns True if the vectors are equal, false otherwise
36
50
  */
37
51
  equals(vector: Vector2): boolean;
38
52
  /**
39
- * Creates a new vector with the same x and y coordinates as the current vector.
53
+ * Creates a new vector with the same coordinates.
54
+ *
40
55
  * @returns A new vector with the same x and y coordinates
41
56
  */
42
57
  clone(): Vector2;
@@ -18,30 +18,53 @@ export class Vector2 {
18
18
  this.y = y;
19
19
  }
20
20
  /**
21
- * Calculates the magnitude of the vector.
21
+ * Returns the Euclidean length of the vector.
22
+ *
22
23
  * @returns Magnitude of the vector
23
24
  */
24
25
  get magnitude() {
25
26
  return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
26
27
  }
27
28
  /**
28
- * Adds the given vector to the current vector.
29
+ * Adds another vector to the current vector in place.
30
+ *
29
31
  * @param vector - Vector to add
32
+ * @returns The current vector after the addition
30
33
  */
31
34
  add(vector) {
32
35
  this.x += vector.x;
33
36
  this.y += vector.y;
37
+ return this;
34
38
  }
35
39
  /**
36
- * Multiplies the current vector by the given number.
40
+ * Multiplies the current vector by a scalar in place.
41
+ *
37
42
  * @param number - Number to multiply by
43
+ * @returns The current vector after scaling
38
44
  */
39
45
  multiplyNumber(number) {
40
46
  this.x *= number;
41
47
  this.y *= number;
48
+ return this;
42
49
  }
43
50
  /**
44
- * Checks if the current vector is equal to the given vector.
51
+ * Normalizes the current vector to unit length in place.
52
+ *
53
+ * If the vector magnitude is zero, it remains unchanged.
54
+ *
55
+ * @returns The current vector after normalization
56
+ */
57
+ normalize() {
58
+ const magnitude = this.magnitude;
59
+ if (magnitude === 0) {
60
+ return this;
61
+ }
62
+ this.multiplyNumber(1 / magnitude);
63
+ return this;
64
+ }
65
+ /**
66
+ * Checks whether another vector has the same coordinates.
67
+ *
45
68
  * @param vector - Vector to compare with
46
69
  * @returns True if the vectors are equal, false otherwise
47
70
  */
@@ -49,7 +72,8 @@ export class Vector2 {
49
72
  return this.x === vector.x && this.y === vector.y;
50
73
  }
51
74
  /**
52
- * Creates a new vector with the same x and y coordinates as the current vector.
75
+ * Creates a new vector with the same coordinates.
76
+ *
53
77
  * @returns A new vector with the same x and y coordinates
54
78
  */
55
79
  clone() {
@@ -10,7 +10,7 @@ export class TemplateCollection {
10
10
  this.storage = {};
11
11
  }
12
12
  buildTemplate(options) {
13
- const { id, name, components = [], children = [], } = options;
13
+ const { id, name, components = [], children = [] } = options;
14
14
  const template = new Template({ id, name });
15
15
  children.forEach((child) => {
16
16
  const childTemplate = this.buildTemplate(child);
@@ -4,19 +4,19 @@ import type { WorldEventMap, SceneEventMap, ActorEventMap } from '../../types/ev
4
4
  import { Entity } from '../entity';
5
5
  import type { EntityOptions } from '../entity';
6
6
  import type { EventType, Event, EventPayload } from '../event-target';
7
- import type { Constructor } from '../../types/utils';
7
+ import { SystemAPIRegistry } from './system-api-registry';
8
8
  type WorldListenerFn<T extends EventType> = (event: T extends keyof WorldEventMap ? WorldEventMap[T] : T extends keyof SceneEventMap ? SceneEventMap[T] : T extends keyof ActorEventMap ? ActorEventMap[T] : Event) => void;
9
9
  /**
10
10
  * A world is the root container for all scenes and actors.
11
- * It is used to contain the overall game state and provide system services.
11
+ * It is also provide an access to system APIs.
12
12
  *
13
13
  * @extends {Entity}
14
14
  *
15
15
  * @category Core
16
16
  */
17
17
  export declare class World extends Entity {
18
- /** Services registered in the world by systems */
19
- private services;
18
+ /** Registry of system APIs */
19
+ readonly systemApi: SystemAPIRegistry;
20
20
  readonly children: Scene[];
21
21
  /** Custom data storage for world-related information */
22
22
  data: Record<string, unknown>;
@@ -31,25 +31,5 @@ export declare class World extends Entity {
31
31
  findChild(predicate: (child: Scene | Actor) => boolean, recursive?: boolean): Scene | Actor | undefined;
32
32
  findChildById(id: string, recursive?: boolean): Scene | Actor | undefined;
33
33
  findChildByName(name: string, recursive?: boolean): Scene | Actor | undefined;
34
- /**
35
- * Adds a service to the world.
36
- * Usually added by systems to share their functionality with other systems or behaviors
37
- *
38
- * @param service - Service to add to the world
39
- */
40
- addService(service: object): void;
41
- /**
42
- * Removes a service from the world.
43
- *
44
- * @param serviceClass - Class of the service to remove
45
- */
46
- removeService<T>(serviceClass: Constructor<T>): void;
47
- /**
48
- * Gets a service from the world.
49
- *
50
- * @param serviceClass - Class of the service to get
51
- * @returns service
52
- */
53
- getService<T>(serviceClass: Constructor<T>): T;
54
34
  }
55
35
  export {};
@@ -1,21 +1,22 @@
1
1
  import { Entity } from '../entity';
2
+ import { SystemAPIRegistry } from './system-api-registry';
2
3
  /**
3
4
  * A world is the root container for all scenes and actors.
4
- * It is used to contain the overall game state and provide system services.
5
+ * It is also provide an access to system APIs.
5
6
  *
6
7
  * @extends {Entity}
7
8
  *
8
9
  * @category Core
9
10
  */
10
11
  export class World extends Entity {
11
- /** Services registered in the world by systems */
12
- services;
12
+ /** Registry of system APIs */
13
+ systemApi;
13
14
  /** Custom data storage for world-related information */
14
15
  data;
15
16
  constructor(options) {
16
17
  super(options);
18
+ this.systemApi = new SystemAPIRegistry();
17
19
  this.data = {};
18
- this.services = {};
19
20
  }
20
21
  addEventListener(type, callback) {
21
22
  super.addEventListener(type, callback);
@@ -44,33 +45,4 @@ export class World extends Entity {
44
45
  findChildByName(name, recursive = true) {
45
46
  return super.findChildByName(name, recursive);
46
47
  }
47
- /**
48
- * Adds a service to the world.
49
- * Usually added by systems to share their functionality with other systems or behaviors
50
- *
51
- * @param service - Service to add to the world
52
- */
53
- addService(service) {
54
- this.services[service.constructor.name] = service;
55
- }
56
- /**
57
- * Removes a service from the world.
58
- *
59
- * @param serviceClass - Class of the service to remove
60
- */
61
- removeService(serviceClass) {
62
- delete this.services[serviceClass.name];
63
- }
64
- /**
65
- * Gets a service from the world.
66
- *
67
- * @param serviceClass - Class of the service to get
68
- * @returns service
69
- */
70
- getService(serviceClass) {
71
- if (this.services[serviceClass.name] === undefined) {
72
- throw new Error(`Can't find service with the following name: ${serviceClass.name}`);
73
- }
74
- return this.services[serviceClass.name];
75
- }
76
48
  }
@@ -0,0 +1,17 @@
1
+ import type { Constructor } from '../../types/utils';
2
+ /**
3
+ * Registry for system-exposed APIs.
4
+ *
5
+ * APIs are stored by their class constructor as a key:
6
+ * `world.systemApi.get(PhysicsAPI)`.
7
+ *
8
+ * @category Core
9
+ */
10
+ export declare class SystemAPIRegistry {
11
+ private entries;
12
+ constructor();
13
+ register<T extends object>(api: T): void;
14
+ unregister<T>(apiClass: Constructor<T>): void;
15
+ get<T>(apiClass: Constructor<T>): T;
16
+ has<T>(apiClass: Constructor<T>): boolean;
17
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Registry for system-exposed APIs.
3
+ *
4
+ * APIs are stored by their class constructor as a key:
5
+ * `world.systemApi.get(PhysicsAPI)`.
6
+ *
7
+ * @category Core
8
+ */
9
+ export class SystemAPIRegistry {
10
+ entries;
11
+ constructor() {
12
+ this.entries = new Map();
13
+ }
14
+ register(api) {
15
+ const apiClass = api.constructor;
16
+ if (this.entries.has(apiClass)) {
17
+ throw new Error(`API already registered: ${apiClass.name}`);
18
+ }
19
+ this.entries.set(apiClass, api);
20
+ }
21
+ unregister(apiClass) {
22
+ this.entries.delete(apiClass);
23
+ }
24
+ get(apiClass) {
25
+ const api = this.entries.get(apiClass);
26
+ if (!api) {
27
+ throw new Error(`Can't find API with the following name: ${apiClass.name}`);
28
+ }
29
+ return api;
30
+ }
31
+ has(apiClass) {
32
+ return this.entries.has(apiClass);
33
+ }
34
+ }
@@ -1,4 +1,4 @@
1
1
  export { AddActor, RemoveActor, LoadScene, EnterScene, ExitScene, DestroyScene, SceneLoaded, SceneEntered, SceneExited, SceneDestroyed, } from '../engine/events';
2
2
  export type { AddActorEvent, RemoveActorEvent, LoadSceneEvent, EnterSceneEvent, ExitSceneEvent, DestroySceneEvent, SceneLoadedEvent, SceneEnteredEvent, SceneExitedEvent, SceneDestroyedEvent, } from '../engine/events';
3
- export { GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
4
- export type { GameStatsUpdateEvent, KeyboardInputEvent, MouseInputEvent, KeyboardControlEvent, MouseControlEvent, CollisionEnterEvent, CollisionStayEvent, CollisionLeaveEvent, AddForceEvent, AddImpulseEvent, SetAudioGroupVolumeEvent, SetAudioSourceVolumeEvent, } from '../contrib/events';
3
+ export { GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
4
+ export type { GameStatsUpdateEvent, KeyboardInputEvent, MouseInputEvent, KeyboardControlEvent, MouseControlEvent, CollisionEnterEvent, CollisionStayEvent, CollisionLeaveEvent, SetAudioGroupVolumeEvent, SetAudioSourceVolumeEvent, } from '../contrib/events';
@@ -1,2 +1,2 @@
1
1
  export { AddActor, RemoveActor, LoadScene, EnterScene, ExitScene, DestroyScene, SceneLoaded, SceneEntered, SceneExited, SceneDestroyed, } from '../engine/events';
2
- export { GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
2
+ export { GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
@@ -23,6 +23,10 @@ declare module 'pixi.js' {
23
23
  sortCenter: [number, number];
24
24
  };
25
25
  meta: Record<string, unknown>;
26
+ /**
27
+ * Flag to indicate if the view is fully initialized and ready (parent set and position updated)
28
+ */
29
+ isReady?: boolean;
26
30
  };
27
31
  }
28
32
  interface Filter {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacha",
3
- "version": "0.17.2",
3
+ "version": "0.18.0-alpha.1",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "exports": {
@@ -16,6 +16,9 @@
16
16
  },
17
17
  "./renderer": {
18
18
  "types": "./build/contrib/systems/renderer/types.d.ts"
19
+ },
20
+ "./physics": {
21
+ "types": "./build/contrib/systems/physics-system/types.d.ts"
19
22
  }
20
23
  },
21
24
  "dependencies": {
@@ -1,16 +0,0 @@
1
- import type { CollisionEntry, Intersection } from '../types';
2
- /**
3
- * Checks box and circle colliders at the intersection.
4
- * The main target is to check two possible scenarios:
5
- * - circle lies inside box
6
- * - circle intersects one of the boxe's edges
7
- * Steps of the algorithm:
8
- * 1. Find the nearest edge to circle center and check wether it intersects with circle or not
9
- * For each edge three points should be considered: corners and circle center projection
10
- * 2. Determine is the circle center lies inside of the box or not.
11
- * This affects how we should compute mtv distance
12
- * 3. If circle doesn't have any intersection with boxe's edges
13
- * and circle center lies outside of the box – return false.
14
- * Otherwise compute mtv vectors considering relative position of circle and box centers
15
- */
16
- export declare const checkBoxAndCircleIntersection: (arg1: CollisionEntry, arg2: CollisionEntry) => Intersection | false;