dacha 0.18.0-alpha.4 → 0.18.0-alpha.6

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 (64) hide show
  1. package/build/contrib/components/audio-source/index.d.ts +1 -1
  2. package/build/contrib/components/audio-source/index.js +1 -1
  3. package/build/contrib/components/character-body/index.d.ts +72 -0
  4. package/build/contrib/components/character-body/index.js +90 -0
  5. package/build/contrib/components/collider/index.d.ts +9 -9
  6. package/build/contrib/components/collider/index.js +6 -6
  7. package/build/contrib/components/index.d.ts +1 -0
  8. package/build/contrib/components/index.js +1 -0
  9. package/build/contrib/events/index.d.ts +19 -39
  10. package/build/contrib/events/index.js +3 -21
  11. package/build/contrib/systems/audio-system/api.d.ts +38 -0
  12. package/build/contrib/systems/audio-system/api.js +44 -0
  13. package/build/contrib/systems/audio-system/index.d.ts +4 -3
  14. package/build/contrib/systems/audio-system/index.js +24 -30
  15. package/build/contrib/systems/character-controller/index.d.ts +32 -0
  16. package/build/contrib/systems/character-controller/index.js +262 -0
  17. package/build/contrib/systems/character-controller/utils.d.ts +2 -0
  18. package/build/contrib/systems/character-controller/utils.js +9 -0
  19. package/build/contrib/systems/index.d.ts +2 -1
  20. package/build/contrib/systems/index.js +2 -1
  21. package/build/contrib/systems/physics-system/api.d.ts +50 -8
  22. package/build/contrib/systems/physics-system/api.js +51 -10
  23. package/build/contrib/systems/physics-system/physics-system.d.ts +1 -0
  24. package/build/contrib/systems/physics-system/physics-system.js +22 -3
  25. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-cast-geometry.d.ts +4 -2
  26. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-cast-geometry.js +7 -4
  27. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +4 -4
  28. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +22 -22
  29. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-capsule-cast-geometry.d.ts +4 -2
  30. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-capsule-cast-geometry.js +14 -10
  31. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-capsule-geometry.d.ts +4 -4
  32. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-capsule-geometry.js +27 -15
  33. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-cast-geometry.d.ts +4 -2
  34. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-cast-geometry.js +10 -6
  35. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +4 -4
  36. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +24 -18
  37. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.js +1 -1
  38. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.d.ts +2 -2
  39. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.js +9 -5
  40. package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +2 -2
  41. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +5 -3
  42. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +34 -1
  43. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +8 -5
  44. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +116 -48
  45. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +7 -0
  46. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +2 -5
  47. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +11 -45
  48. package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +9 -3
  49. package/build/contrib/systems/physics-system/subsystems/physics/index.js +8 -5
  50. package/build/contrib/systems/physics-system/tests/helpers.d.ts +1 -1
  51. package/build/contrib/systems/physics-system/tests/helpers.js +3 -2
  52. package/build/contrib/systems/physics-system/types.d.ts +87 -43
  53. package/build/contrib/systems/renderer/builders/shape-builder/utils.js +38 -62
  54. package/build/contrib/utils/one-way-validator.d.ts +12 -0
  55. package/build/contrib/utils/one-way-validator.js +53 -0
  56. package/build/engine/consts.d.ts +2 -0
  57. package/build/engine/consts.js +2 -0
  58. package/build/engine/game-loop.d.ts +6 -2
  59. package/build/engine/game-loop.js +27 -6
  60. package/build/engine/math-lib/vector/vector2.d.ts +8 -0
  61. package/build/engine/math-lib/vector/vector2.js +11 -1
  62. package/build/events/index.d.ts +2 -2
  63. package/build/events/index.js +1 -1
  64. package/package.json +1 -1
@@ -30,7 +30,7 @@ export interface AudioSourceConfig {
30
30
  * audioSource.volume = 0.5; // Set volume to 50%
31
31
  *
32
32
  * // Play the audio
33
- * actor.dispatchEvent(PlayAudio);
33
+ * audioSource.playing = true;
34
34
  * ```
35
35
  *
36
36
  * @category Components
@@ -23,7 +23,7 @@ import { Component } from '../../../engine/component';
23
23
  * audioSource.volume = 0.5; // Set volume to 50%
24
24
  *
25
25
  * // Play the audio
26
- * actor.dispatchEvent(PlayAudio);
26
+ * audioSource.playing = true;
27
27
  * ```
28
28
  *
29
29
  * @category Components
@@ -0,0 +1,72 @@
1
+ import { Component } from '../../../engine/component';
2
+ import { Vector2 } from '../../../engine/math-lib';
3
+ import type { Actor } from '../../../engine/actor';
4
+ export type CharacterMotionMode = 'surface' | 'free';
5
+ export interface CharacterBodyConfig {
6
+ motionMode?: CharacterMotionMode;
7
+ upDirectionX?: number;
8
+ upDirectionY?: number;
9
+ skinWidth?: number;
10
+ maxSlopeAngle?: number;
11
+ maxSlides?: number;
12
+ maxRecoveries?: number;
13
+ groundSnapDistance?: number;
14
+ disabled?: boolean;
15
+ }
16
+ /**
17
+ * Kinematic character controller state and movement settings.
18
+ *
19
+ * The controller system consumes `velocity` during fixed updates, performs
20
+ * sweep/slide collision handling, and writes the resulting target through the
21
+ * actor's kinematic rigid body.
22
+ *
23
+ * @category Components
24
+ */
25
+ export declare class CharacterBody extends Component {
26
+ private _up;
27
+ /** @internal Pending one-step displacement consumed by CharacterController */
28
+ _displacement: Vector2;
29
+ /** @internal Whether CharacterController should run overlap recovery */
30
+ _needsRecovery: boolean;
31
+ /** Controls contact classification and whether ground snapping is enabled. */
32
+ motionMode: CharacterMotionMode;
33
+ /** Desired character velocity in world units per second */
34
+ velocity: Vector2;
35
+ /** Small distance kept between the character shape and blocking colliders */
36
+ skinWidth: number;
37
+ /** Maximum walkable ground angle in radians, measured from upDirection */
38
+ maxSlopeAngle: number;
39
+ /** Maximum sweep/slide collision iterations used during one fixed update */
40
+ maxSlides: number;
41
+ /** Maximum overlap depenetration iterations used when recovery is requested */
42
+ maxRecoveries: number;
43
+ /** Distance used to probe opposite upDirection and keep ground contact over small gaps */
44
+ groundSnapDistance: number;
45
+ /** Whether the controller should be ignored by CharacterController */
46
+ disabled: boolean;
47
+ /** Whether the controller is standing on walkable ground after the last fixed update */
48
+ onGround: boolean;
49
+ /** Whether movement hit a side wall or non-walkable surface during the last fixed update */
50
+ onWall: boolean;
51
+ /** Whether movement hit a ceiling during the last fixed update */
52
+ onCeiling: boolean;
53
+ /** Normal of the current walkable ground surface, updated by CharacterController */
54
+ groundNormal: Vector2;
55
+ /** Actor providing the current walkable ground, or null when not grounded */
56
+ groundActor: Actor | null;
57
+ constructor(config?: CharacterBodyConfig);
58
+ /** Direction treated as up for ground, ceiling, slopes, ground probes, and jumps */
59
+ get upDirection(): Vector2;
60
+ set upDirection(value: Vector2);
61
+ /**
62
+ * Adds a one-step world-space displacement request.
63
+ *
64
+ * The displacement is consumed by CharacterController on the next fixed
65
+ * update and is already expected to be scaled by delta time.
66
+ */
67
+ move(displacement: Vector2): void;
68
+ /**
69
+ * Requests overlap depenetration on the next CharacterController update.
70
+ */
71
+ recover(): void;
72
+ }
@@ -0,0 +1,90 @@
1
+ import { Component } from '../../../engine/component';
2
+ import { MathOps, Vector2 } from '../../../engine/math-lib';
3
+ /**
4
+ * Kinematic character controller state and movement settings.
5
+ *
6
+ * The controller system consumes `velocity` during fixed updates, performs
7
+ * sweep/slide collision handling, and writes the resulting target through the
8
+ * actor's kinematic rigid body.
9
+ *
10
+ * @category Components
11
+ */
12
+ export class CharacterBody extends Component {
13
+ _up;
14
+ /** @internal Pending one-step displacement consumed by CharacterController */
15
+ _displacement;
16
+ /** @internal Whether CharacterController should run overlap recovery */
17
+ _needsRecovery;
18
+ /** Controls contact classification and whether ground snapping is enabled. */
19
+ motionMode;
20
+ /** Desired character velocity in world units per second */
21
+ velocity;
22
+ /** Small distance kept between the character shape and blocking colliders */
23
+ skinWidth;
24
+ /** Maximum walkable ground angle in radians, measured from upDirection */
25
+ maxSlopeAngle;
26
+ /** Maximum sweep/slide collision iterations used during one fixed update */
27
+ maxSlides;
28
+ /** Maximum overlap depenetration iterations used when recovery is requested */
29
+ maxRecoveries;
30
+ /** Distance used to probe opposite upDirection and keep ground contact over small gaps */
31
+ groundSnapDistance;
32
+ /** Whether the controller should be ignored by CharacterController */
33
+ disabled;
34
+ /** Whether the controller is standing on walkable ground after the last fixed update */
35
+ onGround;
36
+ /** Whether movement hit a side wall or non-walkable surface during the last fixed update */
37
+ onWall;
38
+ /** Whether movement hit a ceiling during the last fixed update */
39
+ onCeiling;
40
+ /** Normal of the current walkable ground surface, updated by CharacterController */
41
+ groundNormal;
42
+ /** Actor providing the current walkable ground, or null when not grounded */
43
+ groundActor;
44
+ constructor(config = {}) {
45
+ super();
46
+ this._up = new Vector2(0, -1);
47
+ this._displacement = new Vector2(0, 0);
48
+ this._needsRecovery = true;
49
+ this.upDirection = new Vector2(config.upDirectionX ?? 0, config.upDirectionY ?? -1);
50
+ this.motionMode = config.motionMode ?? 'surface';
51
+ this.disabled = config.disabled ?? false;
52
+ this.velocity = new Vector2(0, 0);
53
+ this.skinWidth = config.skinWidth ?? 0.1;
54
+ this.maxSlopeAngle = MathOps.degToRad(config.maxSlopeAngle ?? 45);
55
+ this.maxSlides = config.maxSlides ?? 4;
56
+ this.maxRecoveries = config.maxRecoveries ?? 3;
57
+ this.groundSnapDistance = config.groundSnapDistance ?? 1;
58
+ this.onGround = false;
59
+ this.onWall = false;
60
+ this.onCeiling = false;
61
+ this.groundNormal = this.upDirection.clone();
62
+ this.groundActor = null;
63
+ }
64
+ /** Direction treated as up for ground, ceiling, slopes, ground probes, and jumps */
65
+ get upDirection() {
66
+ return this._up;
67
+ }
68
+ set upDirection(value) {
69
+ this._up = value.clone().normalize();
70
+ if (this._up.magnitude === 0) {
71
+ throw new Error('Character controller upDirection must be non-zero');
72
+ }
73
+ }
74
+ /**
75
+ * Adds a one-step world-space displacement request.
76
+ *
77
+ * The displacement is consumed by CharacterController on the next fixed
78
+ * update and is already expected to be scaled by delta time.
79
+ */
80
+ move(displacement) {
81
+ this._displacement.add(displacement);
82
+ }
83
+ /**
84
+ * Requests overlap depenetration on the next CharacterController update.
85
+ */
86
+ recover() {
87
+ this._needsRecovery = true;
88
+ }
89
+ }
90
+ CharacterBody.componentName = 'CharacterBody';
@@ -11,24 +11,24 @@ export interface BaseColliderConfig {
11
11
  }
12
12
  export interface BoxColliderConfig extends BaseColliderConfig {
13
13
  type: 'box';
14
- sizeX: number;
15
- sizeY: number;
14
+ sizeX?: number;
15
+ sizeY?: number;
16
16
  }
17
17
  export interface CircleColliderConfig extends BaseColliderConfig {
18
18
  type: 'circle';
19
- radius: number;
19
+ radius?: number;
20
20
  }
21
21
  export interface SegmentColliderConfig extends BaseColliderConfig {
22
22
  type: 'segment';
23
- point1X: number;
24
- point1Y: number;
25
- point2X: number;
26
- point2Y: number;
23
+ point1X?: number;
24
+ point1Y?: number;
25
+ point2X?: number;
26
+ point2Y?: number;
27
27
  }
28
28
  export interface CapsuleColliderConfig extends BaseColliderConfig {
29
29
  type: 'capsule';
30
- height: number;
31
- radius: number;
30
+ height?: number;
31
+ radius?: number;
32
32
  }
33
33
  export type ColliderConfig = BoxColliderConfig | CircleColliderConfig | SegmentColliderConfig | CapsuleColliderConfig;
34
34
  export interface BoxColliderShape {
@@ -50,27 +50,27 @@ export class Collider extends Component {
50
50
  case 'box':
51
51
  this.shape = {
52
52
  type: config.type,
53
- size: { x: config.sizeX, y: config.sizeY },
53
+ size: { x: config.sizeX ?? 0, y: config.sizeY ?? 0 },
54
54
  };
55
55
  break;
56
56
  case 'circle':
57
57
  this.shape = {
58
58
  type: config.type,
59
- radius: config.radius,
59
+ radius: config.radius ?? 0,
60
60
  };
61
61
  break;
62
62
  case 'segment':
63
63
  this.shape = {
64
64
  type: config.type,
65
- point1: { x: config.point1X, y: config.point1Y },
66
- point2: { x: config.point2X, y: config.point2Y },
65
+ point1: { x: config.point1X ?? 0, y: config.point1Y ?? 0 },
66
+ point2: { x: config.point2X ?? 0, y: config.point2Y ?? 0 },
67
67
  };
68
68
  break;
69
69
  case 'capsule':
70
70
  this.shape = {
71
71
  type: config.type,
72
- height: config.height,
73
- radius: config.radius,
72
+ height: config.height ?? 0,
73
+ radius: config.radius ?? 0,
74
74
  };
75
75
  }
76
76
  }
@@ -2,6 +2,7 @@ export { Camera, type CameraConfig } from './camera';
2
2
  export { KeyboardControl, type KeyboardControlConfig, } from './keyboard-control';
3
3
  export { Collider, type ColliderConfig, type ColliderShape, type ColliderType, type BoxColliderShape, type CircleColliderShape, type SegmentColliderShape, type CapsuleColliderShape, } from './collider';
4
4
  export { RigidBody, type RigidBodyConfig } from './rigid-body';
5
+ export { CharacterBody, type CharacterBodyConfig } from './character-body';
5
6
  export { Animatable, type AnimatableConfig } from './animatable';
6
7
  export { Sprite, type SpriteConfig } from './sprite';
7
8
  export { Transform, type TransformConfig } from './transform';
@@ -2,6 +2,7 @@ export { Camera } from './camera';
2
2
  export { KeyboardControl, } from './keyboard-control';
3
3
  export { Collider, } from './collider';
4
4
  export { RigidBody } from './rigid-body';
5
+ export { CharacterBody } from './character-body';
5
6
  export { Animatable } from './animatable';
6
7
  export { Sprite } from './sprite';
7
8
  export { Transform } from './transform';
@@ -57,32 +57,14 @@ export declare const CollisionStay = "CollisionStay";
57
57
  */
58
58
  export declare const CollisionLeave = "CollisionLeave";
59
59
  /**
60
- * Dispatched to play audio on an actor
60
+ * Dispatched when a character body hits a blocking actor
61
61
  *
62
62
  * @event
63
- * @type {ActorEvent}
63
+ * @type {CharacterHitEvent}
64
64
  *
65
65
  * @category Events
66
66
  */
67
- export declare const PlayAudio = "PlayAudio";
68
- /**
69
- * Dispatched to stop audio on an actor
70
- *
71
- * @event
72
- * @type {ActorEvent}
73
- *
74
- * @category Events
75
- */
76
- export declare const StopAudio = "StopAudio";
77
- /**
78
- * Dispatched to set audio volume
79
- *
80
- * @event
81
- * @type {SetAudioSourceVolumeEvent} (for actors) or {@link SetAudioGroupVolumeEvent} (for whole groups)
82
- *
83
- * @category Events
84
- */
85
- export declare const SetAudioVolume = "SetAudioVolume";
67
+ export declare const CharacterHit = "CharacterHit";
86
68
  /** Event signature for the {@link MouseInput} event
87
69
  *
88
70
  * @category Events
@@ -103,16 +85,6 @@ export type GameStatsUpdateEvent = WorldEvent<{
103
85
  /** Current number of actors in the scene */
104
86
  actorsCount: number;
105
87
  }>;
106
- /** Event signature for the {@link SetAudioVolume} event when used on world level
107
- *
108
- * @category Events
109
- */
110
- export type SetAudioGroupVolumeEvent = WorldEvent<{
111
- /** Audio group name to set volume for */
112
- group: string;
113
- /** Volume value (0.0 to 1.0) */
114
- value: number;
115
- }>;
116
88
  /** Event signature for mouse control events
117
89
  *
118
90
  * @category Events
@@ -155,28 +127,36 @@ export type CollisionStayEvent = CollisionStateEvent;
155
127
  * @category Events
156
128
  */
157
129
  export type CollisionLeaveEvent = CollisionStateEvent;
158
- /** Event signature for the {@link SetAudioVolume} event when used on actor level
130
+ /** Event signature for the {@link CharacterHit} event
159
131
  *
160
132
  * @category Events
161
133
  */
162
- export type SetAudioSourceVolumeEvent = ActorEvent<{
163
- /** Volume value (0.0 to 1.0) */
164
- value: number;
134
+ export type CharacterHitEvent = ActorEvent<{
135
+ /** Actor hit by the character body */
136
+ actor: Actor;
137
+ /** Hit point in world space */
138
+ point: {
139
+ x: number;
140
+ y: number;
141
+ };
142
+ /** Hit normal pointing from the hit actor to the character */
143
+ normal: Vector2;
144
+ /** Distance from the cast origin to the hit */
145
+ distance: number;
146
+ /** Surface classification used by the character controller */
147
+ kind: 'ground' | 'wall' | 'ceiling';
165
148
  }>;
166
149
  declare module '../../types/events' {
167
150
  interface WorldEventMap {
168
151
  [MouseInput]: MouseInputEvent;
169
152
  [KeyboardInput]: KeyboardInputEvent;
170
153
  [GameStatsUpdate]: GameStatsUpdateEvent;
171
- [SetAudioVolume]: SetAudioGroupVolumeEvent;
172
154
  }
173
155
  interface ActorEventMap {
174
156
  [CollisionEnter]: CollisionEnterEvent;
175
157
  [CollisionStay]: CollisionStayEvent;
176
158
  [CollisionLeave]: CollisionLeaveEvent;
177
- [PlayAudio]: ActorEvent;
178
- [StopAudio]: ActorEvent;
179
- [SetAudioVolume]: SetAudioSourceVolumeEvent;
159
+ [CharacterHit]: CharacterHitEvent;
180
160
  }
181
161
  }
182
162
  export {};
@@ -53,29 +53,11 @@ export const CollisionStay = 'CollisionStay';
53
53
  */
54
54
  export const CollisionLeave = 'CollisionLeave';
55
55
  /**
56
- * Dispatched to play audio on an actor
56
+ * Dispatched when a character body hits a blocking actor
57
57
  *
58
58
  * @event
59
- * @type {ActorEvent}
59
+ * @type {CharacterHitEvent}
60
60
  *
61
61
  * @category Events
62
62
  */
63
- export const PlayAudio = 'PlayAudio';
64
- /**
65
- * Dispatched to stop audio on an actor
66
- *
67
- * @event
68
- * @type {ActorEvent}
69
- *
70
- * @category Events
71
- */
72
- export const StopAudio = 'StopAudio';
73
- /**
74
- * Dispatched to set audio volume
75
- *
76
- * @event
77
- * @type {SetAudioSourceVolumeEvent} (for actors) or {@link SetAudioGroupVolumeEvent} (for whole groups)
78
- *
79
- * @category Events
80
- */
81
- export const SetAudioVolume = 'SetAudioVolume';
63
+ export const CharacterHit = 'CharacterHit';
@@ -0,0 +1,38 @@
1
+ export interface AudioAPIHandlers {
2
+ getGroupVolume(group: string): number;
3
+ setGroupVolume(group: string, volume: number): void;
4
+ }
5
+ /**
6
+ * API that provides synchronous audio mixer controls.
7
+ *
8
+ * Actor playback is controlled through AudioSource component state.
9
+ * This API is intended for global audio state such as group and master volume.
10
+ *
11
+ * @category Systems
12
+ */
13
+ export declare class AudioAPI {
14
+ private handlers;
15
+ constructor(handlers: AudioAPIHandlers);
16
+ /**
17
+ * Current master volume.
18
+ */
19
+ get masterVolume(): number;
20
+ /**
21
+ * Sets the master volume.
22
+ */
23
+ set masterVolume(volume: number);
24
+ /**
25
+ * Returns the volume for an audio group.
26
+ *
27
+ * @param group - Audio group name
28
+ * @returns Audio group volume
29
+ */
30
+ getGroupVolume(group: string): number;
31
+ /**
32
+ * Sets the volume for an audio group.
33
+ *
34
+ * @param group - Audio group name
35
+ * @param volume - New group volume
36
+ */
37
+ setGroupVolume(group: string, volume: number): void;
38
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * API that provides synchronous audio mixer controls.
3
+ *
4
+ * Actor playback is controlled through AudioSource component state.
5
+ * This API is intended for global audio state such as group and master volume.
6
+ *
7
+ * @category Systems
8
+ */
9
+ export class AudioAPI {
10
+ handlers;
11
+ constructor(handlers) {
12
+ this.handlers = handlers;
13
+ }
14
+ /**
15
+ * Current master volume.
16
+ */
17
+ get masterVolume() {
18
+ return this.getGroupVolume('master');
19
+ }
20
+ /**
21
+ * Sets the master volume.
22
+ */
23
+ set masterVolume(volume) {
24
+ this.setGroupVolume('master', volume);
25
+ }
26
+ /**
27
+ * Returns the volume for an audio group.
28
+ *
29
+ * @param group - Audio group name
30
+ * @returns Audio group volume
31
+ */
32
+ getGroupVolume(group) {
33
+ return this.handlers.getGroupVolume(group);
34
+ }
35
+ /**
36
+ * Sets the volume for an audio group.
37
+ *
38
+ * @param group - Audio group name
39
+ * @param volume - New group volume
40
+ */
41
+ setGroupVolume(group, volume) {
42
+ this.handlers.setGroupVolume(group, volume);
43
+ }
44
+ }
@@ -25,13 +25,14 @@ export declare class AudioSystem extends WorldSystem {
25
25
  private loadAudio;
26
26
  private handleActorAdd;
27
27
  private handleActorRemove;
28
- private handlePlayAudio;
29
- private handleStopAudio;
30
- private handleSetAudioVolume;
31
28
  private resumeIfSuspended;
29
+ private getGroup;
30
+ private getGroupVolume;
31
+ private setGroupVolume;
32
32
  private initAudio;
33
33
  private playAudio;
34
34
  private stopAudio;
35
35
  private updateAudio;
36
36
  update(): void;
37
37
  }
38
+ export { AudioAPI } from './api';
@@ -1,9 +1,9 @@
1
1
  import { WorldSystem } from '../../../engine/system';
2
- import { Actor, ActorQuery } from '../../../engine/actor';
2
+ import { ActorQuery } from '../../../engine/actor';
3
3
  import { AddActor, RemoveActor } from '../../../engine/events';
4
4
  import { CacheStore } from '../../../engine/data-lib';
5
5
  import { AudioSource } from '../../components';
6
- import { PlayAudio, StopAudio, SetAudioVolume } from '../../../events';
6
+ import { AudioAPI } from './api';
7
7
  import { getAllSources, getAllTemplateSources, loadAudio } from './utils';
8
8
  const MASTER_GROUP = 'master';
9
9
  const VOLUME_TOLERANCE = 0.001;
@@ -44,9 +44,13 @@ export class AudioSystem extends WorldSystem {
44
44
  }, { [MASTER_GROUP]: masterAudioGroup });
45
45
  this.audioStore = new CacheStore();
46
46
  this.audioState = new Map();
47
- this.world.addEventListener(PlayAudio, this.handlePlayAudio);
48
- this.world.addEventListener(StopAudio, this.handleStopAudio);
49
- this.world.addEventListener(SetAudioVolume, this.handleSetAudioVolume);
47
+ const audioApi = new AudioAPI({
48
+ getGroupVolume: (group) => this.getGroupVolume(group),
49
+ setGroupVolume: (group, volume) => {
50
+ this.setGroupVolume(group, volume);
51
+ },
52
+ });
53
+ this.world.systemApi.register(audioApi);
50
54
  window.addEventListener('click', this.resumeIfSuspended, { once: true });
51
55
  window.addEventListener('keydown', this.resumeIfSuspended, { once: true });
52
56
  window.addEventListener('touchstart', this.resumeIfSuspended, {
@@ -96,9 +100,6 @@ export class AudioSystem extends WorldSystem {
96
100
  }
97
101
  onWorldDestroy() {
98
102
  void this.audioContext.close();
99
- this.world.removeEventListener(PlayAudio, this.handlePlayAudio);
100
- this.world.removeEventListener(StopAudio, this.handleStopAudio);
101
- this.world.removeEventListener(SetAudioVolume, this.handleSetAudioVolume);
102
103
  window.removeEventListener('click', this.resumeIfSuspended);
103
104
  window.removeEventListener('keydown', this.resumeIfSuspended);
104
105
  window.removeEventListener('touchstart', this.resumeIfSuspended);
@@ -129,28 +130,6 @@ export class AudioSystem extends WorldSystem {
129
130
  this.audioStore.release(src);
130
131
  this.stopAudio(actor);
131
132
  };
132
- handlePlayAudio = (event) => {
133
- this.playAudio(event.target);
134
- };
135
- handleStopAudio = (event) => {
136
- this.stopAudio(event.target);
137
- };
138
- handleSetAudioVolume = (event) => {
139
- if (event.target instanceof Actor) {
140
- const audioSource = event.target.getComponent(AudioSource);
141
- if (!audioSource) {
142
- return;
143
- }
144
- audioSource.volume = event.value;
145
- }
146
- else {
147
- const audioGroup = this.audioGroups[event.group];
148
- if (!audioGroup) {
149
- return;
150
- }
151
- audioGroup.gain.value = event.value;
152
- }
153
- };
154
133
  resumeIfSuspended = () => {
155
134
  if (this.audioContext.state === 'suspended') {
156
135
  void this.audioContext.resume().catch((err) => {
@@ -158,6 +137,19 @@ export class AudioSystem extends WorldSystem {
158
137
  });
159
138
  }
160
139
  };
140
+ getGroup(group) {
141
+ const audioGroup = this.audioGroups[group];
142
+ if (!audioGroup) {
143
+ throw new Error(`Can't find audio group with the following name: ${group}`);
144
+ }
145
+ return audioGroup;
146
+ }
147
+ getGroupVolume(group) {
148
+ return this.getGroup(group).gain.value;
149
+ }
150
+ setGroupVolume(group, volume) {
151
+ this.getGroup(group).gain.value = volume;
152
+ }
161
153
  initAudio(actor) {
162
154
  const audioSource = actor.getComponent(AudioSource);
163
155
  if (audioSource.autoplay) {
@@ -217,6 +209,7 @@ export class AudioSystem extends WorldSystem {
217
209
  if (Math.abs(audioSource.volume - audioState.properties.volume) >
218
210
  VOLUME_TOLERANCE) {
219
211
  audioState.gainNode.gain.value = audioSource.volume;
212
+ audioState.properties.volume = audioSource.volume;
220
213
  }
221
214
  }
222
215
  update() {
@@ -236,3 +229,4 @@ export class AudioSystem extends WorldSystem {
236
229
  }
237
230
  }
238
231
  AudioSystem.systemName = 'AudioSystem';
232
+ export { AudioAPI } from './api';
@@ -0,0 +1,32 @@
1
+ import { SceneSystem } from '../../../engine/system';
2
+ import type { SceneSystemOptions, UpdateOptions } from '../../../engine/system';
3
+ /**
4
+ * Kinematic character controller system with sweep/slide collision movement.
5
+ *
6
+ * The system expects actors to have `CharacterBody`, `Transform`,
7
+ * `Collider`, and a kinematic `RigidBody`. Put this system before
8
+ * `PhysicsSystem` in system configuration so `movePosition()` targets are
9
+ * consumed by physics in the same fixed step.
10
+ *
11
+ * @category Systems
12
+ */
13
+ export declare class CharacterController extends SceneSystem {
14
+ private actorQuery;
15
+ private world;
16
+ private oneWayValidator;
17
+ constructor(options: SceneSystemOptions);
18
+ onSceneDestroy(): void;
19
+ private isBlockingHit;
20
+ private isWalkable;
21
+ private isRecoverableOverlap;
22
+ private resetGroundState;
23
+ private resetState;
24
+ private cast;
25
+ private castMotion;
26
+ private castGround;
27
+ private recoverOverlaps;
28
+ private handleHit;
29
+ private move;
30
+ private updateGroundState;
31
+ fixedUpdate(options: UpdateOptions): void;
32
+ }