wade method
This frame's waders heard on scene, dt seconds after the last:
a splash as each goes into water at WadingHearing.splashFrom or
faster, as loud as it goes, and not again for WadingHearing.hushSeconds; a
wash (ElementCues.wash) held to each in water at
WadingHearing.washFrom or faster, louder and faster the faster it
goes; a wader not given this frame is let go.
What racing played of its cars through a ford, folded in here: the game says where its bodies are and whether they are in water, and this hears them.
Implementation
void wade(AudioScene scene, Iterable<Wader> waders, double dt) {
final hearing = cues.wading;
final washing = <Held>[];
final seen = <int>{};
for (final w in waders) {
seen.add(w.key);
final was = _waders[w.key];
var hush = math.max(0.0, (was?.hush ?? 0.0) - dt);
final goesIn = w.wet && !(was?.wet ?? false);
if (goesIn && w.speed > hearing.splashFrom && hush <= 0.0) {
hush = hearing.hushSeconds;
scene.play(cues.splash, w.at, bus: bus).gain = (w.speed / hearing.loud)
.clamp(0.3, 1.0);
}
_waders[w.key] = _WaderHeard(wet: w.wet, hush: hush);
if (w.wet && w.speed > hearing.washFrom) {
washing.add(
Held(
key: w.key,
at: Vector3.copy(w.at),
gain: (w.speed / hearing.washLoud).clamp(0.2, 1.0),
rate: 0.9 + 0.3 * (w.speed / hearing.washFast).clamp(0.0, 1.0),
),
);
}
}
_waders.removeWhere((key, _) => !seen.contains(key));
_washes.hold(scene, washing);
}