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.
- package/build/contrib/components/collider/index.d.ts +19 -0
- package/build/contrib/components/collider/index.js +29 -0
- package/build/contrib/components/index.d.ts +2 -2
- package/build/contrib/components/index.js +1 -1
- package/build/contrib/systems/audio-system/index.d.ts +2 -3
- package/build/contrib/systems/audio-system/index.js +17 -24
- package/build/contrib/systems/audio-system/utils.d.ts +3 -2
- package/build/contrib/systems/audio-system/utils.js +6 -6
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/index.js +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +3 -3
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.js +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +19 -19
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.js +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +6 -6
- package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.js +3 -5
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +1 -1
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +4 -4
- package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +1 -1
- package/build/contrib/systems/physics-system/subsystems/physics/index.js +5 -5
- package/build/contrib/systems/physics-system/types.d.ts +1 -1
- package/build/contrib/systems/sprite-renderer/renderer.d.ts +2 -3
- package/build/contrib/systems/sprite-renderer/renderer.js +18 -24
- package/build/contrib/systems/sprite-renderer/utils.d.ts +3 -2
- package/build/contrib/systems/sprite-renderer/utils.js +8 -8
- package/build/engine/scene/scene-manager.d.ts +1 -1
- package/build/engine/scene/scene-manager.js +41 -33
- package/build/engine/scene/tests/mocks/scene-config.mock.d.ts +2 -0
- package/build/engine/scene/tests/mocks/scene-config.mock.js +5 -0
- package/build/engine/scene/tests/mocks/system-config.mock.d.ts +2 -0
- package/build/engine/scene/tests/mocks/system-config.mock.js +4 -0
- package/build/engine/scene/tests/mocks/system.mock.d.ts +22 -0
- package/build/engine/scene/tests/mocks/system.mock.js +48 -0
- package/build/engine/system/index.d.ts +1 -1
- package/build/engine/utils/is-subclass-of.d.ts +1 -0
- package/build/engine/utils/is-subclass-of.js +10 -0
- package/build/index.d.ts +1 -1
- package/package.json +1 -1
- package/build/contrib/components/collider-container/box-collider.d.ts +0 -7
- package/build/contrib/components/collider-container/box-collider.js +0 -12
- package/build/contrib/components/collider-container/circle-collider.d.ts +0 -6
- package/build/contrib/components/collider-container/circle-collider.js +0 -10
- package/build/contrib/components/collider-container/index.d.ts +0 -13
- 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 {
|
|
6
|
-
export type {
|
|
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 {
|
|
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
|
|
11
|
+
private actorCollection?;
|
|
13
12
|
constructor(options: WorldSystemOptions);
|
|
14
13
|
onSceneLoad(scene: Scene): Promise<void>;
|
|
15
14
|
onSceneEnter(scene: Scene): void;
|
|
16
|
-
onSceneExit(
|
|
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 {
|
|
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
|
-
|
|
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
|
-
...
|
|
55
|
-
...
|
|
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.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
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(
|
|
71
|
+
onSceneExit() {
|
|
75
72
|
this.audioState.forEach((audioState) => {
|
|
76
73
|
audioState.sourceNode.stop();
|
|
77
74
|
});
|
|
78
|
-
this.
|
|
79
|
-
this.
|
|
80
|
-
this.
|
|
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
|
-
...
|
|
85
|
-
...
|
|
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
|
-
|
|
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 {
|
|
2
|
-
|
|
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
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
traverseEntity(
|
|
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
|
-
|
|
9
|
+
sources.push(audioSource.src);
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
});
|
|
13
|
-
return
|
|
13
|
+
return sources;
|
|
14
14
|
};
|
|
15
15
|
export const loadAudio = async (url) => {
|
|
16
16
|
const response = await fetch(url);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Collider, Transform } from '../../../../../components';
|
|
2
2
|
import type { BoxGeometry } from '../types';
|
|
3
|
-
export declare const buildBoxGeometry: (
|
|
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 = (
|
|
2
|
+
export const buildBoxGeometry = (collider, transform) => {
|
|
3
3
|
const { offsetX, offsetY, scaleX, scaleY, rotation, } = transform;
|
|
4
|
-
let { centerX, centerY } =
|
|
5
|
-
const { sizeX, sizeY } =
|
|
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 {
|
|
1
|
+
import type { Collider, Transform } from '../../../../../components';
|
|
2
2
|
import type { CircleGeometry } from '../types';
|
|
3
|
-
export declare const buildCircleGeometry: (
|
|
3
|
+
export declare const buildCircleGeometry: (collider: Collider, transform: Transform) => CircleGeometry;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export const buildCircleGeometry = (
|
|
1
|
+
export const buildCircleGeometry = (collider, transform) => {
|
|
2
2
|
const { offsetX, offsetY, scaleX, scaleY, } = transform;
|
|
3
|
-
const { centerX, centerY, radius } =
|
|
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 {
|
|
1
|
+
import type { Collider, Transform } from '../../../../../components';
|
|
2
2
|
import type { Geometry } from '../types';
|
|
3
|
-
export type BuildGeometryFn = (
|
|
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
|
-
|
|
5
|
-
|
|
4
|
+
box: buildBoxGeometry,
|
|
5
|
+
circle: buildCircleGeometry,
|
|
6
6
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActorCollection } from '../../../../../engine/actor';
|
|
2
|
-
import { Transform,
|
|
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
|
-
|
|
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
|
|
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(
|
|
62
|
+
return checkTransform(transform, transformOld) || checkCollider(collider, colliderOld);
|
|
63
63
|
}
|
|
64
64
|
getOrientationData(actor) {
|
|
65
65
|
const transform = actor.getComponent(Transform);
|
|
66
|
-
const
|
|
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:
|
|
77
|
-
centerX:
|
|
78
|
-
centerY:
|
|
79
|
-
sizeX:
|
|
80
|
-
sizeY:
|
|
81
|
-
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
|
|
88
|
-
const geometry = geometryBuilders[
|
|
89
|
-
const aabb = aabbBuilders[
|
|
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
|
|
105
|
-
const geometry = geometryBuilders[
|
|
106
|
-
const aabb = aabbBuilders[
|
|
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(
|
|
185
|
-
const type2 = arg2.actor.getComponent(
|
|
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 {
|
|
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(
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
box: {
|
|
6
|
+
box: checkBoxesIntersection,
|
|
7
|
+
circle: checkBoxAndCircleIntersection,
|
|
8
8
|
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
circle: {
|
|
10
|
+
circle: checkCirclesIntersection,
|
|
11
|
+
box: checkBoxAndCircleIntersection,
|
|
12
12
|
},
|
|
13
13
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Collider } from '../../../../../components';
|
|
2
2
|
import type { OrientationData } from '../types';
|
|
3
|
-
export declare const checkCollider: (
|
|
3
|
+
export declare const checkCollider: (collider: Collider, colliderOld: OrientationData['collider']) => boolean;
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export const checkCollider = (
|
|
2
|
-
if (
|
|
1
|
+
export const checkCollider = (collider, colliderOld) => {
|
|
2
|
+
if (collider.type !== colliderOld.type) {
|
|
3
3
|
return true;
|
|
4
4
|
}
|
|
5
|
-
if (
|
|
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
|
|
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
|
-
|
|
9
|
+
gravity;
|
|
10
10
|
constructor(options) {
|
|
11
|
-
const { scene,
|
|
11
|
+
const { scene, gravity } = options;
|
|
12
12
|
this.scene = scene;
|
|
13
|
-
this.
|
|
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.
|
|
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
|
|
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
|
-
|
|
16
|
+
gravity;
|
|
17
17
|
actorVectors;
|
|
18
18
|
constructor(options) {
|
|
19
|
-
const {
|
|
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.
|
|
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.
|
|
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.
|
|
97
|
+
gravityVector.multiplyNumber(mass * this.gravity);
|
|
98
98
|
}
|
|
99
99
|
return gravityVector;
|
|
100
100
|
}
|
|
@@ -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
|
|
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(
|
|
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,
|
|
17
|
+
import { loadImage, prepareSprite, getAllSources, getTextureMapKey, cloneTexture, } from './utils';
|
|
18
18
|
export class SpriteRenderer extends WorldSystem {
|
|
19
|
-
|
|
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
|
-
...
|
|
79
|
-
...
|
|
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.
|
|
88
|
+
this.actorCollection = new ActorCollection(scene, {
|
|
89
|
+
components: [Sprite, Transform],
|
|
90
|
+
});
|
|
94
91
|
this.handleWindowResize();
|
|
95
92
|
this.lightSubsystem.onSceneEnter(scene);
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
93
|
+
this.actorCollection.addEventListener(AddActor, this.handleActorAdd);
|
|
94
|
+
this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
|
|
98
95
|
}
|
|
99
|
-
onSceneExit(
|
|
100
|
-
this.
|
|
101
|
-
this.
|
|
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.
|
|
104
|
+
this.actorCollection = undefined;
|
|
108
105
|
}
|
|
109
106
|
onSceneDestroy(scene) {
|
|
110
107
|
const allSources = [
|
|
111
|
-
...
|
|
112
|
-
...
|
|
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.
|
|
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
|
-
|
|
249
|
-
|
|
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 {
|
|
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
|
|
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
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
traverseEntity(
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
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
|
|
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 (
|
|
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.
|
|
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((
|
|
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.
|
|
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
|
|
107
|
-
if (
|
|
108
|
-
acc.push(
|
|
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.
|
|
129
|
+
const sceneSystems = this.systemConfigs.reduce((acc, config) => {
|
|
126
130
|
const SystemClass = this.availableSystems[config.name];
|
|
127
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
150
|
-
if (!
|
|
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
|
|
174
|
-
if (!
|
|
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,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;
|
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,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';
|