dacha 0.14.4 → 0.15.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.
- package/build/contrib/components/behaviors/index.d.ts +14 -0
- package/build/contrib/components/behaviors/index.js +15 -0
- package/build/contrib/components/index.d.ts +2 -2
- package/build/contrib/components/index.js +1 -1
- package/build/contrib/events/index.d.ts +12 -15
- package/build/contrib/events/index.js +0 -1
- package/build/contrib/systems/animator/condition-controllers/condition-controller.d.ts +1 -0
- package/build/contrib/systems/animator/condition-controllers/event-condition-controller.d.ts +4 -0
- package/build/contrib/systems/animator/condition-controllers/event-condition-controller.js +15 -9
- package/build/contrib/systems/animator/index.d.ts +5 -6
- package/build/contrib/systems/animator/index.js +10 -5
- package/build/contrib/systems/audio-system/index.d.ts +14 -10
- package/build/contrib/systems/audio-system/index.js +85 -51
- package/build/contrib/systems/audio-system/utils.d.ts +3 -0
- package/build/contrib/systems/audio-system/utils.js +19 -0
- package/build/contrib/systems/behavior-system/index.d.ts +3 -0
- package/build/contrib/systems/behavior-system/index.js +2 -0
- package/build/contrib/systems/behavior-system/system.d.ts +16 -0
- package/build/contrib/systems/behavior-system/system.js +69 -0
- package/build/contrib/systems/{script-system → behavior-system}/types.d.ts +7 -5
- package/build/contrib/systems/behavior-system/types.js +3 -0
- package/build/contrib/systems/camera-system/service.d.ts +5 -5
- package/build/contrib/systems/camera-system/service.js +5 -12
- package/build/contrib/systems/camera-system/system.d.ts +11 -12
- package/build/contrib/systems/camera-system/system.js +31 -34
- package/build/contrib/systems/game-stats-meter/index.d.ts +9 -6
- package/build/contrib/systems/game-stats-meter/index.js +13 -8
- package/build/contrib/systems/index.d.ts +4 -4
- package/build/contrib/systems/index.js +2 -2
- package/build/contrib/systems/keyboard-control-system/index.d.ts +10 -8
- package/build/contrib/systems/keyboard-control-system/index.js +15 -14
- package/build/contrib/systems/keyboard-input-system/index.d.ts +6 -7
- package/build/contrib/systems/keyboard-input-system/index.js +7 -9
- package/build/contrib/systems/mouse-control-system/index.d.ts +10 -8
- package/build/contrib/systems/mouse-control-system/index.js +14 -13
- package/build/contrib/systems/mouse-input-system/index.d.ts +5 -6
- package/build/contrib/systems/mouse-input-system/index.js +5 -9
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.d.ts +4 -5
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.js +7 -9
- package/build/contrib/systems/mouse-input-system/subsystems/input-subsystem/index.d.ts +4 -5
- package/build/contrib/systems/mouse-input-system/subsystems/input-subsystem/index.js +5 -7
- package/build/contrib/systems/physics-system/index.d.ts +5 -6
- package/build/contrib/systems/physics-system/index.js +8 -15
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.d.ts +3 -4
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.js +1 -3
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +3 -4
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +1 -3
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +3 -4
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +1 -3
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +3 -4
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +1 -3
- package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +3 -4
- package/build/contrib/systems/physics-system/subsystems/physics/index.js +1 -3
- package/build/contrib/systems/physics-system/types.d.ts +2 -2
- package/build/contrib/systems/sprite-renderer/light-subsystem/index.d.ts +7 -7
- package/build/contrib/systems/sprite-renderer/light-subsystem/index.js +28 -17
- package/build/contrib/systems/sprite-renderer/renderer.d.ts +16 -12
- package/build/contrib/systems/sprite-renderer/renderer.js +127 -93
- package/build/contrib/systems/sprite-renderer/sprite-cropper.js +1 -1
- package/build/contrib/systems/sprite-renderer/utils.d.ts +4 -4
- package/build/contrib/systems/sprite-renderer/utils.js +13 -7
- package/build/contrib/systems/ui-bridge/index.d.ts +21 -33
- package/build/contrib/systems/ui-bridge/index.js +26 -51
- package/build/engine/actor/actor.d.ts +3 -2
- package/build/engine/actor/actor.js +7 -4
- package/build/engine/data-lib/cache-store.d.ts +11 -0
- package/build/engine/data-lib/cache-store.js +40 -0
- package/build/engine/data-lib/index.d.ts +1 -0
- package/build/engine/data-lib/index.js +1 -0
- package/build/engine/engine.d.ts +1 -1
- package/build/engine/engine.js +19 -33
- package/build/engine/entity/entity.d.ts +3 -2
- package/build/engine/entity/entity.js +8 -5
- package/build/engine/entity/index.d.ts +1 -1
- package/build/engine/entity/index.js +1 -1
- package/build/engine/entity/utils.d.ts +1 -1
- package/build/engine/entity/utils.js +7 -8
- package/build/engine/events/index.d.ts +46 -7
- package/build/engine/events/index.js +7 -1
- package/build/engine/game-loop.d.ts +3 -5
- package/build/engine/game-loop.js +6 -11
- package/build/engine/scene/index.d.ts +1 -2
- package/build/engine/scene/index.js +1 -1
- package/build/engine/scene/scene-manager.d.ts +43 -0
- package/build/engine/scene/scene-manager.js +190 -0
- package/build/engine/scene/scene.d.ts +5 -20
- package/build/engine/scene/scene.js +7 -59
- package/build/engine/system/index.d.ts +2 -2
- package/build/engine/system/index.js +1 -1
- package/build/engine/system/system.d.ts +21 -5
- package/build/engine/system/system.js +4 -0
- package/build/engine/template/template.d.ts +3 -2
- package/build/engine/template/template.js +7 -4
- package/build/engine/types/config.d.ts +2 -10
- package/build/engine/world/index.d.ts +28 -0
- package/build/engine/world/index.js +49 -0
- package/build/events/index.d.ts +4 -4
- package/build/events/index.js +2 -2
- package/build/index.d.ts +3 -2
- package/build/index.js +1 -1
- package/build/types/events.d.ts +4 -0
- package/package.json +1 -1
- package/build/contrib/components/script-bundle/index.d.ts +0 -14
- package/build/contrib/components/script-bundle/index.js +0 -15
- package/build/contrib/systems/audio-system/audio-loader.d.ts +0 -7
- package/build/contrib/systems/audio-system/audio-loader.js +0 -16
- package/build/contrib/systems/script-system/index.d.ts +0 -19
- package/build/contrib/systems/script-system/index.js +0 -71
- package/build/contrib/systems/script-system/types.js +0 -3
- package/build/contrib/systems/ui-bridge/observer/index.d.ts +0 -1
- package/build/contrib/systems/ui-bridge/observer/index.js +0 -1
- package/build/contrib/systems/ui-bridge/observer/observer.d.ts +0 -8
- package/build/contrib/systems/ui-bridge/observer/observer.js +0 -21
- package/build/contrib/systems/webgl-render-system/color/color-reader/color-reader.d.ts +0 -3
- package/build/contrib/systems/webgl-render-system/color/color-reader/color-reader.js +0 -1
- package/build/contrib/systems/webgl-render-system/color/color-reader/consts.d.ts +0 -3
- package/build/contrib/systems/webgl-render-system/color/color-reader/consts.js +0 -10
- package/build/contrib/systems/webgl-render-system/color/color-reader/hex-color-reader.d.ts +0 -4
- package/build/contrib/systems/webgl-render-system/color/color-reader/hex-color-reader.js +0 -14
- package/build/contrib/systems/webgl-render-system/color/color-reader/index.d.ts +0 -6
- package/build/contrib/systems/webgl-render-system/color/color-reader/index.js +0 -6
- package/build/contrib/systems/webgl-render-system/color/color-reader/short-hex-color-reader.d.ts +0 -4
- package/build/contrib/systems/webgl-render-system/color/color-reader/short-hex-color-reader.js +0 -11
- package/build/contrib/systems/webgl-render-system/color/index.d.ts +0 -7
- package/build/contrib/systems/webgl-render-system/color/index.js +0 -41
- package/build/contrib/systems/webgl-render-system/consts.d.ts +0 -9
- package/build/contrib/systems/webgl-render-system/consts.js +0 -9
- package/build/contrib/systems/webgl-render-system/geometry/rectangle.d.ts +0 -6
- package/build/contrib/systems/webgl-render-system/geometry/rectangle.js +0 -22
- package/build/contrib/systems/webgl-render-system/index.d.ts +0 -66
- package/build/contrib/systems/webgl-render-system/index.js +0 -405
- package/build/contrib/systems/webgl-render-system/matrix-transformer/index.d.ts +0 -20
- package/build/contrib/systems/webgl-render-system/matrix-transformer/index.js +0 -55
- package/build/contrib/systems/webgl-render-system/shader-builder/fragment-shader.d.ts +0 -1
- package/build/contrib/systems/webgl-render-system/shader-builder/fragment-shader.js +0 -29
- package/build/contrib/systems/webgl-render-system/shader-builder/index.d.ts +0 -11
- package/build/contrib/systems/webgl-render-system/shader-builder/index.js +0 -39
- package/build/contrib/systems/webgl-render-system/shader-builder/shader-provider.d.ts +0 -10
- package/build/contrib/systems/webgl-render-system/shader-builder/shader-provider.js +0 -34
- package/build/contrib/systems/webgl-render-system/shader-builder/vertex-shader.d.ts +0 -1
- package/build/contrib/systems/webgl-render-system/shader-builder/vertex-shader.js +0 -16
- package/build/contrib/systems/webgl-render-system/texture-handlers/index.d.ts +0 -7
- package/build/contrib/systems/webgl-render-system/texture-handlers/index.js +0 -6
- package/build/contrib/systems/webgl-render-system/texture-handlers/sprite-texture-handler.d.ts +0 -10
- package/build/contrib/systems/webgl-render-system/texture-handlers/sprite-texture-handler.js +0 -16
- package/build/contrib/systems/webgl-render-system/texture-handlers/static-texture-handler.d.ts +0 -9
- package/build/contrib/systems/webgl-render-system/texture-handlers/static-texture-handler.js +0 -10
- package/build/contrib/systems/webgl-render-system/texture-handlers/texture-handler.d.ts +0 -10
- package/build/contrib/systems/webgl-render-system/texture-handlers/texture-handler.js +0 -1
- package/build/contrib/systems/webgl-render-system/utils/index.d.ts +0 -1
- package/build/contrib/systems/webgl-render-system/utils/index.js +0 -1
- package/build/contrib/systems/webgl-render-system/utils/split-to-batch.d.ts +0 -3
- package/build/contrib/systems/webgl-render-system/utils/split-to-batch.js +0 -19
- package/build/engine/controllers/controller.d.ts +0 -7
- package/build/engine/controllers/controller.js +0 -1
- package/build/engine/controllers/index.d.ts +0 -2
- package/build/engine/controllers/index.js +0 -1
- package/build/engine/controllers/scene-controller.d.ts +0 -11
- package/build/engine/controllers/scene-controller.js +0 -50
- package/build/engine/scene/scene-provider.d.ts +0 -50
- package/build/engine/scene/scene-provider.js +0 -148
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Component } from '../../../engine/component';
|
|
2
|
+
interface BehaviorConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
options: Record<string, unknown>;
|
|
5
|
+
}
|
|
6
|
+
export interface BehaviorsConfig {
|
|
7
|
+
list: BehaviorConfig[];
|
|
8
|
+
}
|
|
9
|
+
export declare class Behaviors extends Component {
|
|
10
|
+
list: BehaviorConfig[];
|
|
11
|
+
constructor(config: BehaviorsConfig);
|
|
12
|
+
clone(): Behaviors;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Component } from '../../../engine/component';
|
|
2
|
+
export class Behaviors extends Component {
|
|
3
|
+
list;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
super();
|
|
6
|
+
const { list } = config;
|
|
7
|
+
this.list = list;
|
|
8
|
+
}
|
|
9
|
+
clone() {
|
|
10
|
+
return new Behaviors({
|
|
11
|
+
list: this.list.map(({ name, options }) => ({ name, options: { ...options } })),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
Behaviors.componentName = 'Behaviors';
|
|
@@ -14,8 +14,8 @@ export { Transform } from './transform';
|
|
|
14
14
|
export type { TransformConfig } from './transform';
|
|
15
15
|
export { MouseControl } from './mouse-control';
|
|
16
16
|
export type { MouseControlConfig } from './mouse-control';
|
|
17
|
-
export {
|
|
18
|
-
export type {
|
|
17
|
+
export { Behaviors } from './behaviors';
|
|
18
|
+
export type { BehaviorsConfig } from './behaviors';
|
|
19
19
|
export { Light } from './light';
|
|
20
20
|
export type { LightConfig } from './light';
|
|
21
21
|
export { AudioSource } from './audio-source';
|
|
@@ -6,6 +6,6 @@ export { Animatable } from './animatable';
|
|
|
6
6
|
export { Sprite } from './sprite';
|
|
7
7
|
export { Transform } from './transform';
|
|
8
8
|
export { MouseControl } from './mouse-control';
|
|
9
|
-
export {
|
|
9
|
+
export { Behaviors } from './behaviors';
|
|
10
10
|
export { Light } from './light';
|
|
11
11
|
export { AudioSource } from './audio-source';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Actor } from '../../engine/actor';
|
|
2
2
|
import type { Vector2 } from '../../engine/math-lib';
|
|
3
3
|
import type { CustomMouseEvent, CustomKeyboardEvent } from '../types/input-events';
|
|
4
|
-
import type { ActorEvent, SceneEvent } from '../../types/events';
|
|
5
|
-
export declare const SetCamera = "SetCamera";
|
|
4
|
+
import type { ActorEvent, SceneEvent, WorldEvent } from '../../types/events';
|
|
6
5
|
export declare const GameStatsUpdate = "GameStatsUpdate";
|
|
7
6
|
export declare const Collision = "Collision";
|
|
8
7
|
export declare const KeyboardInput = "KeyboardInput";
|
|
@@ -16,25 +15,22 @@ export declare const StopMovement = "StopMovement";
|
|
|
16
15
|
export declare const PlayAudio = "PlayAudio";
|
|
17
16
|
export declare const StopAudio = "StopAudio";
|
|
18
17
|
export declare const SetAudioVolume = "SetAudioVolume";
|
|
19
|
-
export type MouseInputEvent =
|
|
20
|
-
export type KeyboardInputEvent =
|
|
21
|
-
export type
|
|
22
|
-
actorId: string;
|
|
23
|
-
}>;
|
|
24
|
-
export type GameStatsUpdateEvent = SceneEvent<{
|
|
18
|
+
export type MouseInputEvent = WorldEvent<CustomMouseEvent>;
|
|
19
|
+
export type KeyboardInputEvent = WorldEvent<CustomKeyboardEvent>;
|
|
20
|
+
export type GameStatsUpdateEvent = WorldEvent<{
|
|
25
21
|
fps: number;
|
|
26
22
|
actorsCount: number;
|
|
27
23
|
}>;
|
|
24
|
+
export type SetAudioGroupVolumeEvent = WorldEvent<{
|
|
25
|
+
group: string;
|
|
26
|
+
value: number;
|
|
27
|
+
}>;
|
|
28
28
|
export type CollisionEvent = SceneEvent<{
|
|
29
29
|
actor1: Actor;
|
|
30
30
|
actor2: Actor;
|
|
31
31
|
mtv1: Vector2;
|
|
32
32
|
mtv2: Vector2;
|
|
33
33
|
}>;
|
|
34
|
-
export type SetAudioGroupVolumeEvent = SceneEvent<{
|
|
35
|
-
group: string;
|
|
36
|
-
value: number;
|
|
37
|
-
}>;
|
|
38
34
|
export type MouseControlEvent<T = Record<string, never>> = ActorEvent<Pick<CustomMouseEvent, 'x' | 'y' | 'screenX' | 'screenY' | 'nativeEvent'>> & T;
|
|
39
35
|
export type KeyboardControlEvent<T = Record<string, never>> = ActorEvent<T>;
|
|
40
36
|
type CollisionStateEvent = ActorEvent<{
|
|
@@ -54,14 +50,15 @@ export type SetAudioSourceVolumeEvent = ActorEvent<{
|
|
|
54
50
|
value: number;
|
|
55
51
|
}>;
|
|
56
52
|
declare module '../../types/events' {
|
|
57
|
-
interface
|
|
53
|
+
interface WorldEventMap {
|
|
58
54
|
[MouseInput]: MouseInputEvent;
|
|
59
55
|
[KeyboardInput]: KeyboardInputEvent;
|
|
60
|
-
[SetCamera]: SetCameraEvent;
|
|
61
56
|
[GameStatsUpdate]: GameStatsUpdateEvent;
|
|
62
|
-
[Collision]: CollisionEvent;
|
|
63
57
|
[SetAudioVolume]: SetAudioGroupVolumeEvent;
|
|
64
58
|
}
|
|
59
|
+
interface SceneEventMap {
|
|
60
|
+
[Collision]: CollisionEvent;
|
|
61
|
+
}
|
|
65
62
|
interface ActorEventMap {
|
|
66
63
|
[CollisionEnter]: CollisionEnterEvent;
|
|
67
64
|
[CollisionStay]: CollisionStayEvent;
|
package/build/contrib/systems/animator/condition-controllers/event-condition-controller.d.ts
CHANGED
|
@@ -2,7 +2,11 @@ import type { Actor } from '../../../../engine/actor';
|
|
|
2
2
|
import type { EventConditionProps } from '../../../components/animatable/event-condition-props';
|
|
3
3
|
import { ConditionController } from './condition-controller';
|
|
4
4
|
export declare class EventConditionController implements ConditionController {
|
|
5
|
+
private actor;
|
|
6
|
+
private eventType;
|
|
5
7
|
private isEventFired;
|
|
6
8
|
constructor(props: EventConditionProps, actor: Actor);
|
|
9
|
+
destroy(): void;
|
|
10
|
+
private handleEvent;
|
|
7
11
|
check(): boolean;
|
|
8
12
|
}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
export class EventConditionController {
|
|
2
|
+
actor;
|
|
3
|
+
eventType;
|
|
2
4
|
isEventFired;
|
|
3
5
|
constructor(props, actor) {
|
|
6
|
+
this.actor = actor;
|
|
7
|
+
this.eventType = props.eventType;
|
|
4
8
|
this.isEventFired = false;
|
|
5
|
-
|
|
6
|
-
const handleEvent = (event) => {
|
|
7
|
-
if (event.target !== actor) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
this.isEventFired = true;
|
|
11
|
-
actor.removeEventListener(eventType, handleEvent);
|
|
12
|
-
};
|
|
13
|
-
actor.addEventListener(eventType, handleEvent);
|
|
9
|
+
this.actor.addEventListener(this.eventType, this.handleEvent);
|
|
14
10
|
}
|
|
11
|
+
destroy() {
|
|
12
|
+
this.actor.removeEventListener(this.eventType, this.handleEvent);
|
|
13
|
+
}
|
|
14
|
+
handleEvent = (event) => {
|
|
15
|
+
if (event.target !== this.actor) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.isEventFired = true;
|
|
19
|
+
this.actor.removeEventListener(this.eventType, this.handleEvent);
|
|
20
|
+
};
|
|
15
21
|
check() {
|
|
16
22
|
return this.isEventFired;
|
|
17
23
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
export declare class Animator extends
|
|
1
|
+
import { SceneSystem } from '../../../engine/system';
|
|
2
|
+
import type { UpdateOptions, SceneSystemOptions } from '../../../engine/system';
|
|
3
|
+
export declare class Animator extends SceneSystem {
|
|
4
4
|
private actorCollection;
|
|
5
5
|
private substatePickers;
|
|
6
6
|
private actorConditions;
|
|
7
|
-
constructor(options:
|
|
8
|
-
|
|
9
|
-
unmount(): void;
|
|
7
|
+
constructor(options: SceneSystemOptions);
|
|
8
|
+
onSceneDestroy(): void;
|
|
10
9
|
private handleActorRemove;
|
|
11
10
|
private setUpConditionControllers;
|
|
12
11
|
private updateFrame;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SceneSystem } from '../../../engine/system';
|
|
2
2
|
import { ActorCollection } from '../../../engine/actor';
|
|
3
3
|
import { Animatable } from '../../components/animatable';
|
|
4
4
|
import { RemoveActor } from '../../../engine/events';
|
|
@@ -6,7 +6,7 @@ import { conditionControllers } from './condition-controllers';
|
|
|
6
6
|
import { substatePickers } from './substate-pickers';
|
|
7
7
|
import { setValue } from './utils';
|
|
8
8
|
const FRAME_RATE = 100;
|
|
9
|
-
export class Animator extends
|
|
9
|
+
export class Animator extends SceneSystem {
|
|
10
10
|
actorCollection;
|
|
11
11
|
substatePickers;
|
|
12
12
|
actorConditions;
|
|
@@ -22,12 +22,17 @@ export class Animator extends System {
|
|
|
22
22
|
return storage;
|
|
23
23
|
}, {});
|
|
24
24
|
this.actorConditions = {};
|
|
25
|
-
}
|
|
26
|
-
mount() {
|
|
27
25
|
this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
|
|
28
26
|
}
|
|
29
|
-
|
|
27
|
+
onSceneDestroy() {
|
|
30
28
|
this.actorCollection.removeEventListener(RemoveActor, this.handleActorRemove);
|
|
29
|
+
Object.values(this.actorConditions).forEach((transitions) => {
|
|
30
|
+
Object.values(transitions).forEach((conditions) => {
|
|
31
|
+
Object.values(conditions).forEach((controller) => {
|
|
32
|
+
controller.destroy?.();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
31
36
|
}
|
|
32
37
|
handleActorRemove = (event) => {
|
|
33
38
|
delete this.actorConditions[event.actor.id];
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
1
|
+
import { WorldSystem } from '../../../engine/system';
|
|
2
|
+
import type { Scene } from '../../../engine/scene';
|
|
3
|
+
import type { WorldSystemOptions } from '../../../engine/system';
|
|
4
|
+
export declare class AudioSystem extends WorldSystem {
|
|
4
5
|
private templateCollection;
|
|
5
|
-
private
|
|
6
|
-
private scene
|
|
6
|
+
private world;
|
|
7
|
+
private scene?;
|
|
7
8
|
private audioContext;
|
|
8
9
|
private audioGroups;
|
|
9
|
-
private
|
|
10
|
+
private audioStore;
|
|
10
11
|
private audioState;
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
private actorCollections;
|
|
13
|
+
constructor(options: WorldSystemOptions);
|
|
14
|
+
onSceneLoad(scene: Scene): Promise<void>;
|
|
15
|
+
onSceneEnter(scene: Scene): void;
|
|
16
|
+
onSceneExit(scene: Scene): void;
|
|
17
|
+
onSceneDestroy(scene: Scene): void;
|
|
18
|
+
onWorldDestroy(): void;
|
|
13
19
|
private loadAudio;
|
|
14
|
-
mount(): void;
|
|
15
|
-
unmount(): void;
|
|
16
20
|
private handleActorAdd;
|
|
17
21
|
private handleActorRemove;
|
|
18
22
|
private handlePlayAudio;
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WorldSystem } from '../../../engine/system';
|
|
2
2
|
import { Actor, ActorCollection } from '../../../engine/actor';
|
|
3
3
|
import { AddActor, RemoveActor } from '../../../engine/events';
|
|
4
|
+
import { CacheStore } from '../../../engine/data-lib';
|
|
4
5
|
import { AudioSource } from '../../components';
|
|
5
6
|
import { PlayAudio, StopAudio, SetAudioVolume, } from '../../../events';
|
|
6
|
-
import {
|
|
7
|
+
import { getAllTemplateSources, loadAudio } from './utils';
|
|
7
8
|
const MASTER_GROUP = 'master';
|
|
8
9
|
const VOLUME_TOLERANCE = 0.001;
|
|
9
|
-
export class AudioSystem extends
|
|
10
|
+
export class AudioSystem extends WorldSystem {
|
|
10
11
|
templateCollection;
|
|
11
|
-
|
|
12
|
+
world;
|
|
12
13
|
scene;
|
|
13
14
|
audioContext;
|
|
14
15
|
audioGroups;
|
|
15
|
-
|
|
16
|
+
audioStore;
|
|
16
17
|
audioState;
|
|
18
|
+
actorCollections;
|
|
17
19
|
constructor(options) {
|
|
18
20
|
super();
|
|
19
|
-
const {
|
|
21
|
+
const { world, globalOptions, templateCollection } = options;
|
|
20
22
|
this.templateCollection = templateCollection;
|
|
21
|
-
this.
|
|
22
|
-
components: [AudioSource],
|
|
23
|
-
});
|
|
24
|
-
this.scene = scene;
|
|
23
|
+
this.world = world;
|
|
25
24
|
this.audioContext = new AudioContext();
|
|
26
25
|
const masterAudioGroup = new GainNode(this.audioContext);
|
|
27
26
|
masterAudioGroup.connect(this.audioContext.destination);
|
|
@@ -37,60 +36,92 @@ export class AudioSystem extends System {
|
|
|
37
36
|
acc[groupSettings.name] = gainNode;
|
|
38
37
|
return acc;
|
|
39
38
|
}, { [MASTER_GROUP]: masterAudioGroup });
|
|
40
|
-
this.
|
|
39
|
+
this.audioStore = new CacheStore();
|
|
41
40
|
this.audioState = new Map();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.map((template) => template.getComponent(AudioSource).src);
|
|
47
|
-
const sources = this.actorCollection.map((actor) => actor.getComponent(AudioSource).src);
|
|
48
|
-
const uniqueSources = [...new Set([...templateSources, ...sources])];
|
|
49
|
-
await Promise.all(uniqueSources.map((src) => this.loadAudio(src)));
|
|
50
|
-
}
|
|
51
|
-
async loadAudio(audioSourcePath) {
|
|
52
|
-
if (this.audioCache.has(audioSourcePath)) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const arrayBuffer = await audioLoader.load(audioSourcePath);
|
|
57
|
-
const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
|
|
58
|
-
this.audioCache.set(audioSourcePath, audioBuffer);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
console.error(`An error occurred during audio source loading: ${audioSourcePath}`, error);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
mount() {
|
|
65
|
-
this.actorCollection.forEach((actor) => this.initAudio(actor));
|
|
66
|
-
this.actorCollection.addEventListener(AddActor, this.handleActorAdd);
|
|
67
|
-
this.actorCollection.addEventListener(RemoveActor, this.handleActorRemove);
|
|
68
|
-
this.scene.addEventListener(PlayAudio, this.handlePlayAudio);
|
|
69
|
-
this.scene.addEventListener(StopAudio, this.handleStopAudio);
|
|
70
|
-
this.scene.addEventListener(SetAudioVolume, this.handleSetAudioVolume);
|
|
41
|
+
this.actorCollections = {};
|
|
42
|
+
this.world.addEventListener(PlayAudio, this.handlePlayAudio);
|
|
43
|
+
this.world.addEventListener(StopAudio, this.handleStopAudio);
|
|
44
|
+
this.world.addEventListener(SetAudioVolume, this.handleSetAudioVolume);
|
|
71
45
|
window.addEventListener('click', this.resumeIfSuspended, { once: true });
|
|
72
46
|
window.addEventListener('keydown', this.resumeIfSuspended, { once: true });
|
|
73
47
|
window.addEventListener('touchstart', this.resumeIfSuspended, { once: true });
|
|
74
48
|
}
|
|
75
|
-
|
|
49
|
+
async onSceneLoad(scene) {
|
|
50
|
+
this.actorCollections[scene.id] = new ActorCollection(scene, {
|
|
51
|
+
components: [AudioSource],
|
|
52
|
+
});
|
|
53
|
+
const allSources = [
|
|
54
|
+
...getAllTemplateSources(this.templateCollection),
|
|
55
|
+
...this.actorCollections[scene.id].map((actor) => actor.getComponent(AudioSource).src),
|
|
56
|
+
];
|
|
57
|
+
const uniqueSources = [...new Set(allSources)];
|
|
58
|
+
const audioBuffers = await Promise.all(uniqueSources.map((src) => {
|
|
59
|
+
return !this.audioStore.has(src) ? this.loadAudio(src) : undefined;
|
|
60
|
+
}));
|
|
61
|
+
uniqueSources.forEach((src, index) => {
|
|
62
|
+
if (audioBuffers[index]) {
|
|
63
|
+
this.audioStore.add(src, audioBuffers[index]);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
allSources.forEach((src) => this.audioStore.retain(src));
|
|
67
|
+
}
|
|
68
|
+
onSceneEnter(scene) {
|
|
69
|
+
this.scene = scene;
|
|
70
|
+
this.actorCollections[scene.id]?.forEach((actor) => this.initAudio(actor));
|
|
71
|
+
this.actorCollections[scene.id]?.addEventListener(AddActor, this.handleActorAdd);
|
|
72
|
+
this.actorCollections[scene.id]?.addEventListener(RemoveActor, this.handleActorRemove);
|
|
73
|
+
}
|
|
74
|
+
onSceneExit(scene) {
|
|
76
75
|
this.audioState.forEach((audioState) => {
|
|
77
76
|
audioState.sourceNode.stop();
|
|
78
77
|
});
|
|
78
|
+
this.actorCollections[scene.id]?.removeEventListener(AddActor, this.handleActorAdd);
|
|
79
|
+
this.actorCollections[scene.id]?.removeEventListener(RemoveActor, this.handleActorRemove);
|
|
80
|
+
this.scene = undefined;
|
|
81
|
+
}
|
|
82
|
+
onSceneDestroy(scene) {
|
|
83
|
+
const allSources = [
|
|
84
|
+
...getAllTemplateSources(this.templateCollection),
|
|
85
|
+
...this.actorCollections[scene.id].map((actor) => actor.getComponent(AudioSource).src),
|
|
86
|
+
];
|
|
87
|
+
allSources.forEach((src) => this.audioStore.release(src));
|
|
88
|
+
this.audioStore.cleanReleased();
|
|
89
|
+
delete this.actorCollections[scene.id];
|
|
90
|
+
}
|
|
91
|
+
onWorldDestroy() {
|
|
79
92
|
void this.audioContext.close();
|
|
80
|
-
this.
|
|
81
|
-
this.
|
|
82
|
-
this.
|
|
83
|
-
this.scene.removeEventListener(StopAudio, this.handleStopAudio);
|
|
84
|
-
this.scene.removeEventListener(SetAudioVolume, this.handleSetAudioVolume);
|
|
93
|
+
this.world.removeEventListener(PlayAudio, this.handlePlayAudio);
|
|
94
|
+
this.world.removeEventListener(StopAudio, this.handleStopAudio);
|
|
95
|
+
this.world.removeEventListener(SetAudioVolume, this.handleSetAudioVolume);
|
|
85
96
|
window.removeEventListener('click', this.resumeIfSuspended);
|
|
86
97
|
window.removeEventListener('keydown', this.resumeIfSuspended);
|
|
87
98
|
window.removeEventListener('touchstart', this.resumeIfSuspended);
|
|
88
99
|
}
|
|
100
|
+
async loadAudio(src) {
|
|
101
|
+
if (!src) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const arrayBuffer = await loadAudio(src);
|
|
106
|
+
const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
|
|
107
|
+
return audioBuffer;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error(`An error occurred during audio source loading: ${src}`, error);
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
89
114
|
handleActorAdd = (event) => {
|
|
90
|
-
|
|
115
|
+
const { actor } = event;
|
|
116
|
+
const { src } = actor.getComponent(AudioSource);
|
|
117
|
+
this.audioStore.retain(src);
|
|
118
|
+
this.initAudio(actor);
|
|
91
119
|
};
|
|
92
120
|
handleActorRemove = (event) => {
|
|
93
|
-
|
|
121
|
+
const { actor } = event;
|
|
122
|
+
const { src } = actor.getComponent(AudioSource);
|
|
123
|
+
this.audioStore.release(src);
|
|
124
|
+
this.stopAudio(actor);
|
|
94
125
|
};
|
|
95
126
|
handlePlayAudio = (event) => {
|
|
96
127
|
this.playAudio(event.target);
|
|
@@ -136,7 +167,7 @@ export class AudioSystem extends System {
|
|
|
136
167
|
}
|
|
137
168
|
const { src, group, volume, looped, playing, } = audioSource;
|
|
138
169
|
const audioGroupNode = this.audioGroups[group];
|
|
139
|
-
if (!audioGroupNode || !this.
|
|
170
|
+
if (!audioGroupNode || !this.audioStore.has(src)) {
|
|
140
171
|
return;
|
|
141
172
|
}
|
|
142
173
|
if (playing && this.audioState.has(actor.id)) {
|
|
@@ -146,7 +177,7 @@ export class AudioSystem extends System {
|
|
|
146
177
|
prevAudio.gainNode.disconnect();
|
|
147
178
|
}
|
|
148
179
|
const sourceNode = new AudioBufferSourceNode(this.audioContext, {
|
|
149
|
-
buffer: this.
|
|
180
|
+
buffer: this.audioStore.get(src),
|
|
150
181
|
loop: looped,
|
|
151
182
|
});
|
|
152
183
|
const gainNode = new GainNode(this.audioContext, {
|
|
@@ -184,7 +215,10 @@ export class AudioSystem extends System {
|
|
|
184
215
|
}
|
|
185
216
|
}
|
|
186
217
|
update() {
|
|
187
|
-
this.
|
|
218
|
+
if (!this.scene) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
this.actorCollections[this.scene.id]?.forEach((actor) => {
|
|
188
222
|
const audioSource = actor.getComponent(AudioSource);
|
|
189
223
|
const audioState = this.audioState.get(actor.id);
|
|
190
224
|
if (audioSource.playing && audioState) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AudioSource } from '../../components';
|
|
2
|
+
import { traverseEntity } from '../../../engine/entity';
|
|
3
|
+
export const getAllTemplateSources = (templateCollection) => {
|
|
4
|
+
const templateSources = [];
|
|
5
|
+
templateCollection.getAll().forEach((template) => {
|
|
6
|
+
traverseEntity(template, (entity) => {
|
|
7
|
+
const audioSource = entity.getComponent(AudioSource);
|
|
8
|
+
if (audioSource?.src) {
|
|
9
|
+
templateSources.push(audioSource.src);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
return templateSources;
|
|
14
|
+
};
|
|
15
|
+
export const loadAudio = async (url) => {
|
|
16
|
+
const response = await fetch(url);
|
|
17
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
18
|
+
return arrayBuffer;
|
|
19
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SceneSystem } from '../../../engine/system';
|
|
2
|
+
import type { SceneSystemOptions, UpdateOptions } from '../../../engine/system';
|
|
3
|
+
export declare class BehaviorSystem extends SceneSystem {
|
|
4
|
+
private behaviorCollection;
|
|
5
|
+
private actorSpawner;
|
|
6
|
+
private globalOptions;
|
|
7
|
+
private behaviors;
|
|
8
|
+
private world;
|
|
9
|
+
private scene;
|
|
10
|
+
private activeBehaviors;
|
|
11
|
+
constructor(options: SceneSystemOptions);
|
|
12
|
+
onSceneDestroy(): void;
|
|
13
|
+
private handleActorRemove;
|
|
14
|
+
private setUpBehavior;
|
|
15
|
+
update(options: UpdateOptions): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { SceneSystem } from '../../../engine/system';
|
|
2
|
+
import { ActorCollection } from '../../../engine/actor';
|
|
3
|
+
import { Behaviors } from '../../components';
|
|
4
|
+
import { RemoveActor } from '../../../engine/events';
|
|
5
|
+
export class BehaviorSystem extends SceneSystem {
|
|
6
|
+
behaviorCollection;
|
|
7
|
+
actorSpawner;
|
|
8
|
+
globalOptions;
|
|
9
|
+
behaviors;
|
|
10
|
+
world;
|
|
11
|
+
scene;
|
|
12
|
+
activeBehaviors;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super();
|
|
15
|
+
const { actorSpawner, world, scene, globalOptions, resources = {}, } = options;
|
|
16
|
+
this.world = world;
|
|
17
|
+
this.scene = scene;
|
|
18
|
+
this.behaviorCollection = new ActorCollection(scene, {
|
|
19
|
+
components: [Behaviors],
|
|
20
|
+
});
|
|
21
|
+
this.actorSpawner = actorSpawner;
|
|
22
|
+
this.globalOptions = globalOptions;
|
|
23
|
+
this.behaviors = resources.reduce((acc, behavior) => {
|
|
24
|
+
if (behavior.behaviorName === undefined) {
|
|
25
|
+
throw new Error(`Missing behaviorName field for ${behavior.name} behavior.`);
|
|
26
|
+
}
|
|
27
|
+
acc[behavior.behaviorName] = behavior;
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
this.activeBehaviors = {};
|
|
31
|
+
this.behaviorCollection.addEventListener(RemoveActor, this.handleActorRemove);
|
|
32
|
+
}
|
|
33
|
+
onSceneDestroy() {
|
|
34
|
+
this.behaviorCollection.removeEventListener(RemoveActor, this.handleActorRemove);
|
|
35
|
+
this.behaviorCollection.forEach((actor) => {
|
|
36
|
+
this.activeBehaviors[actor.id].forEach((behavior) => behavior.destroy?.());
|
|
37
|
+
delete this.activeBehaviors[actor.id];
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
handleActorRemove = (event) => {
|
|
41
|
+
const { actor } = event;
|
|
42
|
+
this.activeBehaviors[actor.id].forEach((behavior) => behavior.destroy?.());
|
|
43
|
+
delete this.activeBehaviors[actor.id];
|
|
44
|
+
};
|
|
45
|
+
setUpBehavior(actor) {
|
|
46
|
+
const { list } = actor.getComponent(Behaviors);
|
|
47
|
+
this.activeBehaviors[actor.id] = list.map((config) => {
|
|
48
|
+
const options = {
|
|
49
|
+
...config.options,
|
|
50
|
+
actor,
|
|
51
|
+
actorSpawner: this.actorSpawner,
|
|
52
|
+
world: this.world,
|
|
53
|
+
scene: this.scene,
|
|
54
|
+
globalOptions: this.globalOptions,
|
|
55
|
+
};
|
|
56
|
+
const BehaviorClass = this.behaviors[config.name];
|
|
57
|
+
return new BehaviorClass(options);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
update(options) {
|
|
61
|
+
this.behaviorCollection.forEach((actor) => {
|
|
62
|
+
if (!this.activeBehaviors[actor.id]) {
|
|
63
|
+
this.setUpBehavior(actor);
|
|
64
|
+
}
|
|
65
|
+
this.activeBehaviors[actor.id].forEach((behavior) => behavior.update?.(options));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
BehaviorSystem.systemName = 'BehaviorSystem';
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Actor, ActorSpawner } from '../../../engine/actor';
|
|
2
|
+
import type { World } from '../../../engine/world';
|
|
2
3
|
import type { Scene } from '../../../engine/scene';
|
|
3
4
|
import type { Constructor } from '../../../types/utils';
|
|
4
|
-
export interface
|
|
5
|
+
export interface BehaviorOptions {
|
|
6
|
+
world: World;
|
|
5
7
|
scene: Scene;
|
|
6
8
|
actor: Actor;
|
|
7
9
|
actorSpawner: ActorSpawner;
|
|
@@ -10,12 +12,12 @@ export interface ScriptOptions {
|
|
|
10
12
|
interface UpdateOptions {
|
|
11
13
|
deltaTime: number;
|
|
12
14
|
}
|
|
13
|
-
export declare abstract class
|
|
14
|
-
static
|
|
15
|
+
export declare abstract class Behavior {
|
|
16
|
+
static behaviorName: string;
|
|
15
17
|
destroy?(): void;
|
|
16
18
|
update?(options: UpdateOptions): void;
|
|
17
19
|
}
|
|
18
|
-
export type
|
|
19
|
-
|
|
20
|
+
export type BehaviorConstructor = Constructor<Behavior> & {
|
|
21
|
+
behaviorName: string;
|
|
20
22
|
};
|
|
21
23
|
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { Actor
|
|
1
|
+
import type { Actor } from '../../../engine/actor';
|
|
2
2
|
interface CameraServiceOptions {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
onCameraUpdate: (actor: Actor) => void;
|
|
4
|
+
findCurrentCamera: () => Actor | undefined;
|
|
5
5
|
}
|
|
6
6
|
export declare class CameraService {
|
|
7
|
-
private cameraCollection;
|
|
8
7
|
private onCameraUpdate;
|
|
9
|
-
|
|
8
|
+
private findCurrentCamera;
|
|
9
|
+
constructor({ onCameraUpdate, findCurrentCamera }: CameraServiceOptions);
|
|
10
10
|
setCurrentCamera(actor: Actor): void;
|
|
11
11
|
getCurrentCamera(): Actor | undefined;
|
|
12
12
|
}
|