3D Audio begrijpen en implementeren in GameMaker Studio

Wat je gaat creëren

Audio is een cruciaal element van de algehele game-ervaring, en GameMaker: Studio biedt een relatief eenvoudige manier om 3D-audio in uw projecten te implementeren. 

Om een ​​beter begrip van het concept van 3D-audio te krijgen, stel je voor dat je een paar digitale oren toevoegt aan een door een speler bestuurd game-object. Terwijl de speler een geluidsbron binnen het spel nadert, wordt het volume van die bron luider; wanneer de speler weggaat, neemt het volume af tot het uiteindelijk stil wordt. De positie van de speler ten opzichte van de audiobron zal ook resulteren in directionele stereo-audio, en een geluidssnelheid toegepast op een bewegend object kan worden toegepast om een ​​Doppler-effect te creëren. 

Deze reeks meeslepende audiofuncties kan worden bereikt via een systeem van geluidszenders en een audio luisteraar. In deze zelfstudie maken we twee scènes waarin 3D-audio op verschillende manieren is verwerkt, zoals te zien is in de demovideo. Je kunt de bronbestanden en gecompileerde demo EXE downloaden van GitHub.

3D Audio begrijpen

De concepten die betrokken zijn bij 3D-audio zijn vergelijkbaar in alle game-ontwikkelomgevingen, omdat ze gebaseerd zijn op bekende regels uit de echte wereld: het geluid wordt luider naarmate je de bron nadert en het geluid dat aan je rechterkant komt, wordt luider in je rechteroor. Deze basisprincipes kunnen handmatig worden bereikt door de krijgen en uitgang van een audiobron met betrekking tot een specifiek game-object, maar GameMaker: Studio biedt een reeks krachtige en eenvoudig te gebruiken functies die u directe controle over de audio-API geven.

De zender

De audio-emitter fungeert als de bron van een 3D-geluidsvermogen in GameMaker: Studio. De emitter wordt gedefinieerd door een door de gebruiker gemaakte variabele en een positie (x, y, z) dat kan een van beide zijn statisch of dynamisch. Het volume van de zender wordt geregeld door krijgen en falloff waarden en real-time effecten kunnen worden toegepast via de toonhoogte en snelheid waarden. De manier waarop de emittent het afvallen van audio verwerkt, wordt bepaald door het toegepaste afstandsmodel. Meerdere audio-emitters kunnen binnen dezelfde scène bestaan.

De luisteraar

De audio-luisteraar fungeert als de "oren" die het 3D-geluid ontvangen dat door de zender wordt verzonden. De luisteraar bevindt zich op een positie (x, y, z) dat kan ook statisch of dynamisch zijn, maar de oriëntering van de luisteraar is net zo belangrijk. 

De oriëntatie van de luisteraar bepaalt de precieze richting en hoek waarnaar de luisteraar "kijkt". De standaard luisteraaroriëntatie in GameMaker: Studio resulteert in het omkeren van de linker en rechter audiokanalen voor 3D Audio, die we later tijdens de implementatie zullen corrigeren.

Het Doppler-effect

Zonder in te gaan op een langdurige en grondige uitleg van het Doppler-effect, kan dit worden omschreven als de verandering in frequentie van geluid in relatie tot de beweging en snelheid van de zender of luisteraar. In GameMaker: Studio wordt het Doppler-effect bereikt door vectoren toe te wijzen aan de snelheid van de audio-emitter of luisteraar. Voor een uitgebreide uitleg, lees het Doppler effect op Wikipedia.

3D-audio implementeren

Het implementeren van 3D-audio in uw GameMaker-project is een proces in drie stappen. U moet de emitter in een bestaand game-object correct definiëren, dit object in de ruimte plaatsen en de emitter vertellen wanneer en hoe een geluid moet worden afgespeeld. U moet dan de oriëntatie en positie van de luisteraar definiëren binnen een bestaand spelobject dat zich in dezelfde ruimte als de emitter bevindt. 

De eerste stap is echter het importeren en definiëren van de audio-items.

Activa importeren

Begin door op te klikken Middelen in de hoofdwerkbalk van Game Maker en selecteren Maak geluid uit het vervolgkeuzemenu. Voer een naam in voor het geluidsitem en selecteer de gewenste geluidsattributen voor streaming en bestandscompressie. Vervolgens in de Doel opties deel van de Geluidseigenschappen venster, klik op het eerste vervolgkeuzemenu en selecteer 3D in de lijst met opties.

Door dit item aan te wijzen als een 3D-geluid, kunnen we op een unieke manier gebruik maken van de audio-API van GameMaker.

Een stationaire zender

In ons eerste voorbeeld zullen we een soort isometrische Sim City-achtige versie van 3D-audio creëren met een stationaire zender. Onze luisteraar zal worden gekoppeld aan een spelobject dat de muiscursor volgt en de emitter van het 3D-geluid blijft in een object dat niet beweegt. Dit object wordt vertegenwoordigd door een klein cluster van gebouwen en de emittent speelt een ambient stadsbeeldgeluid met druk verkeer en claxons.. 

Hiermee kunnen we de audio-uitvaleigenschappen van het 3D-audiosysteem testen en kunnen we het belang van luisteraaroriëntatie beter begrijpen..

De luisteraar maken

Onze 3D-audio-luisteraar zal bestaan ​​binnen een object dat de muiscursor volgt. In dit voorbeeld wordt het object geïdentificeerd door een sprite die lijkt op een GPS-markering. De obj_listener object bevat twee belangrijke codeblokken: één in de creëren evenement, en een in de Stap evenement.

Klik op de Voeg evenement toe knop en selecteer creëren om een ​​toe te voegen creëren evenement naar obj_listener. Sleept de Voer code uit pictogram van de Controle tabblad van de obj_listener eigenschappenvenster in de acties deel van de Creëer evenement paneel. Dubbelklik op de Voer code uit pictogram om de GML-code-editor te openen en voeg de volgende regel code toe:

audio_listener_orientation (0,1,0,0,0,1);

Deze code zorgt ervoor dat zodra het luisteraarobject is gemaakt, het in 3D-ruimte wordt geplaatst om te kijken naar het scherm, rechts-boven. Audio afkomstig van een zender die zich rechts van de luisteraar bevindt, is meer aanwezig in de rechterluidspreker en vice versa. Dit is de standaard setup die je in bijna elk type listener-implementatie in GameMaker: Studio wilt gebruiken. 

Als je wilde dat de audio links en rechts werd verwisseld, dan zou je de volgende code gebruiken om te oriënteren:

audio_listener_orientation (0,1,0,0,0, -1);

Voeg een ... toe Stap evenement naar obj_listener en sleep een andere Voer code uit pictogram in de acties paneel. Open de GML-code-editor nogmaals en voer de volgende regels in:

x = mouse_x; y = mouse_y; audio_listener_position (x, y, 0);

Deze code vindt de huidige locatie van de muiscursor en wijst deze coördinaten toe aan de positie van de obj_listener voorwerp. De positie van de audio-luisteraar wordt ook bepaald door deze coördinaten. Door deze code in de Stap evenement, we zorgen ervoor dat de obj_listener object, de bijbehorende sprite en de luisteraar zelf bevinden zich altijd op dezelfde locatie, aangezien de Stap gebeurteniscode wordt uitgevoerd tijdens elk frame tijdens runtime. 

(De 0 in deze code staat de z-positie van de luisteraar. Aangezien onze game in 2D is, zal onze luisteraar er altijd zijn 0 op de z-as.)

Open de ruimte waar u het luisteraarobject wilt laten verschijnen. Klik op de Voorwerpen klik en klik binnen het paneel om de lijst met beschikbare objecten weer te geven. Selecteer uw listener-object en klik binnen de ruimte om het te plaatsen. De startpositie van dit object doet er niet toe, omdat het wordt bijgewerkt om overeen te komen met de positie van de muisaanwijzer tijdens runtime. 

Dat is het voor de luisteraar. Nu moeten we iets maken dat de luisteraar kan horen.

De emitter maken

Net als bij de luisteraar, richten we ons uitsluitend op de creëren en Stap gebeurtenissen van het emitter-object. In dit geval plaatsen we de emitter in de obj_city voorwerp. 

Voeg de toe creëren en Stap evenementen om obj_city ,en voeg een toe Voer code uit actie voor beide evenementen.

In de GML-code van de creëren evenement, voeg het volgende toe:

s_emit = audio_emitter_create (); audio_falloff_set_model (audio_falloff_exponent_distance); audio_emitter_falloff (s_emit, 50, 200, 1); audio_play_sound_on (s_emit, snd_cityaudio, true, 1);

(s_emit is de naam van onze nieuwe zender.)

We kozen voor de Exponentiële afstand falloff-model voor dit voorbeeld omdat het een gestage gain-fall-off geeft met een sterke toename zodra u voldoet aan de Referentie afstand punt. Hierdoor kan het 3D-geluidsvolume afnemen naarmate u verder weg bent van het object, soepel, zonder harde sprongen, totdat u zeer dicht bij de bron komt. Voor een volledige lijst van falloff-modellen en hun gedetailleerde beschrijvingen, lees de documentatie van Falloff Models van GameMaker.

audio_emitter_falloff (emitter, falloff_ref, falloff_max, falloff_factor) is waar we de attributen van het falloff-model hebben ingesteld:

  • emitter is onze s_emit veranderlijk. 
  • falloff_ref is het punt waarop de volumeafname begint te beginnen. 
  • falloff_max is het punt waarop de luisteraar de emitter niet langer kan horen.
  • falloff_factor is een nummer dat wordt gebruikt in de audio_falloff_set_model berekening om de resultaten van de falloff te bepalen. In ons voorbeeld gebruiken we de standaardwaarde van 1 zodat onze s_emit de emitter begint af te vallen zodra de luisteraar 100 pixels verwijderd is van de zender en de luisteraar de emitter niet op een afstand van 300 pixels of groter kan horen.

audio_play_sound_on (emitter, geluid, loop, prioriteit) is hoe we de zender laten beginnen met het spelen van ons 3D-geluid: 

  • emitter is onze s_emit veranderlijk. 
  • geluid is onze snd_cityaudio 3D-audio-item dat we eerder hebben geïmporteerd. 
  • lus bepaalt of dit geluid moet worden herhaald of niet. 
  • prioriteit is een waarde van 0 naar 100 dat bepaalt het 'belang' van het geluid dat wordt afgespeeld - grotere getallen vertegenwoordigen geluiden met een hogere prioriteit. 

In ons voorbeeld hebben we maar één geluid dat wordt afgespeeld, dus de prioriteit doet er niet toe. En aangezien deze code wordt uitgevoerd in de creëren en we hebben ervoor gekozen om het geluid in een lus te zetten. Dit 3D-audio-item wordt afgespeeld zodra de kamer is geladen en blijft spelen totdat wordt aangegeven dat het moet stoppen. En dat brengt ons bij een heel belangrijke stap:

Dit audio-item wordt afgespeeld zelfs wanneer u een andere ruimte laadt die de emitter niet bevat. Om effectief te voorkomen dat dit item in een andere kamer dan in de ruimte met de emitter wordt afgespeeld, moeten we een toevoegen Room End evenement naar obj_city

In de acties paneel van de Room End evenement, voeg een ander toe Voer code uit pictogram met de volgende GML-code:

sound_stop (snd_cityaudio);

Nu hoeft alleen nog het obj_city object in de kamer alsof je de luisteraar eerder hebt geplaatst. Voer het spel uit en experimenteer met de positie van de muiscursor om de locatie van de luisteraar ten opzichte van de zender te wijzigen om precies te zien hoe 3D-audio in de praktijk werkt.

Een bewegende zender met het Doppler-effect

In het tweede voorbeeld koppelen we de emitter aan een bewegend object en passen we het Doppler-effect toe terwijl we hetzelfde listenerobject gebruiken dat we eerder hebben gemaakt. 

Een kogelobject beweegt van de rechterkant van het scherm naar links. Wanneer de kogel de rand van het scherm bereikt, loopt deze rond en gaat verder waar hij is begonnen. (We gaan niet door hoe deze beweging te maken.) Het opsommingsteken geeft een lusgeluid dat kan worden omschreven als een "suizend" of "zoemend" geluid. Wanneer het object de luisteraar nadert, de frequentie van het geluid zal veranderen, vanwege het Doppler-effect.

De emitter maken

Voeg een ... toe creëren en een Stap evenement voor de obj_bullet object en voeg de Voer code uit actie voor beide evenementen.

In de creëren evenement, voeg de volgende code toe aan de GML-editor:

s_emit2 = audio_emitter_create (); audio_emitter_falloff (s_emit2, 25, 200, 1.5); audio_play_sound_on (s_emit2, snd_bullet, true, 1);

Hier, s_emit2 is de naam van onze nieuwe zender.

Deze emitter gebruikt hetzelfde valutamodel als gedefinieerd in de vorige kamer, omdat slechts één type falloff-model tegelijk actief kan zijn en ons oorspronkelijke model geschikt is voor dit voorbeeld. De nieuwe falloff-eigenschappen maken gebruik van een falloff-referentie van 25 pixels, een falloff maximum van 200 pixels en een falloff-factor van 2.5 voor berekening. De snd_bullet 3D-geluidsvermogen begint te spelen zodra het object is gemaakt, met een prioriteit van 1, en zal oneindig herhalen.

In de GML-editor van de Stap evenement, voeg deze regel toe:

audio_emitter_position (s_emit2, x, y, 0);

Omdat het object beweegt en de x- en y-waarden voortdurend veranderen, wordt de positie van de emitter ook bij elke stap bijgewerkt naar de nieuwe positie.

Vergeet niet om het opsommingstekenobject toe te voegen aan de ruimte en zorg ervoor dat u het opsommingsteken toevoegt sound_stop (snd_bullet) code naar de objecten Room End evenement.

Het Doppler-effect creëren

Het 3D-geluidssysteem is nu op zijn plaats voor het bullet-object en de luisteraar werkt naar behoren, maar laten we de dingen interessanter maken met het Doppler-effect. 

Het toevoegen van het Doppler-effect is eigenlijk heel eenvoudig. Open gewoon de Voer code uit actie in de obj_bullet creëren evenement, en voeg de volgende regel code toe:

audio_emitter_velocity (s_emit2, -25, -25, 0);

audio_emitter_velocity (emitter, vx, vy, vz) stelt ons in staat de eigenschappen van het Doppler-effect te definiëren: 

  • emitter is onze s_emit 2 veranderlijk. 
  • vx is de snelheid (in pixels per stap) langs de x-as. 
  • vy is de snelheid (in pixels per stap) langs de y-as. 
  • vz is van toepassing op de snelheid langs de z-as, maar ons spel bevindt zich in 2D, dus we bepalen dit 0

Typische Doppler-effectopstellingen gebruiken de hspeed en vspeed variabelen van een object om de snelheidswaarden te bepalen, maar in dit geval gebruiken we gewoon een waarde van -25 om een ​​realistisch kogelgeluid te creëren. U kunt het object testen met de volgende code om het verschil op te merken:

audio_emitter_velocity (s_emit2, hspeed, vspeed, 0);

Implementatie-ideeën

3D-audio kan een grote diepte en sfeer toevoegen aan uw gameproject, met minimale inspanning vereist. Hier zijn slechts enkele voorbeelden om u op weg te helpen:

  • Een verstoppertje waarbij je naar audiokenwijzingen moet luisteren om een ​​verborgen object te vinden.
  • Elektriciteit of brandgevaar in een platformgame die u waarschuwt voor de gevaren als u dichterbij komt.
  • Een spel in Frogger-stijl waarbij auto's langs je zoeven met het Doppler-effect.
  • Stromend water in een grot of wind die door een luchtkanaal blaast om je naar de uitgang te leiden.
  • Een spionspel waarbij je dicht bij een doelwit moet komen om een ​​gesprek te horen.