Verstehen und Implementieren von 3D-Audio in GameMaker Studio

Was Sie erstellen werden

Audio ist ein entscheidender Bestandteil des gesamten Spielerlebnisses. GameMaker: Studio bietet eine relativ einfache Möglichkeit, 3D-Audio in Ihre Projekte zu integrieren. 

Um das Konzept von 3D-Audio besser zu verstehen, stellen Sie sich vor, Sie fügen einem spielergesteuerten Spielobjekt ein Paar Ohren hinzu. Wenn sich der Spieler einer Klangquelle innerhalb des Spiels nähert, wird die Lautstärke dieser Quelle lauter. Wenn sich der Spieler wegbewegt, nimmt die Lautstärke ab, bis sie schließlich stumm wird. Die Position des Players in Bezug auf die Audioquelle führt auch zu gerichtetem Stereo-Audio, und die auf ein sich bewegendes Objekt angewendete Schallgeschwindigkeit kann angewendet werden, um einen Doppler-Effekt zu erzeugen. 

Dieser Satz immersiver Audiofunktionen kann durch ein System von erreicht werden Audio-Emitter und ein Audio-Listener. In diesem Lernprogramm erstellen wir zwei Szenen, die 3D-Audio auf unterschiedliche Weise enthalten, wie im Demo-Video gezeigt. Sie können die Quelldateien und die kompilierte Demo-EXE von GitHub herunterladen.

3D-Audio verstehen

Die Konzepte für 3D-Audio sind in allen Spieleentwicklungsumgebungen ähnlich, da sie auf bekannten Regeln der realen Welt basieren: Der Klang wird lauter, wenn Sie sich der Quelle nähern, und der rechtsgerichtete Klang wird im rechten Ohr lauter. Diese Grundprinzipien können manuell durch die Berechnung des erreicht werden gewinnen und Ausgabe einer Audioquelle in Bezug auf ein bestimmtes Spielobjekt, aber GameMaker: Studio bietet eine Reihe leistungsfähiger und benutzerfreundlicher Funktionen, mit denen Sie die Audio-API direkt steuern können.

Der Emitter

Der Audio-Emitter fungiert in GameMaker: Studio als Quelle eines 3D-Sound-Assets. Der Emitter wird durch eine vom Benutzer erstellte Variable und eine Position definiert (x, y, z) das kann entweder sein statisch oder dynamisch. Die Lautstärke des Emitters wird mit gesteuert gewinnen und runterfallen Werte und Echtzeiteffekte können über die angewendet werden Tonhöhe und Geschwindigkeit Werte. Die Art und Weise, wie der Emitter mit dem Audiofall umgeht, wird durch das verwendete Entfernungsmodell bestimmt. Innerhalb einer Szene können mehrere Audio-Emitter vorhanden sein.

Der Zuhörer

Der Audio-Listener fungiert als "Ohren", die den vom Sender gesendeten 3D-Sound empfangen. Der Listener befindet sich an einer Position (x, y, z) das kann auch statisch oder dynamisch sein, aber das Orientierung Der Zuhörer ist genauso wichtig. 

Die Ausrichtung des Hörers bestimmt die genaue Richtung und den Winkel, den der Hörer "betrachtet". Die Standardausrichtung des Listeners in GameMaker: Studio führt dazu, dass der linke und der rechte Audiokanal für 3D-Audio umgekehrt werden. Dies wird später bei der Implementierung korrigiert.

Der Doppler-Effekt

Ohne auf eine ausführliche Erklärung des Dopplereffekts einzugehen, kann er als Änderung der Schallfrequenz in Bezug auf die Bewegung und Geschwindigkeit des Senders oder Zuhörers beschrieben werden. In GameMaker: Studio wird der Doppler-Effekt durch Zuweisen von Vektoren zur Geschwindigkeit des Audio-Senders oder Hörers erzielt. Um eine ausführliche Erklärung zu erhalten, lesen Sie den Doppler-Effekteintrag in Wikipedia.

3D-Audio implementieren

Die Implementierung von 3D-Audio in Ihrem GameMaker-Projekt erfolgt in drei Schritten. Sie müssen den Emitter in einem vorhandenen Spielobjekt richtig definieren, dieses Objekt im Raum platzieren und dem Emitter mitteilen, wann und wie ein Sound abgespielt wird. Sie müssen dann die Ausrichtung und Position des Listeners innerhalb eines vorhandenen Spielobjekts definieren, das sich in demselben Raum wie der Emitter befindet. 

Im ersten Schritt werden jedoch die Audio-Assets importiert und definiert.

Assets importieren

Beginnen Sie mit einem Klick auf Ressourcen in der GameMaker-Symbolleiste und Auswahl Sound erstellen aus dem Dropdown-Menü. Geben Sie einen Namen für das Sound-Asset ein und wählen Sie die gewünschten Soundattribute für Streaming und Dateikomprimierung aus. Dann in der Zieloptionen Abschnitt der Soundeigenschaften Klicken Sie im ersten Dropdown-Menü und wählen Sie 3D aus der Liste der Optionen.

Durch die Einstufung dieses Assets als 3D-Sound können wir die Audio-API von GameMaker auf einzigartige Weise nutzen.

Ein stationärer Emitter

In unserem ersten Beispiel erstellen wir eine Art isometrischer 3D-Audio-Instanz im Sim City-Stil mit einem stationären Emitter. Unser Listener wird an ein Spielobjekt gebunden, das dem Mauszeiger folgt, und der Emitter des 3D-Sounds bleibt in einem Objekt, das sich nicht bewegt. Dieses Objekt wird durch eine kleine Ansammlung von Gebäuden dargestellt, und der Emitter wird einen atmosphärischen Stadtklang mit geschäftigem Verkehr und Autohupen wiedergeben. 

Auf diese Weise können wir die Audioabweichungseigenschaften des 3D-Audiosystems testen und die Bedeutung der Zuhörerorientierung besser verstehen.

Den Listener erstellen

Unser 3D-Audio-Listener wird in einem Objekt vorhanden sein, das dem Mauszeiger folgt. In diesem Beispiel wird das Objekt durch ein Sprite identifiziert, das einer GPS-Markierung ähnelt. Das obj_listener Das Objekt enthält zwei wichtige Codeblöcke: einen im Erstellen Veranstaltung und eine in der Schritt Veranstaltung.

Drücke den Ereignis hinzufügen Taste und wählen Sie Erstellen a hinzufügen Erstellen Veranstaltung zu obj_listener. Zieh den Code ausführen Symbol aus der Steuerung Tab der obj_listener Eigenschaftenfenster in die Aktionen Abschnitt der Veranstaltung erstellen Panel. Doppelklicken Sie auf das Code ausführen Symbol, um den GML-Code-Editor zu öffnen, und fügen Sie die folgende Codezeile hinzu:

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

Dieser Code stellt sicher, dass das Listener-Objekt sofort nach dem Erstellen im 3D-Bereich positioniert wird, um zu suchen gegenüber den Bildschirm nach rechts. Audio von einem Emitter, der sich rechts vom Zuhörer befindet, ist im rechten Lautsprecher stärker präsent und umgekehrt. Dies ist die Standardeinstellung, die Sie in nahezu jeder Art der Listener-Implementierung in GameMaker: Studio verwenden möchten. 

Wenn Sie möchten, dass das linke und das rechte Audio ausgetauscht werden, verwenden Sie zur Orientierung folgenden Code:

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

Füge hinzu ein Schritt Veranstaltung zu obj_listener und ziehen Sie ein anderes Code ausführen Symbol in die Aktionen Panel. Öffnen Sie den GML-Code-Editor erneut und geben Sie die folgenden Codezeilen ein:

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

Dieser Code ermittelt die aktuelle Position des Mauszeigers und ordnet diese Koordinaten der Position des Mauszeigers zu obj_listener Objekt. Die Position des Audio-Listeners wird ebenfalls durch diese Koordinaten definiert. Indem Sie diesen Code in die Schritt Wir sorgen dafür, dass die obj_listener Das Objekt, das dazugehörige Sprite und der Listener selbst befinden sich immer am selben Ort, da das Schritt Event-Code wird zu jedem Frame zur Laufzeit ausgeführt. 

(Das 0 In diesem Code ist die Z-Position des Listeners. Da unser Spiel in 2D ist, ist unser Hörer immer dabei 0 auf der z-Achse.)

Öffnen Sie den Raum, in dem das Listener-Objekt angezeigt werden soll. Drücke den Objekte Klicken Sie auf die Registerkarte und klicken Sie in das Bedienfeld, um die Liste der verfügbaren Objekte anzuzeigen. Wählen Sie Ihr Listener-Objekt aus und klicken Sie in den Raum, um es zu platzieren. Die Startposition dieses Objekts spielt keine Rolle, da es zur Laufzeit an die Position des Mauszeigers angepasst wird. 

Das ist es für den Hörer. Jetzt müssen wir etwas erstellen, das der Zuhörer hören kann.

Den Emitter erstellen

Wie beim Hörer konzentrieren wir uns ausschließlich auf den Erstellen und Schritt Ereignisse des Emitterobjekts. In diesem Fall platzieren wir den Emitter im obj_city Objekt. 

Ergänzen Sie die Erstellen und Schritt Ereignisse zu obj_city ,und füge eine hinzu Code ausführen Aktion für beide Ereignisse.

Im GML-Code der Erstellen Ereignis, fügen Sie Folgendes hinzu:

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 ist der Name unseres neuen Emitters.)

Wir haben uns für das entschieden Exponentielle Entfernung Falloff - Modell für dieses Beispiel, da es einen stetigen Gewinnabfall mit einem starken Anstieg ergibt, sobald Sie die Referenzentfernung Punkt. Dadurch kann die 3D-Audio-Lautstärke sinken, je weiter Sie sich vom Objekt entfernen, ohne harte Sprünge, bis Sie sich der Quelle sehr nahe kommen. Eine vollständige Liste der Falloff-Modelle und ihre ausführlichen Beschreibungen finden Sie in der Dokumentation zu GameMakers Falloff-Modellen.

audio_emitter_falloff (Sender, falloff_ref, falloff_max, falloff_factor) Hier legen wir die Attribute des Falloff-Modells fest:

  • Emitter ist unser s_emit Variable. 
  • falloff_ref ist der Punkt, an dem der Volumenabfall beginnt. 
  • falloff_max ist der Punkt, an dem der Hörer den Sender nicht mehr hören kann.
  • falloff_factor ist eine in der audio_falloff_set_model Berechnung, um die Ergebnisse der Abnahme zu bestimmen. In unserem Beispiel verwenden wir den Standardwert von 1 damit unser s_emit Der Emitter fällt ab, sobald der Hörer 100 Pixel vom Sender entfernt ist, und der Hörer kann den Sender nicht in einem Abstand von mindestens 300 Pixel hören.

audio_play_sound_on (Sender, Sound, Loop, Priorität) So können wir den Emitter dazu bringen, unseren 3D-Sound zu spielen: 

  • Emitter ist unser s_emit Variable. 
  • klingen ist unser snd_cityaudio 3D-Audioobjekt, das wir zuvor importiert haben. 
  • Schleife legt fest, ob sich dieser Ton wiederholen soll oder nicht. 
  • Priorität ist ein Wert von 0 zu 100 Dies bestimmt die 'Wichtigkeit' des gespielten Sounds. Größere Zahlen repräsentieren Sounds mit höherer Priorität. 

In unserem Beispiel wird nur ein Sound gespielt, daher spielt die Priorität keine Rolle. Und da dieser Code in der ausgeführt wird Erstellen Wenn wir den Sound als Loop abspielen, wird dieses 3D-Audio-Asset abgespielt, sobald der Raum geladen ist, und es wird weiter abgespielt, bis der Befehl zum Stoppen angezeigt wird. Und das bringt uns zu einem sehr wichtiger schritt:

Dieses Audio-Asset wird abgespielt Auch wenn Sie einen anderen Raum laden, in dem sich der Emitter nicht befindet. Um zu verhindern, dass dieses Asset in einem anderen Raum als dem Raum abgespielt wird, in dem sich der Emitter befindet, müssen Sie ein hinzufügen Raumende Veranstaltung zu obj_city

In dem Aktionen Panel der Raumende Ereignis, fügen Sie ein anderes hinzu Code ausführen Symbol mit dem folgenden GML-Code:

sound_stop (snd_cityaudio);

Jetzt müssen Sie nur noch das Platzieren obj_city Objekt in den Raum, wie Sie den Hörer zuvor platziert haben. Führen Sie das Spiel aus, und experimentieren Sie mit der Position des Mauszeigers, um die Position des Listeners in Bezug auf den Sender zu ändern, um zu sehen, wie 3D-Audio in der Praxis funktioniert.

Ein Moving Emitter mit dem Doppler-Effekt

Im zweiten Beispiel hängen wir den Emitter an ein sich bewegendes Objekt an und wenden den Doppler-Effekt an, während Sie dasselbe Listener-Objekt verwenden, das wir zuvor erstellt haben. 

Ein Objekt bewegt sich von der rechten Seite des Bildschirms nach links. Wenn das Geschoss den Rand des Bildschirms erreicht, wird es umbrochen und beginnt dort, wo es begonnen hat. (Wir gehen nicht durch, wie diese Bewegung erzeugt wird.) Das Objekt der Kugel gibt einen Schleifenklang ab, der als "surrender" oder "summender" Ton bezeichnet werden kann. Wenn sich das Objekt dem Listener nähert, wird der Frequenz Der Sound ändert sich aufgrund des Doppler-Effekts.

Den Emitter erstellen

Füge hinzu ein Erstellen und ein Schritt Veranstaltung zum obj_bullet Objekt und fügen Sie das hinzu Code ausführen Aktion für beide Ereignisse.

In dem Erstellen Fügen Sie dem GML-Editor den folgenden Code hinzu:

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 ist der Name unseres neuen Emitters.

Dieser Emitter verwendet das gleiche Falloff-Modell, das im vorherigen Raum definiert wurde, da nur ein Typ von Falloff-Modell gleichzeitig aktiv sein kann und unser Originalmodell für dieses Beispiel geeignet ist. Die neuen Falloff-Eigenschaften verwenden eine Falloff-Referenz von 25 Pixel, ein Abfall von maximal 200 Pixel und einen Abfallfaktor von 2,5 zur Berechnung. Das snd_bullet Das 3D-Sound-Asset wird abgespielt, sobald das Objekt erstellt wurde, mit einer Priorität von 1, und wird auf unbestimmte Zeit wiederholt.

Im GML-Editor des Schritt Ereignis, fügen Sie diese Codezeile hinzu:

audio_emitter_position (s_emit2, x, y, 0);

Da sich das Objekt bewegt und sich die x- und y-Werte ständig ändern, wird die Position des Emitters bei jedem Schritt ebenfalls auf die neue Position aktualisiert.

Vergessen Sie nicht, das Aufzählungsobjekt dem Raum hinzuzufügen, und stellen Sie sicher, dass Sie das sound_stop (snd_bullet) Code für das Objekt Raumende Veranstaltung.

Erstellen des Doppler-Effekts

Das 3D-Soundsystem ist jetzt für das Aufzählungsobjekt vorhanden, und der Listener funktioniert einwandfrei, aber mit dem Doppler-Effekt wollen wir die Dinge interessanter gestalten. 

Das Hinzufügen des Doppler-Effekts ist eigentlich sehr einfach. Öffnen Sie einfach die Code ausführen Aktion in der obj_bullet Erstellen event, und fügen Sie die folgende Codezeile hinzu:

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

audio_emitter_velocity (Sender, vx, vy, vz) erlaubt uns, die Eigenschaften des Doppler-Effekts zu definieren: 

  • Emitter ist unser s_emit 2 Variable. 
  • vx ist die Geschwindigkeit (in Pixel pro Schritt) entlang der x-Achse. 
  • vy ist die Geschwindigkeit (in Pixel pro Schritt) entlang der y-Achse. 
  • vz gilt für die Geschwindigkeit entlang der Z-Achse, aber unser Spiel ist in 2D, also setzen wir dies auf 0

Typische Doppler-Effekt-Setups verwenden die hspeed und vspeed Variablen eines Objekts zur Bestimmung der Geschwindigkeitswerte, in diesem Fall verwenden wir jedoch nur den Wert -25 um einen realistischeren Bullet-Sound zu erzeugen. Sie können das Objekt mit folgendem Code testen, um den Unterschied festzustellen:

audio_emitter_velocity (s_emit2, hspeed, vspeed, 0);

Umsetzungsideen

3D-Audio kann Ihrem Spielprojekt mit minimalem Aufwand viel Tiefe und Atmosphäre verleihen. Hier sind nur einige Beispiele für den Einstieg:

  • Ein Versteckspiel, in dem Sie Audiohinweise anhören müssen, um ein verstecktes Objekt zu finden.
  • Strom- oder Brandgefahren in einem Plattformer, die Sie bei Annäherung vor den Gefahren warnen.
  • Ein Spiel im Frogger-Stil, bei dem Autos mit dem Doppler-Effekt an Ihnen vorbeirasten.
  • Fließendes Wasser in einer Höhle oder Wind, der durch einen Luftkanal bläst, um Sie zum Ausgang zu führen.
  • Ein Spionspiel, bei dem Sie sich einem Ziel nähern müssen, um ein Gespräch zu hören.