Kauguspõhine heli (distance-based audio)¶
Sissejuhatus¶
Kauguspõhine heli võimaldab mängusimulaatorites luua realistlikuma helikeskkonna, kus helitugevus sõltub mängija kaugusest heli allikast. See lähenemine aitab mängijal paremini tajuda ümbritsevat keskkonda.
Kauguspõhist heli kasutatakse olukordades, kus heliallikad paiknevad mängumaailmas kindlates kohtades ning mängija liikumine nende suhtes mõjutab helide tajumist. Näiteks võib see olla kasulik:
Taustamüra (nt elektriliinide sumin, veevulin) loomisel, mis muutub valjemaks, kui mängija läheneb allikale.
Hoiatussignaalide või ohtude märkamise hõlbustamiseks, kus heli tugevneb ohuallikale lähenedes.
Mängumaailma atmosfääri rikastamiseks, lisades dünaamilisi heliefekte vastavalt mängija asukohale.
Selles peatükis uurime kauguspõhise heli loomise põhimõtteid, tuginedes järgmisele näitele: Distance based sound example (libGDX)
Kauguspõhise heli rakendamine¶
1. Heliressursi laadimine¶
Esmalt tuleb laadida vajalik helifail, mida soovime mängus kasutada.
Siin loome Music objekti, mis esindab meie heliallikat. Fail
electric-sound.mp3
peaks asuma projekti assets kaustas.
Music electricSound = Gdx.audio.newMusic(Gdx.files.internal("electric-sound.mp3"));
2. Heli esitamine ja peatamine sõltuvalt kaugusest¶
Järgmisena määrame loogika, mis otsustab, millal heli esitada või peatada, sõltuvalt mängija kaugusest heliallikast.
Funktsioon canPlaySound()
kontrollib, kas mängija ei ole dialoogis,
cutscene on lõppenud ja mäng ei ole MENU
olekus. Kui kõik tingimused
on täidetud ja heli ei mängi, alustatakse esitust. Kui tingimused enam
ei kehti, peatatakse heli esitamine.
if (canPlaySound()) {
if (!electricSound.isPlaying()) {
electricSound.play();
}
updateElectricSoundVolume();
} else {
if (electricSound.isPlaying()) {
electricSound.pause();
}
}
3. Helitugevuse dünaamiline muutmine¶
Helitugevuse sujuvaks muutmiseks vastavalt kaugusele:
Arvutame mängija ja heliallika vahelise kauguse ning määrame helitugevuse vastavalt sellele. Kui mängija on väga lähedal, mängib heli maksimaalse tugevusega; kui kaugel, siis heli ei mängi üldse. Vahepealsetel kaugustel muutub helitugevus sujuvalt.
private void updateElectricSoundVolume() {
float maxDistance = 300f; // kaugus, mille juures heli on vaevukuuldav
float minDistance = 50f; // kaugus, mille juures heli on maksimaalse tugevusega
float maxVolume = 0.7f;
float distance = characterPosition.dst(lightning.getPosition()); // eeldades, et lightning-l on meetod getPosition()
if (distance < minDistance) {
electricSound.setVolume(maxVolume);
} else if (distance > maxDistance) {
electricSound.setVolume(0f);
} else {
// Lineaarne interpolatsioon minimaalse ja maksimaalse kauguse vahel
float volume = maxVolume * (1 - (distance - minDistance) / (maxDistance - minDistance));
electricSound.setVolume(volume);
}
}
4. Ressursside vabastamine¶
Ja muidugi ära unusta vabastada electricSound
objekti
poolt kasutatud ressursid.
electricSound.dispose();
Täiendavad võimalused ja optimeerimised¶
Helitugevuse muutmise sageduse piiramine¶
Helitugevuse pidev muutmine igal kaadril võib põhjustada jõudlusprobleeme. Selle vältimiseks võime piirata helitugevuse uuendamise sagedust, näiteks iga 200 millisekundi järel.
See lähenemine vähendab protsessori koormust, säilitades samas heli sujuvuse.
long lastUpdateTime = 0;
long updateInterval = 200; // millisekundites
public void update(float deltaTime) {
long currentTime = TimeUtils.millis();
if (currentTime - lastUpdateTime > updateInterval) {
updateElectricSoundVolume();
lastUpdateTime = currentTime;
}
}
Realistlikum helitugevuse langus¶
Helitugevuse langust kauguse suurenedes võib modelleerida realistlikumalt, kasutades pöördvõrdelist ruutfunktsiooni.
See tagab, et helitugevus väheneb kiiremini kauguse suurenedes, imiteerides reaalse maailma heli käitumist.
float distance = characterPosition.dst(lightning.getPosition());
float volume = maxVolume / (1 + distance * distance);
electricSound.setVolume(volume);
Stereoefektide lisamine¶
Kui soovite lisada stereoefekte, kus heli suund sõltub mängija asukohast
heliallikaga võrreldes, peate kasutama Sound
klassi ja määrama vasaku ja
parema kanali helitugevused eraldi. LibGDX-is saab seda teha järgmiselt:
Siin pan
väärtus vahemikus -1 (vasak) kuni 1 (parem) määrab heli suuna.
Sound sound = Gdx.audio.newSound(Gdx.files.internal("sound.wav"));
long soundId = sound.play();
sound.setPan(soundId, pan, volume);
Lähtekood¶
Vaata näidisprojekti GitHubis: GitHub