Tworzę usługę Roll It

Roll It to eksperyment w Chrome, który stanowi nową wersję klasycznej gry planszowej dostępnej tylko w przeglądarce na telefonie i komputerze. Przeglądarka na telefonie umożliwia celowanie i toczenie piłką jednym ruchem nadgarstka, a przeglądarka na komputerze renderuje w czasie rzeczywistym grafikę przedstawiającą trasę Roll It za pomocą WebGL i Canvas. Oba urządzenia komunikują się przez Websockets. Brak aplikacji. Bez pobierania. Brak tokenów. Potrzebujesz tylko nowoczesnej przeglądarki.

Zgodnie z wytycznymi Google Creative Lab firma Legwork opracowała interfejs użytkownika, interfejsy i środowisko gry, a potem nawiązała współpracę z partnerem deweloperskim Mode Set, by stworzyć Roll It. W trakcie projektu czekało na Ciebie wiele wyjątkowych wyzwań. W tym artykule omawiamy wybrane przez nas techniki, sztuczki i wskazówki, które zdobyliśmy podczas wdrażania Roll It.

Przepływ pracy w 3D

Jedną z trudności na początku było znalezienie najlepszego sposobu przeniesienia modeli 3D z naszego oprogramowania do formatu pliku dostępnego w internecie. Po utworzeniu zasobów w Cinema 4D modele zostały uproszczone i przekształcone w siatki o niskiej wielokątnej wartości. Każdej siatce przypisano określone tagi wyboru wielokąta w celu rozróżnienia części obiektu na potrzeby kolorowania i teksturowania. Następnie mogliśmy wyeksportować plik Collada 1.5 (.dae) i zaimportować go do Blender, programu 3D typu open source, aby utworzyć zgodne pliki dla pliku 3.js. Gdy upewniliśmy się, że modele zostały prawidłowo zaimportowane, wyeksportowaliśmy siatkę w formacie JSON, a oświetlenie zostało zastosowane za pomocą kodu. Poniżej przedstawiamy bardziej szczegółowe informacje na temat podjętych przez nas działań:

Utwórz model obiektu w obrębie obiektu C4D. Upewnij się, że granica siatki jest skierowana na zewnątrz.
Modeluj obiekt w C4D. Upewnij się, że granica siatki jest skierowana na zewnątrz.
Używając narzędzia do wybierania wielokątów, utwórz znaczniki wyboru konkretnych obszarów, na które chcesz nałożyć tekstury. Zastosuj materiały do każdego z tagów wyboru.
Używając narzędzia do wybierania wielokątów, utwórz znaczniki wyboru konkretnych obszarów, na które chcesz nałożyć tekstury. Zastosuj materiały do każdego z tagów wyboru.
Wyeksportuj siatkę jako plik COLLADA 1.5 .dae.
Wyeksportuj siatkę jako plik.dae COLLADA 1 .5.
Upewnij się, że zaznaczona jest opcja „Eksportuj geometrię 2D”. Eksportowanie trójkątów jest ogólnie szerzej obsługiwane w środowiskach 3D po stronie kodu, ale wadą jest podwojenie liczby wielokątów. Im większa liczba wielokątów, tym bardziej obciążany będzie model komputera. Jeśli zauważysz spadek skuteczności, pozostaw to pole odznaczone.
Sprawdź, czy zaznaczona jest opcja „Eksportuj geometrię 2D”. Eksportowanie trójkątów jest ogólnie szerzej obsługiwane w środowiskach 3D po stronie kodu, ale wadą jest podwojenie liczby wielokątów. Im większa liczba wielokątów, tym bardziej obciążany będzie model komputera. Jeśli zauważysz spadek skuteczności, pozostaw to pole odznaczone.
Zaimportuj plik Collada do Blendera.
Zaimportuj plik Collada do Blendera.
Po zaimportowaniu do blendera zobaczysz, że wybrane materiały i tagi wyboru również zostały przeniesione.
Po zaimportowaniu do blendera zobaczysz, że wybrane materiały i tagi wyboru również zostały przeniesione.
Wybierz obiekt i dostosuj materiały do swoich potrzeb.
Wybierz obiekt i dostosuj dostępne dla niego materiały.
Wyeksportuj plik jako trzy.js
Wyeksportuj plik jako trzy.js, aby zapewnić zgodność z WebGL.

Pisanie kodu

Aplikacja Roll It została opracowana z wykorzystaniem bibliotek open source i działa natywnie w nowoczesnych przeglądarkach. Dzięki takim technologiom jak WebGL czy WebSockets internet dominuje w świecie gier i multimediów w jakości konsolowej. Łatwość i wygoda, z jaką deweloperzy mogą tworzyć te funkcje, znacznie się rozwinęły w miarę pojawiania się kolejnych nowoczesnych narzędzi do programowania w języku HTML.

Środowisko programistyczne

Większość oryginalnego kodu aplikacji Roll została napisana przy użyciu CoffeeScript – przejrzystego i zwięzłego języka, który po transkompilowaniu do poprawnie sformatowanego i lintowanego języka JavaScript. CoffeeScript świetnie nadaje się do programowania OOP dzięki świetnemu modelowi dziedziczenia i bardziej przejrzystej obsłudze zakresów. CSS został napisany za pomocą platformy SASS, która zapewnia deweloperowi szereg świetnych narzędzi do ulepszania arkuszy stylów projektu i zarządzania nimi. Dodanie tych systemów do procesu kompilacji może trochę potrwać, ale warto to zrobić, zwłaszcza w przypadku większego projektu, takiego jak Roll It. Skonfigurowaliśmy serwer Ruby on Rails, który automatycznie kompilowa nasze zasoby w trakcie tworzenia aplikacji, dzięki czemu wszystkie kroki kompilacji są przejrzyste.

Oprócz utworzenia przejrzystego i wygodnego środowiska kodowania zoptymalizowaliśmy zasoby ręcznie, aby zminimalizować liczbę żądań i przyspieszyć wczytywanie strony. Każdy obraz przetestowaliśmy za pomocą 2 programów kompresji: ImageOptim i ImageAlpha. Każdy program optymalizuje obrazy na swój sposób – odpowiednio bezstratnie i w sposób stratny. Dzięki odpowiedniej kombinacji ustawień mogą one znacznie zmniejszyć rozmiar pliku obrazu. Oszczędza to przepustowość podczas wczytywania obrazów zewnętrznych, ale po optymalizacji obrazy zostaną zamienione na znacznie mniejsze ciągi zakodowane w standardzie base64 do umieszczania w treściach w językach HTML, CSS i JavaScript. Jeśli chodzi o kodowanie base64, za pomocą tej techniki umieściliśmy też pliki czcionek Open Sans WOFF i SVG bezpośrednio w CSS, co spowodowało jeszcze mniejszą łączną liczbę żądań.

Scena 3D z obsługą fizyki

THREE.js to biblioteka 3D JavaScript dostępna do stosowania w internecie. Ta niskopoziomowa optymalizacja matematyczna 3D i sprzętowa optymalizacje WebGL umożliwiają zwykli śmiertelnikom łatwe tworzenie dobrze oświetlonych, pięknych interaktywnych scen 3D bez konieczności pisania niestandardowych programów do cieniowania i ręcznego przekształcania macierzy. Physijs to kod THREE.js dla popularnej biblioteki fizycznej C++ przetłumaczonej na JavaScript. Skorzystaliśmy z tej biblioteki, aby w 3D symulować toczącą się, skakającą i odbijającą się piłkę w kierunku jej miejsca docelowego.

Od samego początku zadbaliśmy o to, aby fizyczne elementy gry wyglądały realistycznie, ale były też realistyczne. Wymagało to wielu iteracji dostosowania ogólnej grawitacji w scenie Physijs, prędkości piłki podczas rzutu zawodnika, nachyleń skoku na torze oraz właściwości tarcia i regeneracji (odporności) piłki oraz materiałów na torze. Połączenie większej grawitacji z szybkością spowodowało, że gra stała się bardziej realistyczna.

Wygładzanie

Większość współczesnych połączeń przeglądarek i kart wideo powinna wykorzystywać natywne sprzętowe anti-aliasing w środowisku WebGL, ale niektóre te nie będą działać dobrze. Jeśli anti-aliasing nie będzie działać natywnie, wszystkie twarde i skontrastowane krawędzie w scenie THREE.js będą postrzępione i brzydkie (przynajmniej dla naszych wyczulonych oczu).

Na szczęście jest to rozwiązanie: za pomocą fragmentu kodu możemy określić, czy platforma natywnie obsługuje antyaliasing. Jeśli tak, możemy go edytować. Jeśli nie, oferujemy pomoc w tzw.cieniowaniu, które można wykorzystać w trakcie przetwarzania końcowego. czyli antyaliasing FXAA. Dzięki ponownemu rysowaniu wyrenderowanej sceny w ramach tego narzędzia do cieniowania nasze linie i krawędzie są z reguły płynniejsze. Zobacz prezentację poniżej:

// Check for native platform antialias support via the THREE renderer
// from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing
var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;

Sterowanie grą oparte na akcelerometrze

Działanie rolki wiąże się w większości z gestem rotowania piłką, który gracz wykonuje za pomocą telefonu. Komórki już od jakiegoś czasu mają dostęp do akcelerometru w przeglądarce, ale jako branża dopiero zaczynamy rozwijać funkcję rozpoznawania gestów w internecie. Jesteśmy w pewnym stopniu ograniczone danymi dostarczanymi przez akcelerometr telefonu, ale przy odrobinie kreatywności możemy wymyślić coś nowego.

Wykrywanie głównego gestu „obrócenia” rozpoczyna się od śledzenia 10 ostatnich aktualizacji akcelerometru pochodzących ze zdarzenia deviceorientation w oknie. Odejmując wcześniejszą wartość nachylenia od bieżącej wartości nachylenia, zapisujemy różnicę kątów między zdarzeniami. Następnie, nieustannie sumując ostatnie dziesięć kątów, możemy wykryć ciągły obrót telefonu w przestrzeni kosmicznej. Gdy telefon przekracza próg zmiany kąta przemieszczenia, uruchamiany jest obrót. Następnie, znajdując największą pojedynczą delta pochylenia podczas tego przebiegu, możemy oszacować prędkość piłki. W funkcji Roll It prędkość jest normalizowana za pomocą sygnatur czasowych dodawanych do każdej aktualizacji akcelerometru. Pomaga to uzyskać płynną zmianę szybkości, z jaką aktualizacje z akcelerometru są przesyłane do przeglądarki na różnych urządzeniach.

Komunikacja za pomocą WebSockets

Gdy gracz obraca piłkę za pomocą telefonu, z telefonu na laptopa jest wysyłana wiadomość z prośbą o wypuszczenie piłki. Ten komunikat „roll” jest wysyłany przez obiekt danych JSON przez połączenie WebSocket między 2 maszynami. Dane JSON są niewielkie i składają się głównie z typu wiadomości, szybkości rzucania oraz kierunku celu.

{
  "type": "device:ball-thrown",
  "speed": 0.5,
  "aim": 0.1
}

Cała komunikacja między laptopem a telefonem odbywa się za pomocą małych wiadomości JSON, takich jak ta. Za każdym razem, gdy gra aktualizuje swój stan na pulpicie albo użytkownik przechyla lub dotyka przycisk na telefonie, między komputerami jest przesyłana wiadomość WebSocket. Aby komunikacja była prosta i łatwa do zarządzania, wiadomości WebSockets są transmitowane za pomocą jednego punktu wyjścia z każdej z przeglądarek. I na odwrót: w przeglądarce odbierającej znajduje się jeden punkt wejścia, a jeden obiekt WebSocket po obu stronach obsługuje wszystkie wiadomości przychodzące i wychodzące. Po otrzymaniu wiadomości WebSocket dane JSON są retransmisowane w aplikacji JavaScript przy użyciu metody trigger() jQuery. Na tym etapie przychodzące dane działają tak samo jak każde inne niestandardowe zdarzenie DOM – mogą być odbierane i przetwarzane przez dowolny inny obiekt w aplikacji.

var websocket = new WebSocket(serverIPAddress);

// rebroadcast incoming WebSocket messages with a global event via jQuery
websocket.onmessage = function(e) {
  if (e.data) {
    var obj = JSON.parse(e.data);
    $(document).trigger(data.type, obj);
  }
};

// broadcast outgoing WebSocket messages by passing in a native .js object
var broadcast = function(obj) {
  websocket.send(JSON.stringify(obj));
};

Serwery Roll It's WebSocket są tworzone w czasie rzeczywistym, gdy 2 urządzenia są synchronizowane przy użyciu kodu gry. Backend dla Roll It został stworzony na platformie Google Compute Engine i App Engine przy użyciu Go.

Pochylane ekrany menu

Oprócz komunikatów WebSocket opartych na zdarzeniach podczas rozgrywki menu w funkcji Roll It steruje przechylaniem telefonu i naciskiem przycisku, aby potwierdzić wybór. Wymaga to bardziej stabilnego strumienia danych przechylenia przesyłanego z telefonu do laptopa. Aby zmniejszyć obciążenie przepustowości sieci i uniknąć wysyłania niepotrzebnych aktualizacji, te wiadomości są wysyłane tylko wtedy, gdy przechylenie urządzenia jest większe o więcej niż kilka stopni. Nie ma sensu wysyłanie strumienia danych o przechyleniu, jeśli telefon leży płasko na stole. Zmniejszana jest też szybkość transmisji – w funkcji Roll It jest wysyłanych maksymalnie 15 wiadomości WebSockets na sekundę, nawet jeśli urządzenie jest aktywnie przechylone.

Po zebraniu wartości przechylenia na komputerze są one z czasem interpolowane za pomocą narzędzia requestAnimationFrame, aby zachować płynność działania. Rezultatem jest obracające się menu i kulka, która ułatwia wybór użytkownika. Gdy telefon wysyła dane o przechyleniu, te elementy DOM są aktualizowane w czasie rzeczywistym przez ponowne obliczenie przekształcenia CSS w pętli requestAnimationFrame. Kontener menu obraca się, ale piłka toczy się po podłodze. W tym celu stosujemy podstawową trygonometrię, aby powiązać współrzędne X kul z ich obrotem. Proste równanie wygląda tak: obroty = x / (średnica * π)

Podsumowanie

Krążek to znak czasu. Spośród projektów open source, które wpłynęły na jego rozwój, moc obliczeniowa urządzeń, które znajdują się w naszych biurkach i w naszych kieszeniach, a także stan internetu jako platformy, jest to naprawdę ekscytujący, przełomowy czas na łączenie się z internetem w otwartej sieci. Jeszcze kilka lat temu duża część tej technologii istniała tylko w zastrzeżonych systemach, których nie można było swobodnie wykorzystywać ani rozpowszechniać. Dzisiaj złożone doświadczenia można realizować przy mniejszym nakładzie pracy i większej wyobraźni, ponieważ codziennie tworzymy i udostępniamy nowe elementy łamigłówki. Nie zastanawiaj się. Zbuduj coś wspaniałego i podziel się tym ze światem.

Logo Roll it