13.07.2026 19:25

Silnik gier 2D: dźwięk, który słyszysz z właściwej strony — audio pozycyjne

⏱️ 3 min czytania
Udostępnij:

Do tej pory dźwięki w silniku gier 2D w Moonlight Animate grały „płasko" — z tą samą głośnością i po środku, niezależnie od tego, gdzie w świecie był ich emiter. Teraz doszło audio pozycyjne (spatial 2D): źródło dźwięku umiejscowione w świecie cichnie z odległością od kamery i panuje w lewo/prawo wedle tego, po której stronie ekranu się znajduje.

Dwa sposoby użycia

1. Węzeł, który sam się aktualizuje. Ustaw na węźle AudioPlayer2D tryb pozycyjny — jego głośność i panorama są przeliczane co klatkę na podstawie pozycji węzła względem aktywnej kamery (słuchacza). Idealne dla ruchomych, ciągłych źródeł: przejeżdżający samochód, buczący generator, wodospad w tle. Gdy oddalasz kamerę — dźwięk cichnie; gdy źródło przesuwa się na prawo — słyszysz je bardziej z prawej.

-- (w scenie: AudioPlayer2D z positional=true, maxDist=600, panRange=400)
-- Nic więcej nie trzeba — silnik sam aktualizuje głośność i panoramę.

2. Strzał „w miejscu". mp.play_sound_at(ścieżka, x, y) odpala jednorazowy dźwięk w konkretnym punkcie świata — parametry przestrzenne liczone raz, w chwili odpalenia. Idealne dla zdarzeń: wybuch, trafienie, brzęk monety tam, gdzie coś się właśnie stało.

mp.play_sound_at("explosion.ogg", wybuch_x, wybuch_y)   -- głośność i strona wg pozycji kamery

Jak to liczy

  • Tłumienie liniowe: pełna głośność w promieniu minDist, potem równomierny spadek do zera przy maxDist. Prosto, przewidywalnie i deterministycznie — ta sama scena brzmi zawsze tak samo.
  • Panorama: zależna od poziomego przesunięcia względem słuchacza; osiąga skrajne lewo/prawo przy zadanym panRange (osobnym od zasięgu głośności, żeby dźwięk najpierw „przeszedł" na bok, a dopiero potem zniknął).
  • Słuchacz = aktywna kamera. Pozycja odsłuchu to środek bieżącej kamery świata. Gdy scena nie ma aktywnej kamery, dźwięk gra bez spatializacji (na swojej bazowej głośności) — żadnych niespodzianek.
  • Odporność: skrajne przypadki (zerowy zakres, śmieciowe wartości) są bezpiecznie obcinane — brak dzielenia przez zero, brak trzasków.

Detale inżynierskie

Rdzeń przestrzenny to czysta funkcja matematyczna (pozycja słuchacza + emitera → głośność i panorama), w pełni pokryta testami jednostkowymi niezależnie od warstwy audio. Wybór „aktywnej kamery" to jedna współdzielona funkcja używana zarówno przez audio, jak i przez system paralaksy — zamiast trzech kopii tej samej logiki. Nowe właściwości węzła zapisują się w scenie tylko gdy odbiegają od domyślnych, więc stare sceny pozostają bajtowo identyczne (pełna zgodność wsteczna).

Kolejny klocek dokładany do silnika gier 2D w Moonlight Animate — tym razem taki, który słychać.

📚 Powiązane posty

14.07.2026 22:19

Silnik gier: od szablonu do grywalnej gry RPG top-down

Startowy szablon silnika gier to teraz kompletny, grywalny wycinek gry RPG top-down: chodzenie po siatce, rozmowy z postaciami, przeciwnik goniący gdy...
Czytaj dalej →
14.07.2026 19:16

Moonlight Animate — system dialogów w grach

Silnik gier 2D w Moonlight Animate ma teraz kompletny system dialogów: kwestie z efektem maszyny do pisania, wybory z warunkami, zmienne fabularne i g...
Czytaj dalej →
14.07.2026 18:40

Moonlight Animate: ruchoma panorama dźwięku także w wyeksportowanym wideo

Dźwięk przejeżdżający z lewego do prawego głośnika brzmiał dobrze w podglądzie, ale eksport przez serwer zamrażał go w miejscu. Ostatnia luka parytetu...
Czytaj dalej →

📧 Bądź na bieżąco!

Zapisz się na listę oczekujących, aby otrzymywać powiadomienia o nowych postach na Dev Blog oraz informacje o starcie platformy Moonlight.