@umicat/three-sdk 0.10.0 → 0.11.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/dist/GameAudio.d.ts +24 -1
- package/dist/GameAudio.js +49 -1
- package/package.json +1 -1
package/dist/GameAudio.d.ts
CHANGED
|
@@ -58,6 +58,13 @@ export declare class GameAudio {
|
|
|
58
58
|
private ctx;
|
|
59
59
|
private master;
|
|
60
60
|
private musicGain;
|
|
61
|
+
/** Everything that is not music, on its own knob.
|
|
62
|
+
*
|
|
63
|
+
* Effects used to connect straight to the master, which made "quieter
|
|
64
|
+
* music" and "quieter sound" the same lever — and they are the two things
|
|
65
|
+
* players most want to set separately. Someone who wants the track down
|
|
66
|
+
* wants to keep hearing what is shooting at them. */
|
|
67
|
+
private sfxGain;
|
|
61
68
|
private musicEl;
|
|
62
69
|
private musicName;
|
|
63
70
|
private readonly buffers;
|
|
@@ -65,7 +72,10 @@ export declare class GameAudio {
|
|
|
65
72
|
private readonly clips;
|
|
66
73
|
private readonly base;
|
|
67
74
|
private readonly ext;
|
|
68
|
-
|
|
75
|
+
/** Not readonly any more: it is the top of the music's range and the level
|
|
76
|
+
* `duck()` returns to, and both move when the player moves the slider. */
|
|
77
|
+
private musicVolume;
|
|
78
|
+
private sfxVolume;
|
|
69
79
|
private muted;
|
|
70
80
|
private readonly cleanups;
|
|
71
81
|
constructor(opts: GameAudioOptions);
|
|
@@ -87,6 +97,19 @@ export declare class GameAudio {
|
|
|
87
97
|
play(name: string): void;
|
|
88
98
|
/** Duck the music for a moment — for an ending that should be heard over it. */
|
|
89
99
|
duck(seconds?: number): void;
|
|
100
|
+
/**
|
|
101
|
+
* How loud the music is, 0 to 1, as a fraction of the mix it was given.
|
|
102
|
+
*
|
|
103
|
+
* Separate from mute, and both are kept: mute is a switch you flip on the way
|
|
104
|
+
* into a room and back on the way out, and losing the level you had set to
|
|
105
|
+
* find it back at 1 is a small betrayal. Muted, this still records what the
|
|
106
|
+
* player chose — unmuting restores it.
|
|
107
|
+
*/
|
|
108
|
+
setMusicVolume(v: number): void;
|
|
109
|
+
get musicLevel(): number;
|
|
110
|
+
/** How loud everything that is not music is, 0 to 1. */
|
|
111
|
+
setSfxVolume(v: number): void;
|
|
112
|
+
get sfxLevel(): number;
|
|
90
113
|
setMuted(on: boolean): void;
|
|
91
114
|
get isMuted(): boolean;
|
|
92
115
|
dispose(): void;
|
package/dist/GameAudio.js
CHANGED
|
@@ -38,10 +38,18 @@ export class GameAudio {
|
|
|
38
38
|
this.ctx = null;
|
|
39
39
|
this.master = null;
|
|
40
40
|
this.musicGain = null;
|
|
41
|
+
/** Everything that is not music, on its own knob.
|
|
42
|
+
*
|
|
43
|
+
* Effects used to connect straight to the master, which made "quieter
|
|
44
|
+
* music" and "quieter sound" the same lever — and they are the two things
|
|
45
|
+
* players most want to set separately. Someone who wants the track down
|
|
46
|
+
* wants to keep hearing what is shooting at them. */
|
|
47
|
+
this.sfxGain = null;
|
|
41
48
|
this.musicEl = null;
|
|
42
49
|
this.musicName = null;
|
|
43
50
|
this.buffers = new Map();
|
|
44
51
|
this.lastPlayed = new Map();
|
|
52
|
+
this.sfxVolume = 1;
|
|
45
53
|
this.muted = false;
|
|
46
54
|
this.cleanups = [];
|
|
47
55
|
this.clips = opts.clips;
|
|
@@ -88,6 +96,9 @@ export class GameAudio {
|
|
|
88
96
|
this.musicGain = this.ctx.createGain();
|
|
89
97
|
this.musicGain.gain.value = this.musicVolume;
|
|
90
98
|
this.musicGain.connect(this.master);
|
|
99
|
+
this.sfxGain = this.ctx.createGain();
|
|
100
|
+
this.sfxGain.gain.value = this.sfxVolume;
|
|
101
|
+
this.sfxGain.connect(this.master);
|
|
91
102
|
void this.loadAll();
|
|
92
103
|
}
|
|
93
104
|
// Called inside the gesture's call stack, and awaited before anything asks
|
|
@@ -180,7 +191,10 @@ export class GameAudio {
|
|
|
180
191
|
const g = ctx.createGain();
|
|
181
192
|
g.gain.value = spec?.volume ?? 0.5;
|
|
182
193
|
src.connect(g);
|
|
183
|
-
|
|
194
|
+
// Through the effects knob, not straight to the master. The clip's own
|
|
195
|
+
// `volume` is still its balance against the others; this is the player's
|
|
196
|
+
// opinion about all of them at once.
|
|
197
|
+
g.connect(this.sfxGain ?? this.master);
|
|
184
198
|
src.start();
|
|
185
199
|
// Nodes disconnect themselves when they end; without this they pile up as
|
|
186
200
|
// garbage the collector has to chase during play.
|
|
@@ -196,6 +210,40 @@ export class GameAudio {
|
|
|
196
210
|
this.musicGain.gain.linearRampToValueAtTime(this.musicVolume * 0.25, t + 0.2);
|
|
197
211
|
this.musicGain.gain.linearRampToValueAtTime(this.musicVolume, t + seconds);
|
|
198
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* How loud the music is, 0 to 1, as a fraction of the mix it was given.
|
|
215
|
+
*
|
|
216
|
+
* Separate from mute, and both are kept: mute is a switch you flip on the way
|
|
217
|
+
* into a room and back on the way out, and losing the level you had set to
|
|
218
|
+
* find it back at 1 is a small betrayal. Muted, this still records what the
|
|
219
|
+
* player chose — unmuting restores it.
|
|
220
|
+
*/
|
|
221
|
+
setMusicVolume(v) {
|
|
222
|
+
this.musicVolume = Math.max(0, Math.min(1, v));
|
|
223
|
+
if (this.musicGain && this.ctx) {
|
|
224
|
+
// Ramped, not assigned. A gain that jumps clicks, audibly, and a slider
|
|
225
|
+
// is a stream of tiny jumps.
|
|
226
|
+
this.musicGain.gain.setTargetAtTime(this.musicVolume, this.ctx.currentTime, 0.02);
|
|
227
|
+
}
|
|
228
|
+
// The fallback path, where the element could not be routed through the
|
|
229
|
+
// graph. Without this, the slider does nothing at all on those engines —
|
|
230
|
+
// and they are the ones nobody tests on.
|
|
231
|
+
if (this.musicEl && this.musicEl.volume !== undefined) {
|
|
232
|
+
try {
|
|
233
|
+
this.musicEl.volume = this.musicVolume;
|
|
234
|
+
}
|
|
235
|
+
catch { /* not fatal */ }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
get musicLevel() { return this.musicVolume; }
|
|
239
|
+
/** How loud everything that is not music is, 0 to 1. */
|
|
240
|
+
setSfxVolume(v) {
|
|
241
|
+
this.sfxVolume = Math.max(0, Math.min(1, v));
|
|
242
|
+
if (this.sfxGain && this.ctx) {
|
|
243
|
+
this.sfxGain.gain.setTargetAtTime(this.sfxVolume, this.ctx.currentTime, 0.02);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
get sfxLevel() { return this.sfxVolume; }
|
|
199
247
|
setMuted(on) {
|
|
200
248
|
this.muted = on;
|
|
201
249
|
if (this.master && this.ctx) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umicat/three-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Three.js runtime for Umicat games: the scene3d design format, its loader with physics, a kinematic character controller, and the Umicat platform via @umicat/platform-sdk.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|