dacha 0.13.0 → 0.14.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/audio-source/index.d.ts +18 -0
- package/build/contrib/components/audio-source/index.js +28 -0
- package/build/contrib/components/index.d.ts +2 -0
- package/build/contrib/components/index.js +1 -0
- package/build/contrib/events/index.d.ts +14 -0
- package/build/contrib/events/index.js +3 -0
- package/build/contrib/systems/audio-system/audio-loader.d.ts +7 -0
- package/build/contrib/systems/audio-system/audio-loader.js +16 -0
- package/build/contrib/systems/audio-system/index.d.ts +27 -0
- package/build/contrib/systems/audio-system/index.js +195 -0
- package/build/contrib/systems/audio-system/types.d.ts +17 -0
- package/build/contrib/systems/audio-system/types.js +1 -0
- package/build/contrib/systems/index.d.ts +1 -0
- package/build/contrib/systems/index.js +1 -0
- package/build/contrib/systems/script-system/index.d.ts +1 -0
- package/build/contrib/systems/script-system/index.js +4 -1
- package/build/contrib/systems/script-system/types.d.ts +1 -0
- package/build/contrib/systems/sprite-renderer/renderer.js +1 -1
- package/build/contrib/systems/sprite-renderer/sort/utils.d.ts +2 -1
- package/build/contrib/systems/sprite-renderer/sort/utils.js +1 -1
- package/build/contrib/systems/sprite-renderer/types.d.ts +7 -0
- package/build/contrib/systems/sprite-renderer/types.js +1 -0
- package/build/contrib/systems/ui-bridge/index.d.ts +2 -0
- package/build/contrib/systems/ui-bridge/index.js +4 -1
- package/build/engine/scene/scene-provider.js +1 -1
- package/build/engine/types/config.d.ts +12 -14
- package/build/events/index.d.ts +2 -2
- package/build/events/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Component } from '../../../engine/component';
|
|
2
|
+
export interface AudioSourceConfig {
|
|
3
|
+
src: string;
|
|
4
|
+
group: string;
|
|
5
|
+
looped: boolean;
|
|
6
|
+
volume: number;
|
|
7
|
+
autoplay: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class AudioSource extends Component {
|
|
10
|
+
src: string;
|
|
11
|
+
group: string;
|
|
12
|
+
looped: boolean;
|
|
13
|
+
volume: number;
|
|
14
|
+
autoplay: boolean;
|
|
15
|
+
playing: boolean;
|
|
16
|
+
constructor(config: AudioSourceConfig);
|
|
17
|
+
clone(): AudioSource;
|
|
18
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Component } from '../../../engine/component';
|
|
2
|
+
export class AudioSource extends Component {
|
|
3
|
+
src;
|
|
4
|
+
group;
|
|
5
|
+
looped;
|
|
6
|
+
volume;
|
|
7
|
+
autoplay;
|
|
8
|
+
playing;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
super();
|
|
11
|
+
this.src = config.src;
|
|
12
|
+
this.group = config.group;
|
|
13
|
+
this.looped = config.looped;
|
|
14
|
+
this.volume = config.volume;
|
|
15
|
+
this.autoplay = config.autoplay;
|
|
16
|
+
this.playing = false;
|
|
17
|
+
}
|
|
18
|
+
clone() {
|
|
19
|
+
return new AudioSource({
|
|
20
|
+
src: this.src,
|
|
21
|
+
group: this.group,
|
|
22
|
+
looped: this.looped,
|
|
23
|
+
volume: this.volume,
|
|
24
|
+
autoplay: this.autoplay,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
AudioSource.componentName = 'AudioSource';
|
|
@@ -18,3 +18,5 @@ export { ScriptBundle } from './script-bundle';
|
|
|
18
18
|
export type { ScriptBundleConfig } from './script-bundle';
|
|
19
19
|
export { Light } from './light';
|
|
20
20
|
export type { LightConfig } from './light';
|
|
21
|
+
export { AudioSource } from './audio-source';
|
|
22
|
+
export type { AudioSourceConfig } from './audio-source';
|
|
@@ -13,6 +13,9 @@ export declare const CollisionLeave = "CollisionLeave";
|
|
|
13
13
|
export declare const AddForce = "AddForce";
|
|
14
14
|
export declare const AddImpulse = "AddImpulse";
|
|
15
15
|
export declare const StopMovement = "StopMovement";
|
|
16
|
+
export declare const PlayAudio = "PlayAudio";
|
|
17
|
+
export declare const StopAudio = "StopAudio";
|
|
18
|
+
export declare const SetAudioVolume = "SetAudioVolume";
|
|
16
19
|
export type MouseInputEvent = SceneEvent<CustomMouseEvent>;
|
|
17
20
|
export type KeyboardInputEvent = SceneEvent<CustomKeyboardEvent>;
|
|
18
21
|
export type SetCameraEvent = SceneEvent<{
|
|
@@ -28,6 +31,10 @@ export type CollisionEvent = SceneEvent<{
|
|
|
28
31
|
mtv1: Vector2;
|
|
29
32
|
mtv2: Vector2;
|
|
30
33
|
}>;
|
|
34
|
+
export type SetAudioGroupVolumeEvent = SceneEvent<{
|
|
35
|
+
group: string;
|
|
36
|
+
value: number;
|
|
37
|
+
}>;
|
|
31
38
|
export type MouseControlEvent<T = Record<string, never>> = ActorEvent<Pick<CustomMouseEvent, 'x' | 'y' | 'screenX' | 'screenY' | 'nativeEvent'>> & T;
|
|
32
39
|
export type KeyboardControlEvent<T = Record<string, never>> = ActorEvent<T>;
|
|
33
40
|
type CollisionStateEvent = ActorEvent<{
|
|
@@ -43,6 +50,9 @@ export type AddForceEvent = ActorEvent<{
|
|
|
43
50
|
export type AddImpulseEvent = ActorEvent<{
|
|
44
51
|
value: Vector2;
|
|
45
52
|
}>;
|
|
53
|
+
export type SetAudioSourceVolumeEvent = ActorEvent<{
|
|
54
|
+
value: number;
|
|
55
|
+
}>;
|
|
46
56
|
declare module '../../types/events' {
|
|
47
57
|
interface SceneEventMap {
|
|
48
58
|
[MouseInput]: MouseInputEvent;
|
|
@@ -50,6 +60,7 @@ declare module '../../types/events' {
|
|
|
50
60
|
[SetCamera]: SetCameraEvent;
|
|
51
61
|
[GameStatsUpdate]: GameStatsUpdateEvent;
|
|
52
62
|
[Collision]: CollisionEvent;
|
|
63
|
+
[SetAudioVolume]: SetAudioGroupVolumeEvent;
|
|
53
64
|
}
|
|
54
65
|
interface ActorEventMap {
|
|
55
66
|
[CollisionEnter]: CollisionEnterEvent;
|
|
@@ -58,6 +69,9 @@ declare module '../../types/events' {
|
|
|
58
69
|
[AddForce]: AddForceEvent;
|
|
59
70
|
[AddImpulse]: AddImpulseEvent;
|
|
60
71
|
[StopMovement]: ActorEvent;
|
|
72
|
+
[PlayAudio]: ActorEvent;
|
|
73
|
+
[StopAudio]: ActorEvent;
|
|
74
|
+
[SetAudioVolume]: SetAudioSourceVolumeEvent;
|
|
61
75
|
}
|
|
62
76
|
}
|
|
63
77
|
export {};
|
|
@@ -9,3 +9,6 @@ export const CollisionLeave = 'CollisionLeave';
|
|
|
9
9
|
export const AddForce = 'AddForce';
|
|
10
10
|
export const AddImpulse = 'AddImpulse';
|
|
11
11
|
export const StopMovement = 'StopMovement';
|
|
12
|
+
export const PlayAudio = 'PlayAudio';
|
|
13
|
+
export const StopAudio = 'StopAudio';
|
|
14
|
+
export const SetAudioVolume = 'SetAudioVolume';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class AudioLoader {
|
|
2
|
+
cache;
|
|
3
|
+
constructor() {
|
|
4
|
+
this.cache = new Map();
|
|
5
|
+
}
|
|
6
|
+
async load(url) {
|
|
7
|
+
if (this.cache.has(url)) {
|
|
8
|
+
return structuredClone(this.cache.get(url));
|
|
9
|
+
}
|
|
10
|
+
const response = await fetch(url);
|
|
11
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
12
|
+
this.cache.set(url, arrayBuffer);
|
|
13
|
+
return structuredClone(arrayBuffer);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export const audioLoader = new AudioLoader();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { System } from '../../../engine/system';
|
|
2
|
+
import type { SystemOptions } from '../../../engine/system';
|
|
3
|
+
export declare class AudioSystem extends System {
|
|
4
|
+
private templateCollection;
|
|
5
|
+
private actorCollection;
|
|
6
|
+
private scene;
|
|
7
|
+
private audioContext;
|
|
8
|
+
private audioGroups;
|
|
9
|
+
private audioCache;
|
|
10
|
+
private audioState;
|
|
11
|
+
constructor(options: SystemOptions);
|
|
12
|
+
load(): Promise<void>;
|
|
13
|
+
private loadAudio;
|
|
14
|
+
mount(): void;
|
|
15
|
+
unmount(): void;
|
|
16
|
+
private handleActorAdd;
|
|
17
|
+
private handleActorRemove;
|
|
18
|
+
private handlePlayAudio;
|
|
19
|
+
private handleStopAudio;
|
|
20
|
+
private handleSetAudioVolume;
|
|
21
|
+
private resumeIfSuspended;
|
|
22
|
+
private initAudio;
|
|
23
|
+
private playAudio;
|
|
24
|
+
private stopAudio;
|
|
25
|
+
private updateAudio;
|
|
26
|
+
update(): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { System } from '../../../engine/system';
|
|
2
|
+
import { Actor, ActorCollection } from '../../../engine/actor';
|
|
3
|
+
import { AddActor, RemoveActor } from '../../../engine/events';
|
|
4
|
+
import { AudioSource } from '../../components';
|
|
5
|
+
import { PlayAudio, StopAudio, SetAudioVolume, } from '../../../events';
|
|
6
|
+
import { audioLoader } from './audio-loader';
|
|
7
|
+
const MASTER_GROUP = 'master';
|
|
8
|
+
const VOLUME_TOLERANCE = 0.001;
|
|
9
|
+
export class AudioSystem extends System {
|
|
10
|
+
templateCollection;
|
|
11
|
+
actorCollection;
|
|
12
|
+
scene;
|
|
13
|
+
audioContext;
|
|
14
|
+
audioGroups;
|
|
15
|
+
audioCache;
|
|
16
|
+
audioState;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super();
|
|
19
|
+
const { scene, globalOptions, templateCollection } = options;
|
|
20
|
+
this.templateCollection = templateCollection;
|
|
21
|
+
this.actorCollection = new ActorCollection(scene, {
|
|
22
|
+
components: [AudioSource],
|
|
23
|
+
});
|
|
24
|
+
this.scene = scene;
|
|
25
|
+
this.audioContext = new AudioContext();
|
|
26
|
+
const masterAudioGroup = new GainNode(this.audioContext);
|
|
27
|
+
masterAudioGroup.connect(this.audioContext.destination);
|
|
28
|
+
const audioGroupsOption = globalOptions.audioGroups;
|
|
29
|
+
const audioGroupsSettings = audioGroupsOption?.groups ?? [];
|
|
30
|
+
this.audioGroups = audioGroupsSettings.reduce((acc, groupSettings) => {
|
|
31
|
+
if (groupSettings.name === MASTER_GROUP) {
|
|
32
|
+
return acc;
|
|
33
|
+
}
|
|
34
|
+
const gainNode = new GainNode(this.audioContext);
|
|
35
|
+
gainNode.gain.value = groupSettings.volume;
|
|
36
|
+
gainNode.connect(masterAudioGroup);
|
|
37
|
+
acc[groupSettings.name] = gainNode;
|
|
38
|
+
return acc;
|
|
39
|
+
}, { [MASTER_GROUP]: masterAudioGroup });
|
|
40
|
+
this.audioCache = new Map();
|
|
41
|
+
this.audioState = new Map();
|
|
42
|
+
}
|
|
43
|
+
async load() {
|
|
44
|
+
const templateSources = this.templateCollection.getAll()
|
|
45
|
+
.filter((template) => template.getComponent(AudioSource))
|
|
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);
|
|
71
|
+
window.addEventListener('click', this.resumeIfSuspended, { once: true });
|
|
72
|
+
window.addEventListener('keydown', this.resumeIfSuspended, { once: true });
|
|
73
|
+
window.addEventListener('touchstart', this.resumeIfSuspended, { once: true });
|
|
74
|
+
}
|
|
75
|
+
unmount() {
|
|
76
|
+
this.audioState.forEach((audioState) => {
|
|
77
|
+
audioState.sourceNode.stop();
|
|
78
|
+
});
|
|
79
|
+
void this.audioContext.close();
|
|
80
|
+
this.actorCollection.removeEventListener(AddActor, this.handleActorAdd);
|
|
81
|
+
this.actorCollection.removeEventListener(RemoveActor, this.handleActorRemove);
|
|
82
|
+
this.scene.removeEventListener(PlayAudio, this.handlePlayAudio);
|
|
83
|
+
this.scene.removeEventListener(StopAudio, this.handleStopAudio);
|
|
84
|
+
this.scene.removeEventListener(SetAudioVolume, this.handleSetAudioVolume);
|
|
85
|
+
}
|
|
86
|
+
handleActorAdd = (event) => {
|
|
87
|
+
this.initAudio(event.actor);
|
|
88
|
+
};
|
|
89
|
+
handleActorRemove = (event) => {
|
|
90
|
+
this.stopAudio(event.actor);
|
|
91
|
+
};
|
|
92
|
+
handlePlayAudio = (event) => {
|
|
93
|
+
this.playAudio(event.target);
|
|
94
|
+
};
|
|
95
|
+
handleStopAudio = (event) => {
|
|
96
|
+
this.stopAudio(event.target);
|
|
97
|
+
};
|
|
98
|
+
handleSetAudioVolume = (event) => {
|
|
99
|
+
if (event.target instanceof Actor) {
|
|
100
|
+
const audioSource = event.target.getComponent(AudioSource);
|
|
101
|
+
if (!audioSource) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
audioSource.volume = event.value;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const audioGroup = this.audioGroups[event.group];
|
|
108
|
+
if (!audioGroup) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
audioGroup.gain.value = event.value;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
resumeIfSuspended = () => {
|
|
115
|
+
if (this.audioContext.state === 'suspended') {
|
|
116
|
+
void this.audioContext.resume();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
initAudio(actor) {
|
|
120
|
+
const audioSource = actor.getComponent(AudioSource);
|
|
121
|
+
if (audioSource.autoplay) {
|
|
122
|
+
this.playAudio(actor);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
playAudio(actor) {
|
|
126
|
+
const audioSource = actor.getComponent(AudioSource);
|
|
127
|
+
if (!audioSource) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const { src, group, volume, looped, playing, } = audioSource;
|
|
131
|
+
const audioGroupNode = this.audioGroups[group];
|
|
132
|
+
if (!audioGroupNode || !this.audioCache.has(src)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (playing && this.audioState.has(actor.id)) {
|
|
136
|
+
const prevAudio = this.audioState.get(actor.id);
|
|
137
|
+
prevAudio.sourceNode.removeEventListener('ended', prevAudio.properties.endedListener);
|
|
138
|
+
prevAudio.sourceNode.stop();
|
|
139
|
+
prevAudio.gainNode.disconnect();
|
|
140
|
+
}
|
|
141
|
+
const sourceNode = new AudioBufferSourceNode(this.audioContext, {
|
|
142
|
+
buffer: this.audioCache.get(src),
|
|
143
|
+
loop: looped,
|
|
144
|
+
});
|
|
145
|
+
const gainNode = new GainNode(this.audioContext, {
|
|
146
|
+
gain: volume,
|
|
147
|
+
});
|
|
148
|
+
const endedListener = () => this.stopAudio(actor);
|
|
149
|
+
sourceNode.connect(gainNode).connect(audioGroupNode);
|
|
150
|
+
sourceNode.addEventListener('ended', endedListener);
|
|
151
|
+
sourceNode.start();
|
|
152
|
+
this.audioState.set(actor.id, {
|
|
153
|
+
sourceNode,
|
|
154
|
+
gainNode,
|
|
155
|
+
properties: { volume, group, endedListener },
|
|
156
|
+
});
|
|
157
|
+
audioSource.playing = true;
|
|
158
|
+
}
|
|
159
|
+
stopAudio(actor) {
|
|
160
|
+
const audioSource = actor.getComponent(AudioSource);
|
|
161
|
+
if (audioSource) {
|
|
162
|
+
audioSource.playing = false;
|
|
163
|
+
}
|
|
164
|
+
const audioState = this.audioState.get(actor.id);
|
|
165
|
+
if (!audioState) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
audioState.sourceNode.stop();
|
|
169
|
+
audioState.gainNode.disconnect();
|
|
170
|
+
this.audioState.delete(actor.id);
|
|
171
|
+
}
|
|
172
|
+
updateAudio(actor) {
|
|
173
|
+
const audioSource = actor.getComponent(AudioSource);
|
|
174
|
+
const audioState = this.audioState.get(actor.id);
|
|
175
|
+
if (Math.abs(audioSource.volume - audioState.properties.volume) > VOLUME_TOLERANCE) {
|
|
176
|
+
audioState.gainNode.gain.value = audioSource.volume;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
update() {
|
|
180
|
+
this.actorCollection.forEach((actor) => {
|
|
181
|
+
const audioSource = actor.getComponent(AudioSource);
|
|
182
|
+
const audioState = this.audioState.get(actor.id);
|
|
183
|
+
if (audioSource.playing && audioState) {
|
|
184
|
+
this.updateAudio(actor);
|
|
185
|
+
}
|
|
186
|
+
if (audioSource.playing && !audioState) {
|
|
187
|
+
this.playAudio(actor);
|
|
188
|
+
}
|
|
189
|
+
if (!audioSource.playing && audioState) {
|
|
190
|
+
this.stopAudio(actor);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
AudioSystem.systemName = 'AudioSystem';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type AudioStateNode = {
|
|
2
|
+
sourceNode: AudioBufferSourceNode;
|
|
3
|
+
gainNode: GainNode;
|
|
4
|
+
properties: {
|
|
5
|
+
volume: number;
|
|
6
|
+
group: string;
|
|
7
|
+
endedListener: () => void;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export type AudioGroup = {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
volume: number;
|
|
14
|
+
};
|
|
15
|
+
export type AudioGroups = {
|
|
16
|
+
groups: AudioGroup[];
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,3 +11,4 @@ export type { ScriptOptions } from './script-system';
|
|
|
11
11
|
export { SpriteRenderer, SpriteRendererService } from './sprite-renderer';
|
|
12
12
|
export { UiBridge } from './ui-bridge';
|
|
13
13
|
export type { UiInitFnOptions, UiInitFn, UiDestroyFn } from './ui-bridge';
|
|
14
|
+
export { AudioSystem } from './audio-system';
|
|
@@ -9,3 +9,4 @@ export { PhysicsSystem } from './physics-system';
|
|
|
9
9
|
export { ScriptSystem, Script } from './script-system';
|
|
10
10
|
export { SpriteRenderer, SpriteRendererService } from './sprite-renderer';
|
|
11
11
|
export { UiBridge } from './ui-bridge';
|
|
12
|
+
export { AudioSystem } from './audio-system';
|
|
@@ -7,12 +7,13 @@ export { Script };
|
|
|
7
7
|
export class ScriptSystem extends System {
|
|
8
8
|
scriptsCollection;
|
|
9
9
|
actorSpawner;
|
|
10
|
+
globalOptions;
|
|
10
11
|
scripts;
|
|
11
12
|
scene;
|
|
12
13
|
activeScripts;
|
|
13
14
|
constructor(options) {
|
|
14
15
|
super();
|
|
15
|
-
const { actorSpawner, scene, resources = {}, } = options;
|
|
16
|
+
const { actorSpawner, scene, globalOptions, resources = {}, } = options;
|
|
16
17
|
this.scene = scene;
|
|
17
18
|
this.scriptsCollection = new ActorCollection(scene, {
|
|
18
19
|
components: [
|
|
@@ -20,6 +21,7 @@ export class ScriptSystem extends System {
|
|
|
20
21
|
],
|
|
21
22
|
});
|
|
22
23
|
this.actorSpawner = actorSpawner;
|
|
24
|
+
this.globalOptions = globalOptions;
|
|
23
25
|
this.scripts = resources.reduce((acc, script) => {
|
|
24
26
|
if (script.scriptName === undefined) {
|
|
25
27
|
throw new Error(`Missing scriptName field for ${script.name} script.`);
|
|
@@ -53,6 +55,7 @@ export class ScriptSystem extends System {
|
|
|
53
55
|
actor,
|
|
54
56
|
actorSpawner: this.actorSpawner,
|
|
55
57
|
scene: this.scene,
|
|
58
|
+
globalOptions: this.globalOptions,
|
|
56
59
|
});
|
|
57
60
|
});
|
|
58
61
|
}
|
|
@@ -43,7 +43,7 @@ export class SpriteRenderer extends System {
|
|
|
43
43
|
this.templateCollection = templateCollection;
|
|
44
44
|
this.window = getWindowNode(windowNodeId);
|
|
45
45
|
this.sortFn = composeSort([
|
|
46
|
-
createSortByLayer(parseSortingLayers(globalOptions.sortingLayers)),
|
|
46
|
+
createSortByLayer(parseSortingLayers(globalOptions.sortingLayers?.layers)),
|
|
47
47
|
sortByYAxis,
|
|
48
48
|
sortByXAxis,
|
|
49
49
|
sortByZAxis,
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SortingLayer } from '../types';
|
|
2
|
+
export declare const parseSortingLayers: (sortingLayers?: SortingLayer[]) => Array<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -12,6 +12,7 @@ type ActionFn = (options: ActionFnOptions) => void;
|
|
|
12
12
|
export interface UiInitFnOptions {
|
|
13
13
|
scene: Scene;
|
|
14
14
|
templateCollection: TemplateCollection;
|
|
15
|
+
globalOptions: Record<string, unknown>;
|
|
15
16
|
gameStateObserver: Observer;
|
|
16
17
|
pushAction: (action: ActionFn) => void;
|
|
17
18
|
}
|
|
@@ -26,6 +27,7 @@ export declare class UiBridge extends System {
|
|
|
26
27
|
private scene;
|
|
27
28
|
private loadUiApp;
|
|
28
29
|
private templateCollection;
|
|
30
|
+
private globalOptions;
|
|
29
31
|
private gameStateObserver;
|
|
30
32
|
private actionsQueue;
|
|
31
33
|
private onUiInit?;
|
|
@@ -5,13 +5,14 @@ export class UiBridge extends System {
|
|
|
5
5
|
scene;
|
|
6
6
|
loadUiApp;
|
|
7
7
|
templateCollection;
|
|
8
|
+
globalOptions;
|
|
8
9
|
gameStateObserver;
|
|
9
10
|
actionsQueue;
|
|
10
11
|
onUiInit;
|
|
11
12
|
onUiDestroy;
|
|
12
13
|
constructor(options) {
|
|
13
14
|
super();
|
|
14
|
-
const { actorSpawner, resources, scene, templateCollection, } = options;
|
|
15
|
+
const { actorSpawner, resources, scene, templateCollection, globalOptions, } = options;
|
|
15
16
|
const loadUiApp = resources?.loadUiApp;
|
|
16
17
|
if (loadUiApp === undefined) {
|
|
17
18
|
throw new Error('UiBridge requires a UI loader. Please specify the loader in the resources section.');
|
|
@@ -20,6 +21,7 @@ export class UiBridge extends System {
|
|
|
20
21
|
this.scene = scene;
|
|
21
22
|
this.actorSpawner = actorSpawner;
|
|
22
23
|
this.templateCollection = templateCollection;
|
|
24
|
+
this.globalOptions = globalOptions;
|
|
23
25
|
this.gameStateObserver = new Observer();
|
|
24
26
|
this.actionsQueue = [];
|
|
25
27
|
}
|
|
@@ -33,6 +35,7 @@ export class UiBridge extends System {
|
|
|
33
35
|
this.onUiInit({
|
|
34
36
|
scene: this.scene,
|
|
35
37
|
templateCollection: this.templateCollection,
|
|
38
|
+
globalOptions: this.globalOptions,
|
|
36
39
|
gameStateObserver: this.gameStateObserver,
|
|
37
40
|
pushAction: this.pushAction.bind(this),
|
|
38
41
|
});
|
|
@@ -29,7 +29,7 @@ export class SceneProvider {
|
|
|
29
29
|
this.systems = systems;
|
|
30
30
|
this.resources = resources;
|
|
31
31
|
this.globalOptions = globalOptions.reduce((acc, option) => {
|
|
32
|
-
acc[option.name] = option.
|
|
32
|
+
acc[option.name] = option.options;
|
|
33
33
|
return acc;
|
|
34
34
|
}, {});
|
|
35
35
|
this.loadedScene = void 0;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export interface GlobalOption {
|
|
2
|
-
id: string;
|
|
3
2
|
name: string;
|
|
4
|
-
|
|
5
|
-
value: unknown;
|
|
3
|
+
options: Record<string, unknown>;
|
|
6
4
|
}
|
|
7
5
|
export interface ComponentConfig {
|
|
8
6
|
name: string;
|
|
@@ -11,20 +9,20 @@ export interface ComponentConfig {
|
|
|
11
9
|
export interface TemplateConfig {
|
|
12
10
|
id: string;
|
|
13
11
|
name: string;
|
|
14
|
-
components?:
|
|
15
|
-
children?:
|
|
12
|
+
components?: ComponentConfig[];
|
|
13
|
+
children?: TemplateConfig[];
|
|
16
14
|
}
|
|
17
15
|
export interface ActorConfig {
|
|
18
16
|
id: string;
|
|
19
17
|
name: string;
|
|
20
|
-
children?:
|
|
21
|
-
components?:
|
|
18
|
+
children?: ActorConfig[];
|
|
19
|
+
components?: ComponentConfig[];
|
|
22
20
|
templateId?: string;
|
|
23
21
|
}
|
|
24
22
|
export interface LevelConfig {
|
|
25
23
|
id: string;
|
|
26
24
|
name: string;
|
|
27
|
-
actors:
|
|
25
|
+
actors: ActorConfig[];
|
|
28
26
|
}
|
|
29
27
|
export interface SystemConfig {
|
|
30
28
|
name: string;
|
|
@@ -34,14 +32,14 @@ export interface SceneConfig {
|
|
|
34
32
|
id: string;
|
|
35
33
|
name: string;
|
|
36
34
|
levelId: string | null;
|
|
37
|
-
systems:
|
|
35
|
+
systems: SystemConfig[];
|
|
38
36
|
}
|
|
39
37
|
export interface Config {
|
|
40
|
-
scenes:
|
|
41
|
-
levels:
|
|
42
|
-
templates:
|
|
43
|
-
loaders:
|
|
38
|
+
scenes: SceneConfig[];
|
|
39
|
+
levels: LevelConfig[];
|
|
40
|
+
templates: TemplateConfig[];
|
|
41
|
+
loaders: SceneConfig[];
|
|
44
42
|
startSceneId: string | null;
|
|
45
43
|
startLoaderId: string | null;
|
|
46
|
-
globalOptions:
|
|
44
|
+
globalOptions: GlobalOption[];
|
|
47
45
|
}
|
package/build/events/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { AddActor, RemoveActor, LoadScene, LoadLevel, } from '../engine/events';
|
|
2
2
|
export type { AddActorEvent, RemoveActorEvent, LoadSceneEvent, LoadLevelEvent, } from '../engine/events';
|
|
3
|
-
export { SetCamera, GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, } from '../contrib/events';
|
|
4
|
-
export type { SetCameraEvent, GameStatsUpdateEvent, KeyboardInputEvent, MouseInputEvent, KeyboardControlEvent, MouseControlEvent, CollisionEnterEvent, CollisionStayEvent, CollisionLeaveEvent, AddForceEvent, AddImpulseEvent, } from '../contrib/events';
|
|
3
|
+
export { SetCamera, GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
|
|
4
|
+
export type { SetCameraEvent, GameStatsUpdateEvent, KeyboardInputEvent, MouseInputEvent, KeyboardControlEvent, MouseControlEvent, CollisionEnterEvent, CollisionStayEvent, CollisionLeaveEvent, AddForceEvent, AddImpulseEvent, SetAudioGroupVolumeEvent, SetAudioSourceVolumeEvent, } from '../contrib/events';
|
package/build/events/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { AddActor, RemoveActor, LoadScene, LoadLevel, } from '../engine/events';
|
|
2
|
-
export { SetCamera, GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, } from '../contrib/events';
|
|
2
|
+
export { SetCamera, GameStatsUpdate, KeyboardInput, MouseInput, CollisionEnter, CollisionStay, CollisionLeave, AddForce, AddImpulse, PlayAudio, StopAudio, SetAudioVolume, } from '../contrib/events';
|