Tworzenie wieloplatformowej gry WebGL za pomocą Babylon.js

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ Oto wyzwanie dla Ciebie: co powiesz na zbudowanie gry 3D w weekend? Babylon.js to framework JavaScript do tworzenia gier 3D za pomocą HTML5, WebGL i Web Audio , stworzony przez Ciebie i zespół Babylon.js. Aby uczcić nową wersję 2.3 biblioteki, postanowiliśmy stworzyć nowe demo o nazwie „Sponza”, aby pokazać, co można zrobić z silnikiem WebGL i HTML5, jeśli chodzi o budowanie wspaniałych gier w dzisiejszych czasach. Pomysł polegał na stworzeniu spójnego, podobnego, jeśli nie identycznego, doświadczenia na wszystkich platformach obsługiwanych przez WebGL i próbie dotarcia do funkcji aplikacji natywnych. W tym artykule wyjaśnię, jak to wszystko działa razem, wraz z różnymi wyzwaniami, z którymi się zmierzyliśmy, oraz lekcjami, których nauczyliśmy się podczas jego tworzenia.

Oto wyzwanie dla Ciebie: co powiesz na zbudowanie gry 3D w weekend? Babylon.js to framework JavaScript do tworzenia gier 3D za pomocą HTML5, WebGL i Web Audio , stworzony przez Ciebie i zespół Babylon.js. Aby uczcić nową wersję 2.3 biblioteki, postanowiliśmy stworzyć nowe demo o nazwie „Sponza”, aby pokazać, co można zrobić z silnikiem WebGL i HTML5, jeśli chodzi o budowanie wspaniałych gier w dzisiejszych czasach.

Pomysł polegał na stworzeniu spójnego, podobnego, jeśli nie identycznego, doświadczenia na wszystkich platformach obsługiwanych przez WebGL i próbie dotarcia do funkcji aplikacji natywnych. W tym artykule wyjaśnię, jak to wszystko działa razem, wraz z różnymi wyzwaniami, z którymi się zmierzyliśmy, oraz lekcjami, których nauczyliśmy się podczas jego tworzenia.

Dalsze czytanie na SmashingMag:

  • Tworzenie shaderów za pomocą Babylon.js
  • Korzystanie z interfejsu API gamepada w grach internetowych
  • Wprowadzenie do modelowania wielokątnego i Three.js
  • Jak stworzyć responsywną 8-bitową maszynę perkusyjną?

Aby osiągnąć ten cel, Sponza wykorzystuje szereg funkcji HTML5, takich jak WebGL, Web Audio, a także Pointer Events (szeroko obsługiwane teraz dzięki jQuery PEP polyfill), Gamepad API, IndexedDB, HTML5 AppCache, przejście/animacja CSS3, flexbox i Fullscreen API. Możesz przetestować wersję demonstracyjną Sponzy na swoim komputerze stacjonarnym, telefonie komórkowym lub Xbox One.

Więcej po skoku! Kontynuuj czytanie poniżej ↓
Sala w grze Sponza
Sala główna w interaktywnym demo Sponza.

Odkrywanie wersji demo

Najpierw zaczniesz od automatycznie animowanej sekwencji, dając napisy końcowe temu, kto zbudował scenę. Większość członków zespołu wywodzi się ze sceny demonstracyjnej. Odkryjesz, że jest to ważna część kultury twórców 3D. Z mojej strony byłem na Atari, podczas gdy David Catuhe był na Amidze, która wciąż jest regularnym źródłem konfliktów między nami, wierzcie lub nie. Trochę kodowałem, ale głównie komponowałem muzykę w mojej grupie demo. Byłem wielkim fanem Future Crew, a dokładniej Purple Motion, mojego ulubionego kompozytora sceny demo wszech czasów. Ale nie odbiegajmy od tematu.

W przypadku Sponzy, oto współtwórcy:

  • Michel Rousseau aka „Mitch” wykonał niezwykłe animacje wizualne i optymalizacje renderowania, działając jako artysta 3D. Do wygenerowania tego, co widzisz, wykorzystano model Sponza udostępniony bezpłatnie przez firmę Crytek na ich stronie internetowej i wykorzystano eksporter 3DS Max.
  • David Catuhe aka „deltakosh” i ja wykonaliśmy główną część silnika Babylon.js, a także cały kod do wersji demonstracyjnej (niestandardowy program ładujący, efekty specjalne dla trybu demonstracyjnego z wykorzystaniem postprocesów przejścia do czerni itp.), a także nowy typ kamery o nazwie „ UniversalCamera ” obsługujący wszystkie typy wejść w sposób ogólny.
  • Muzykę skomponowałem przy użyciu banku brzmień Renoise i EastWest Symphonic Orchestra. Jeśli jesteś zainteresowany, podzieliłem się już moim przepływem pracy i procesem w artykule na temat komponowania muzyki do gry World Monger na Windows 8 przy użyciu trackera Renoise i wtyczek East West VST
  • Julien Moreau-Mathis pomógł nam, budując nowe narzędzie, które pomaga artystom 3D sfinalizować pracę między narzędziami do modelowania (3DS Max, Blender) a wynikiem końcowym. Na przykład Michel używał go do testowania i dostrajania różnych animowanych kamer oraz do wstrzykiwania cząstek na scenę.

Jeśli poczekasz do końca automatycznej sekwencji aż do „epickiego zakończenia”, zostaniesz automatycznie przełączony w tryb interaktywny. Jeśli chcesz ominąć tryb demonstracyjny, po prostu kliknij ikonę aparatu lub naciśnij A na gamepadzie.

W trybie interaktywnym, jeśli korzystasz z komputera Mac lub PC, będziesz mógł poruszać się po scenie za pomocą klawiatury/myszy jak w grze FPS. Jeśli korzystasz ze smartfona, możesz poruszać się za pomocą jednego dotknięcia (i 2 do obracania aparatu). Wreszcie na Xbox One możesz użyć gamepada (lub komputera stacjonarnego, jeśli podłączasz do niego gamepad). Ciekawostka: na dotykowym komputerze z systemem Windows możesz potencjalnie używać 3 typów danych wejściowych w tym samym czasie.

Atmosfera jest inna w trybie interaktywnym. Masz trzy źródła dźwięku burzy rozmieszczone losowo w środowisku 3D, wieje wiatr i pękają w ogniu na każdym rogu. W obsługiwanych przeglądarkach (Chrome, Firefox, Opera i Safari) możesz nawet przełączać się między normalnym trybem głośnika a trybem słuchawkowym, klikając dedykowaną ikonę. Następnie użyje binauralnego renderowania dźwięku Web Audio, aby uzyskać bardziej realistyczną symulację dźwięku — jeśli słuchasz przez słuchawki.

Aby zapewnić pełne wrażenia z aplikacji, wygenerowaliśmy ikony i kafelki dla wszystkich platform. Oznacza to na przykład, że w systemie Windows 810 możesz przypiąć aplikację internetową do menu „Start”. Dostępnych jest nawet wiele rozmiarów:

Możesz przypiąć aplikację internetową do menu Start
Po wygenerowaniu ikon i kafelków możesz przypiąć aplikację internetową do menu „Start”.
Aplikację internetową można przypiąć do menu Start w systemie iOS, Android lub Windows Mobile
Działa również na Twoim iPhonie, urządzeniu z Androidem lub Windows Mobile.

Najpierw offline!

Po całkowitym załadowaniu wersji demonstracyjnej możesz przełączyć telefon w tryb samolotowy, aby odciąć łączność, i kliknąć ikonę Sponza. Aplikacja internetowa będzie nadal zapewniać pełne wrażenia z renderowania WebGL, dźwięku internetowego 3D i obsługi dotyku. Przełącz go na pełny ekran, a dosłownie nie poczujesz różnicy między wersją demonstracyjną a natywną aplikacją.

W tym celu używamy warstwy IndexedDB dostępnej natywnie w Babylon.js. Scena (format JSON) i zasoby (tekstury JPG/PNG oraz MP3 dla muzyki i dźwięków) są przechowywane w IDB. Warstwa IDB w połączeniu z pamięcią podręczną aplikacji HTML5 zapewnia wtedy wrażenia offline. Aby dowiedzieć się więcej o tej części i o tym, jak skonfigurować grę, aby uzyskać podobne wyniki, możesz przeczytać artykuł Używanie IndexedDB do obsługi zasobów 3D WebGL: udostępnianie informacji zwrotnych i wskazówek dotyczących Babylon.JS i buforowanie zasobów w IndexedDB w Babylon.js

Xbox One cieszy się pokazem

Last but not least, to samo demo działa bezbłędnie w MS Edge na twoim Xbox One:

MS Edge na Xbox One

Naciśnij A , aby przejść do trybu interaktywnego . Xbox One powiadomi Cię, że możesz teraz poruszać się za pomocą gamepada w scenie 3D:

Powiadomienie Xbox One: możesz teraz poruszać się za pomocą gamepada w scenie 3D

Przypomnijmy więc krótko.

Ta sama baza kodu działa na komputerach Mac, Linux, Windows na MS Edge, Chrome, Firefox, Opera i Safari, na iPhone/iPad, na urządzeniach z Androidem z Chrome lub Firefox, Firefox OS i na Xbox One! Czy to nie fajne? Czy możesz kierować reklamy na tak wiele urządzeń z pełnoprawnym, natywnym interfejsem bezpośrednio ze swojego serwera internetowego?

Podzieliłem się już moim podekscytowaniem związanym z potencjałem technologii w poprzednim artykule w Internecie: kolejna granica gier?

Zhakuj scenę za pomocą warstwy debugowania

Jeśli chcesz zrozumieć, w jaki sposób Michel opanowuje magię modelowania 3D, możesz zhakować scenę za pomocą narzędzia Babylon.js Debug Layer . Aby włączyć ją na komputerze z klawiaturą, naciśnij CMD/CTRL + SHIFT + D , a jeśli używasz pada na PC lub Xbox, naciśnij Y . Należy pamiętać, że wyświetlanie warstwy debugowania kosztuje trochę wydajności ze względu na pracę związaną z komponowaniem, którą musi wykonać silnik renderujący. Wyświetlane FPS są więc nieco mniej ważne niż prawdziwy FPS, który masz bez wyświetlonej warstwy debugowania.

Przetestujmy to na przykład na komputerze.

Przesuń się w pobliże głowy lwa i wytnij kanał wypukłości z potoku naszego shadera:

Głowa lwa

Powinieneś zobaczyć, że głowa jest teraz mniej realistyczna. Graj z innym kanałem, aby sprawdzić, co się dzieje.

Możesz także odciąć dynamiczny silnik błyskawicy lub wyłączyć silnik kolizji, aby latać lub poruszać się po ścianach. Na przykład wyłącz pole wyboru „ kolizje ” i leć na pierwsze piętro. Umieść aparat przed czerwonymi flagami. Widać, jak się lekko poruszają. Michel wykorzystał obsługę kości/szkieletów w Babylon.js, aby je przenieść. Teraz wyłącz opcję „ szkielety ” i powinny przestać się poruszać:

Opcja szkieletów

W końcu możesz wyświetlić drzewo siatek w prawym górnym rogu. Możesz je włączyć lub wyłączyć, aby całkowicie przerwać pracę wykonaną przez Michela:

Usunięcie geometrii, kanałów modułu cieniującego lub niektórych opcji silnika może pomóc w rozwiązywaniu problemów z wydajnością na konkretnym urządzeniu, aby zobaczyć, co obecnie kosztuje zbyt dużo. Możesz także sprawdzić, czy jesteś ograniczony procesorem lub procesorem graficznym, chociaż przez większość czasu będziesz ograniczony procesorem w WebGL ze względu na jednowątkowy charakter JavaScript. Wreszcie, narzędzie jest również bardzo przydatne, aby pomóc Ci dowiedzieć się, jak scena została zbudowana przez artystę 3D.

Nawiasem mówiąc, działa całkiem nieźle na Xbox One:

Xbox jeden sponza

Wyzwania

Po drodze napotkaliśmy szereg problemów i wyzwań związanych z budowaniem wersji demo. Przyjrzyjmy się niektórym z nich szczegółowo.

Wydajność WebGL i kompatybilność między platformami

Strona programowania była prawdopodobnie najłatwiejsza do rozwiązania, ponieważ jest całkowicie obsługiwana przez sam silnik Babylon.js. Używamy niestandardowej architektury shaderów, która dostosowuje się do platformy , próbując znaleźć najlepszy shader dostępny dla aktualnej przeglądarki/GPU przy użyciu różnych rozwiązań awaryjnych. Pomysł polega na obniżeniu jakości i złożoności silnika renderującego, dopóki nie uda nam się wyświetlić czegoś znaczącego na ekranie.

Babylon.js jest oparty głównie na WebGL 1.0, aby zagwarantować, że zbudowane na nim doświadczenia 3D będą działać praktycznie wszędzie. Został zbudowany z myślą o filozofii sieciowej, więc stopniowo ulepszamy proces kompilacji shaderów. Jest to całkowicie przejrzyste dla artysty 3D, który przez większość czasu nie chce zajmować się tymi zawiłościami.

Mimo to artysta 3D odgrywa bardzo ważną rolę w optymalizacji wydajności. Musi znać platformę, na którą kieruje reklamy, obsługiwane funkcje i ograniczenia. Nie możesz wziąć zasobów pochodzących z gier AAA stworzonych dla wysokiej klasy procesorów graficznych i DirectX 12 i po prostu zintegrować je z grą działającą na silniku WebGL. Twierdzę, że dzisiejsze kierowanie na WebGL jest dość podobne do pracy, którą musisz wykonać, aby zoptymalizować doświadczenia na urządzeniach mobilnych, z odrobiną dodatkowego JavaScriptu, który musi być wysoce jednowątkowy.

Mitch jest w tym wyjątkowo dobry: optymalizuje tekstury, wstępnie oblicza błyskawice, aby wtopić je w tekstury, maksymalnie zmniejsza liczbę wywołań losowania itp. Ma za sobą lata doświadczenia i widział różne generacje Sprzęt i silniki 3D (od PowerVR/3DFX po dzisiejsze procesory graficzne), które naprawdę pomogły w stworzeniu demonstracji.

Opowiedział już trochę o tych podstawach w swoich artykułach na temat Real Time 3D: robienie demonstracji dla WebGL Cels-Basics i już kilka razy udowodnił, że można stworzyć całkiem fascynujące wrażenia wizualne w sieci z wysoką wydajnością na małych zintegrowanych procesorach graficznych, np. w Sceny demo Mansion, Hill Valley lub Espilit. Jeśli jesteś zainteresowany, poświęć trochę czasu na obejrzenie jego wykładu na temat NGF2014 – Tworzenie zasobów 3D dla świata mobilnego i internetu, punkt widzenia projektanta 3D, w którym podzielił się swoim doświadczeniem i tym, jak udało mu się zoptymalizować scenę Hill Valley od mniej niż 1 fps do 60 fps.

Pierwotnym celem Sponzy było zbudowanie dwóch scen. Jeden do komputerów stacjonarnych i jeden do urządzeń mobilnych o mniejszej złożoności, mniejszych teksturach i prostszych siatkach i geometriach. Ale podczas naszych testów w końcu odkryliśmy, że wersja komputerowa działa również całkiem dobrze na urządzeniach mobilnych, ponieważ może działać z prędkością do 60 klatek na sekundę na iPhonie 6s lub Android OnePlus 2. Następnie postanowiliśmy nie kontynuować pracy nad prostszą wersją mobilną.

Ale znowu, prawdopodobnie lepiej byłoby mieć czyste podejście do urządzeń mobilnych w Sponza, aby osiągnąć 30 klatek na sekundę + na wielu urządzeniach mobilnych, a następnie ulepszyć scenę dla zaawansowanych urządzeń mobilnych i komputerów stacjonarnych. Mimo to większość opinii, które otrzymaliśmy do tej pory na Twitterze, wydaje się wskazywać, że ostateczny wynik działa bardzo dobrze na większości urządzeń. Trzeba przyznać, że Sponza została zoptymalizowana na GPU HD4000 (zintegrowany z Intel Core i5), który jest mniej więcej odpowiednikiem rzeczywistych GPU z najwyższej półki.

Byliśmy bardzo zadowoleni z wyników, które udało nam się osiągnąć. Sponza używa naszego shadera z włączonymi ambient , diffuse , bump , specular i reflection . Mamy kilka cząstek symulujących małe pożary na każdym rogu, animowane kości dla czerwonych flag, dźwięki pozycjonowane w 3D i kolizje podczas poruszania się w trybie interaktywnym.

Technicznie rzecz biorąc, w scenie mamy 98 siatek, które generują do 377781 wierzchołków, 16 aktywnych kości, ponad 60 cząstek, które mogą generować do 36 wywołań losowania. Czego się nauczyliśmy? Jedno jest pewne: mniejsza liczba wywołań remisowych jest kluczem do optymalnej wydajności, zwłaszcza w sieci.

Ładowarka

W przypadku Sponza chcieliśmy stworzyć nowy loader, inny niż domyślny, którego używamy na stronie BabylonJS, aby mieć czystą i dopracowaną aplikację internetową. Następnie poprosiłem Michela, aby zasugerował coś nowego.

Najpierw przesłał mi następujący ekran:

Wyjaśnienie ładowania

Rzeczywiście, ekran wygląda bardzo ładnie, gdy po raz pierwszy na niego spojrzysz. Ale wtedy możesz zacząć się zastanawiać, jak sprawić, by działał na wszystkich urządzeniach, w naprawdę responsywny sposób? Rozwiążmy to.

Porozmawiajmy najpierw o tle. Efekt rozmycia stworzony przez Michela był przyjemny, ale nie działał dobrze we wszystkich rozmiarach okien i rozdzielczościach, generując morę. Następnie zastąpiłem go „klasycznym” zrzutem ekranu sceny. Chciałem jednak, aby tło całkowicie wypełniało ekran bez czarnych pasów i bez rozciągania obrazu, aby złamać proporcje.

Rozwiązanie pochodzi głównie z CSS background-size: cover + centrowanie obrazu na osiach X i Y. W rezultacie mamy doświadczenie, którego szukałem, niezależnie od używanego współczynnika ekranu:

Sponza 100 procent

Pozostałe części używają starego dobrego pozycjonowania CSS opartego na procentach. Dobra, posortuj to, jak radzimy sobie z typografią — rozmiar czcionki powinien być oparty na rozmiarze okna roboczego. Oczywiście możemy do tego użyć jednostek rzutni. vw i vh (gdzie 1vw to 1% szerokości widocznego obszaru, a 1vh to 1% jego wysokości) są dość dobrze obsługiwane w różnych przeglądarkach, w szczególności we wszystkich przeglądarkach zgodnych z WebGL. (W Smashing Magazine znajduje się również artykuł o typografii wielkości widoku, który gorąco polecam.)

Na koniec bawimy się właściwością opacity obrazu tła, aby przenieść go z 0 do 1 na podstawie bieżącego procesu pobierania zmieniającego się z 0 do 100%.

A tak przy okazji, animacje tekstu są po prostu wykonywane przy użyciu przejść CSS lub animacji w połączeniu z układem flexbox, aby mieć prosty, ale skuteczny sposób wyświetlania w środku lub na każdym rogu.

Obsługa wszystkich danych wejściowych w przejrzysty sposób

Nasz silnik WebGL wykonuje całą pracę po stronie renderowania, aby poprawnie wyświetlać wizualizacje na wszystkich platformach. Ale jak możemy zagwarantować, że użytkownik będzie mógł poruszać się wewnątrz sceny, niezależnie od użytego typu wejścia?

W poprzedniej wersji Babylon.js wspieraliśmy wszystkie rodzaje wprowadzania i interakcji użytkownika: klawiatura/mysz, dotyk, wirtualne joysticki dotykowe, gamepad, orientacja urządzenia VR (dla Card Board) i WebVR, każdy za pomocą dedykowanej kamery. Możesz przeczytać naszą dokumentację, aby dowiedzieć się o nich nieco więcej.

Touch jest zarządzany uniwersalnie dzięki specyfikacji Pointer Events propagowanej na wszystkie platformy za pośrednictwem jQuery PEP polyfill (generowanie Touch Events dla aplikacji w razie potrzeby). Aby dowiedzieć się więcej o zdarzeniach wskaźnika, przeczytaj artykuł Unifying touch and mouse: w jaki sposób zdarzenia wskaźnika ułatwi obsługę dotykową w różnych przeglądarkach

Wróćmy więc do demonstracji. Ideą dla Sponzy było posiadanie unikalnej kamery, obsługującej jednocześnie wszystkie scenariusze użytkowników: stacjonarne, mobilne i konsolowe.

Skończyło się na stworzeniu UniversalCamera . Szczerze mówiąc, stworzenie było tak oczywiste i proste, że nadal nie wiem, dlaczego wcześniej tego nie zrobiliśmy. UniversalCamera to mniej więcej kamera z gamepadem rozszerzająca kamerę dotykową, która rozszerza FreeCamera .

FreeCamera zapewnia logikę klawiatury/myszy; TouchCamera zapewnia logikę dotykową, a ostatnie rozszerzenie zapewnia logikę gamepada.

UniversalCamera jest teraz domyślnie używana w Babylon.js. Jeśli przeglądasz dema, możesz poruszać się po scenach za pomocą myszy, dotyku i gamepada na wszystkich. Ponownie, możesz przestudiować kod, aby zobaczyć, jak to się robi.

Synchronizacja przejść z muzyką

W tej części zadaliśmy sobie najwięcej pytań. Być może zauważyłeś, że sekwencja wprowadzająca jest zsynchronizowana z określonymi obszarami ścieżki odtwarzania muzyki . Pierwsze linie są wyświetlane, gdy włącza się część bębnów, a ostatnia sekwencja końcowa to szybkie przełączanie z jednej kamery na drugą przy każdej nucie instrumentu waltorniowego, którego używamy.

Synchronizacja dźwięku z pętlą renderowania WebGL nie jest łatwa. Ponownie, jest to jednowątkowa natura JavaScript, która generuje tę złożoność. Artykuły na temat Wprowadzenie do pracowników internetowych HTML5: wielowątkowość w JavaScript dzielą się pewnymi spostrzeżeniami na ten temat. Bardzo ważne jest zrozumienie problemu, aby zrozumieć globalny problem, z którym mamy do czynienia, ale wchodzenie w szczegóły wykracza poza zakres tego artykułu.

Zwykle w scenach demonstracyjnych (i grach wideo), jeśli chcesz zsynchronizować efekty wizualne z dźwiękami/muzyką, będziesz kierowany przez stos audio. Często stosowane są dwa podejścia:

  1. Generuj metadane, które zostałyby wstrzyknięte do plików audio, a następnie mogłyby „wywołać” niektóre zdarzenia, gdy dotrzesz do określonej ich części,
  2. Analiza strumienia audio w czasie rzeczywistym za pomocą FFT lub podobnych technologii w celu wykrycia interesujących szczytów lub zmian BPM, które ponownie wygenerowałyby zdarzenia dla silnika wizualnego.

Te podejścia działają szczególnie dobrze w środowiskach wielowątkowych, takich jak C++. Ale w JavaScript, z Web Audio, mamy dwa problemy:

  1. JavaScript, który jest jednowątkowy i niestety przez większość czasu webworkerzy nam tak naprawdę nie pomogą,
  2. Web Audio nie ma żadnych zdarzeń , które mogłyby zostać odesłane do wątku interfejsu użytkownika, nawet jeśli Web Audio jest obsługiwane w oddzielnym wątku przez przeglądarkę.

Web Audio ma znacznie dokładniejszy zegar niż JavaScript. Byłoby fantastycznie móc użyć tego oddzielnego timera w osobnym wątku, aby przekierować zdarzenia z powrotem do wątku interfejsu użytkownika. Ale dzisiaj nie możesz tego zrobić (jeszcze?).

Z drugiej strony renderujemy scenę za pomocą WebGL i metody requestAnimationFrame . Oznacza to, że w „najlepszych przypadkach” mamy ramy czasowe okien 16 ms. Jeśli brakuje jednego, będziesz musiał poczekać do 16 ms, aby móc działać na następnej klatce, aby odzwierciedlić synchronizację dźwięku (na przykład, aby uruchomić efekt „zanikania do czerni”).

Myślałem wtedy o wstrzyknięciu logiki synchronizacji do pętli requestAnimationFrame . Przestudiowałem czas spędzony od początku sekwencji i zastanowiłem się nad możliwością dostosowania obrazu do reakcji na zdarzenie dźwiękowe. Dobrą wiadomością jest to, że dźwięk w sieci będzie renderował dźwięk niezależnie od tego, co dzieje się w głównym wątku interfejsu użytkownika. Na przykład możesz być pewien, że znacznik czasowy muzyki 12 s nadejdzie dokładnie 12 s po rozpoczęciu odtwarzania muzyki, nawet jeśli GPU ma trudności z renderowaniem sceny.

W końcu w końcu wybraliśmy prawdopodobnie najprostsze rozwiązanie: używając wywołań setTimeout() ! Tak, wiem. Jeśli zajrzysz do większości artykułów, w tym do tego, do którego podałem link powyżej, przekonasz się, że jest on dość niewiarygodny. Ale w naszym przypadku, gdy scena jest gotowa do renderowania, wiemy, że pobraliśmy wszystkie nasze zasoby (tekstury i dźwięki) i skompilowaliśmy nasze shadery. Nie powinny nas zbytnio denerwować nieoczekiwane zdarzenia nasycające wątek interfejsu użytkownika. GC może być problemem , ale spędziliśmy również dużo czasu walcząc z nim w silniku: Zmniejszenie nacisku na garbage collector za pomocą paska programisty F12 w Internet Explorerze 11.

Mimo to wiemy, że to rozwiązanie jest dalekie od ideału. Przejście do innej karty lub zablokowanie telefonu i odblokowanie go kilka sekund później może generować pewne problemy z synchronizacją części demo. Moglibyśmy rozwiązać te problemy za pomocą interfejsu API widoczności strony, np. przez wstrzymanie pętli renderowania, różnych dźwięków i ponowne obliczenie kolejnych ram czasowych dla wywołań setTimeout() .

Ale może coś przeoczyliśmy; być może, a nawet prawdopodobnie, istniało lepsze podejście do rozwiązania tego problemu. Chętnie poznamy Twoje przemyślenia i sugestie w sekcji komentarzy, jeśli uważasz, że istnieje lepszy sposób rozwiązania tego samego problemu.

Obsługa Web Audio w iOS

Ostatnim wyzwaniem, którym chciałbym się z Wami podzielić, jest sposób, w jaki Web Audio jest obsługiwane przez iOS na iPhonie i iPadzie. Jeśli szukasz artykułów na temat „dźwięk w sieci + iOS”, znajdziesz wiele osób, które mają problemy z odtwarzaniem dźwięków na iOS. Co się tam dzieje?

iOS ma niezwykłą obsługę Web Audio — nawet binauralnego trybu audio. Ale firma Apple zdecydowała, że ​​strona internetowa nie może domyślnie odtwarzać żadnego dźwięku bez konkretnej interakcji użytkownika. Ta decyzja została prawdopodobnie podjęta, aby uniknąć wyświetlania reklam lub czegokolwiek innego, co mogłoby przeszkadzać użytkownikowi poprzez odtwarzanie niechcianych dźwięków.

Co to oznacza dla twórców stron internetowych? Cóż, najpierw musisz odblokować internetowy kontekst audio iOS po dotknięciu użytkownika — zanim spróbujesz odtworzyć jakikolwiek dźwięk. W przeciwnym razie Twoja aplikacja internetowa pozostanie rozpaczliwie wyciszona.

Niestety, jedyny sposób, w jaki znalazłem, aby to zrobić, to sprawdzenie, czy stosując podejście do sniffowania platformy użytkownika, ponieważ nie znalazłem sposobu na wykrywanie funkcji, aby to zrobić. To nic innego jak okropne, a nie kuloodporne techniki, ale nie mogłem znaleźć żadnego innego rozwiązania, które rozwiązałoby problem. Kod? Proszę bardzo!

Jeśli nie korzystasz z iPada/iPhone'a/iPoda, kontekst audio jest natychmiast dostępny do użycia. W przeciwnym razie odblokowujemy kontekst audio systemu iOS, odtwarzając pusty dźwięk wygenerowany przez kod w zdarzeniu touchend . Możesz zarejestrować się w wydarzeniu onAudioUnlocked , jeśli chcesz poczekać na nie przed uruchomieniem gry. Jeśli więc uruchamiasz Sponzę na iPhonie/iPadzie, na końcu sekwencji ładowania pojawi się ten ostatni ekran:

Dotknij, aby rozpocząć

Dotknięcie dowolnego miejsca na ekranie odblokuje stos audio systemu iOS i uruchomi „pokaz”.

Więc zaczynamy! Mam nadzieję, że spodobało Ci się kilka spostrzeżeń związanych z rozwojem wersji demonstracyjnej. Aby dowiedzieć się więcej, przeczytaj pełny kod źródłowy tego demo na naszym GitHub. Oczywiście wszystko jest typu open source, a główne pliki można znaleźć na GitHub: index.js i babylon.demo.ts.

Wreszcie, mam nadzieję, że będziesz teraz jeszcze bardziej przekonany, że sieć jest zdecydowanie świetną platformą do gier! Bądź na bieżąco, ponieważ w tej chwili pracujemy nad nowymi demami i miejmy nadzieję, że również będą imponujące.

Ten artykuł jest częścią serii poświęconej tworzeniu stron internetowych opracowanej przez ewangelistów technicznych i inżynierów firmy Microsoft na temat praktycznej nauki języka JavaScript, projektów open source i najlepszych praktyk dotyczących interoperacyjności, w tym przeglądarki Microsoft Edge.

Zachęcamy do testowania na różnych przeglądarkach i urządzeniach, w tym Microsoft Edge — domyślnej przeglądarce dla systemu Windows 10 — za pomocą bezpłatnych narzędzi na dev.microsoftedge.com, w tym narzędzi programistycznych F12 — siedmiu odrębnych, w pełni udokumentowanych narzędzi ułatwiających debugowanie, testowanie i przyspieszyć swoje strony internetowe. Odwiedź także blog Edge, aby być na bieżąco i otrzymywać informacje od programistów i ekspertów firmy Microsoft.