Gra polegająca na znajdowaniu przedmiotów w pobliżu, zainspirowana grą saper.
Zespół, który stworzył squoosh.app, powraca! Tym razem stworzyliśmy grę internetową o nazwie PROXX (proxx.app). PROXX to gra zbliżeniowa inspirowana legendarną grą Saper. Akcja gry toczy się w kosmosie, a Twoim zadaniem jest odnalezienie czarnych dziur. Działa na wszystkich urządzeniach – od komputerów po telefony komórkowe. Użytkownicy mogą grać za pomocą myszy, klawiatury lub panelu kierunkowego, nawet przy użyciu czytnika ekranu.
Nasza linia bazowa
Zanim stworzyliśmy tę grę, wyznaczyliśmy dla niej te cele i budżety:
- To samo podstawowe działanie: wszystkie urządzenia muszą działać w ten sam sposób.
- Dostępność: mysz, klawiatura, ekran dotykowy, panel dotykowy, czytniki ekranu.
- Wydajność:
- mniej niż 25 KB początkowego ładunku danych;
- TTI (czas do interakcji) poniżej 5 sekund w przypadku powolnej sieci 3G.
- stała animacja z częstotliwością 60 kl./s,
Skrypty Web Worker
Gra składa się z 4 głównych elementów: głównej logiki gry, usługi interfejsu użytkownika, usługi stanu i grafiki animacji. Wiedzieliśmy od początku, że w głównym wątku będziemy musieli uruchomić mocno animowaną grafikę, więc przeprowadziliśmy logikę gry i usługę stanu do web workera, aby główny wątek był jak najbardziej wolny.
Kompilacja przed renderowaniem
Nasze interfejsy są tworzone za pomocą Preact, ponieważ pozwala nam to osiągnąć ambitny cel dotyczący początkowego rozmiaru pliku mniejszych niż 25 KB. Aby zapewnić płynne wczytywanie, zdecydowaliśmy się na wstępny renderowanie pierwszego widoku. Podczas kompilacji używamy Puppeteer do uzyskania dostępu do strony głównej i zapisywania DOM-u w pliku preact. Wygenerowany DOM jest następnie serializowany do kodu HTML i zapisywany jako index.html.
Płótno do animacji, (niewidoczny) DOM do ułatwień dostępu
Grafika gry jest renderowana na płótnie za pomocą WebGL. Jeden canvas odpowiada za animację tła, a drugi – za siatkę gry na górze. Ze względu na ułatwienia dostępu mamy też tabelę HTML z przyciskami, która znajduje się na obu tych obszarach roboczych, ale jest niewidoczna (przezroczystość: 0). Chociaż widzisz renderowanie stanu gry na płótnie, gracz wchodzi w interakcję z niewidoczną tabelą DOM, co umożliwia nam dołączanie odbiorników zdarzeń i poleganie na zarządzaniu fokusem przeglądarki.
Dzięki temu, że element DOM pozostaje na kanwie, możemy korzystać z wbudowanych w przeglądarkę funkcji ułatwień dostępu. Na przykład: dzięki ustawieniu role="grid"
na naszej planszy do gry czytniki ekranu mogą odczytywać na głos wiersz i kolumnę komórki, na której jest skupiona uwaga użytkownika, bez konieczności implementowania tej funkcji.
Podsumowanie dotyczące grupowania i dzielenia kodu
Łączny rozmiar aplikacji spakowanej w pliku GZIP wynosi 100 KB. Z tego 20 KB to początkowy ładunek (plik index.html). W tym projekcie używamy Rollup.js. Mamy współdzielone zależności między wątkiem głównym a naszym wątkiem roboczym w przeglądarce. Rollup może umieścić te współdzielone zależności w oddzielnym kawałku kodu, który trzeba wczytać tylko raz. Inne narzędzia do tworzenia pakietów, takie jak webpack, powielają wspólne zależności, co powoduje podwójne wczytywanie.
Obsługa telefonów z podstawową przeglądarką
Inteligentne telefony komórkowe, takie jak KaiOS, szybko zyskują na popularności. To urządzenia o bardzo ograniczonych zasobach, ale nasze podejście polegające na używaniu web workerów w miarę możliwości pozwoliło nam zapewnić na tych telefonach również bardzo responsywne działanie. Telefony z podstawową przeglądarką mają inny interfejs wprowadzania (pad i klawisze numeryczne, bez ekranu dotykowego), dlatego wdrożyliśmy też interfejs oparty na przyciskach.
Co dalej?
Praca nad tą grą była bardzo intensywna, ale udało nam się ją ukończyć na czas Google I/O 2019. Teraz zamierzamy odpocząć, ale planujemy wrócić z bardziej szczegółową dokumentacją dotyczącą każdego z tych obszarów gry.
Do tego czasu obejrzyj prezentację Mariko na temat tego projektu z konferencji I/O.
Kod możesz przeglądać w repozytorium GitHub proxx.
Pozdrawiamy, Surma, Jake, Mariko