Jak zbudować wieloosobową grę wirtualną w czasie rzeczywistym (część 1)
Opublikowany: 2022-03-10W tej serii samouczków zbudujemy internetową grę wieloosobową w wirtualnej rzeczywistości, w której gracze będą musieli współpracować, aby rozwiązać zagadkę. Użyjemy A-Frame do modelowania VR, MirrorVR do synchronizacji między urządzeniami w czasie rzeczywistym, a A-Frame Low Poly do estetyki low-poly. Pod koniec tego samouczka otrzymasz w pełni działające demo online, w które może zagrać każdy.
Każda para graczy otrzymuje pierścień kul. Celem jest „włączenie” wszystkich kul, przy czym kula jest „włączona”, jeśli jest uniesiona i jasna. Kula jest „wyłączona”, jeśli jest niższa i słaba. Jednak niektóre „dominujące” kule wpływają na swoich sąsiadów: jeśli zmienią stan, ich sąsiedzi również zmienią stan. Tylko gracz 2 może kontrolować kule dominujące, podczas gdy tylko gracz 1 może kontrolować kule niedominujące. Zmusza to obu graczy do współpracy w celu rozwiązania zagadki. W tej pierwszej części samouczka zbudujemy środowisko i dodamy elementy projektu do naszej gry VR.
Siedem kroków tego samouczka podzielono na trzy sekcje:
- Konfiguracja sceny (kroki 1-2)
- Tworzenie kul (kroki 3–5)
- Tworzenie interaktywnych kul (kroki 6–7)
Ta pierwsza część zakończy się klikalną kulą, która włącza się i wyłącza (jak na zdjęciu poniżej). Będziesz używać A-Frame VR i kilku rozszerzeń A-Frame.

Konfiguracja sceny
1. Chodźmy z podstawową sceną
Na początek spójrzmy, jak możemy skonfigurować prostą scenę z podłożem:

Pierwsze trzy poniższe instrukcje są zaczerpnięte z mojego poprzedniego artykułu. Zaczniesz od skonfigurowania witryny internetowej z pojedynczą statyczną stroną HTML. Dzięki temu możesz kodować z komputera i automatycznie wdrażać w Internecie. Wdrożoną stronę internetową można następnie załadować na telefon komórkowy i umieścić w goglach VR. Alternatywnie wdrożoną witrynę można załadować za pomocą samodzielnego zestawu słuchawkowego VR.
Zacznij od przejścia na glitch.com. Następnie wykonaj następujące czynności:
- Kliknij „Nowy projekt” w prawym górnym rogu,
- Kliknij „hello-webpage” w menu rozwijanym,
- Następnie kliknij index.html na lewym pasku bocznym. Będziemy nazywać to „redaktorem”.
Powinieneś teraz zobaczyć następujący ekran Glitch z domyślnym plikiem HTML.

Podobnie jak w przypadku powyższego połączonego samouczka, zacznij od usunięcia całego istniejącego kodu z bieżącego pliku index.html . Następnie wpisz następujące informacje dla podstawowego projektu webVR, używając A-Frame VR. Tworzy to pustą scenę przy użyciu domyślnego oświetlenia i aparatu A-Frame.
<!DOCTYPE html> <html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> </a-scene> </body> </html>
Podnieś kamerę na wysokość stojącą. Zgodnie z zaleceniami A-Frame VR (problem z Github), owiń kamerę nową jednostką i przenieś jednostkę nadrzędną zamiast bezpośrednio do kamery. Pomiędzy znacznikami a-scene
w wierszach 8 i 9 dodaj następujące.
<!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity>
Następnie dodaj duże pudełko do oznaczenia podłoża, używając a-box
. Umieść go bezpośrednio pod kamerą z poprzedniej instrukcji.
<!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box>
Twój plik index.html powinien teraz dokładnie odpowiadać poniższemu. Pełny kod źródłowy można znaleźć tutaj, na Github.
<html> <head> <title>Lightful</title> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> <!-- Camera! --> <a-entity position="0 3 0"> <a-camera wasd-controls look-controls></a-camera> </a-entity> <!-- Action! --> <a-box shadow width="75" height="0.1" depth="75" position="0 -1 0" color="#222"></a-box> </a-scene> </body> </html>
Na tym kończy się konfiguracja. Następnie dostosujemy oświetlenie, aby uzyskać bardziej tajemniczą atmosferę.
2. Dodaj atmosferę
W tym kroku skonfigurujemy mgłę i niestandardowe oświetlenie.

Dodaj mgłę, która zasłoni nam obiekty znajdujące się daleko. Zmodyfikuj znacznik a-scene
w linii 8. Tutaj dodamy ciemną mgłę, która szybko zasłania krawędzie ziemi, dając efekt odległego horyzontu.
<a-scene fog="type: linear; color: #111; near:10; far:15"></a-scene>
Ciemnoszary #111
zanika liniowo z odległości 10 do 15. Wszystkie obiekty w odległości większej niż 15 jednostek są całkowicie zasłonięte, a wszystkie obiekty w odległości mniejszej niż 10 jednostek są całkowicie widoczne. Każdy obiekt pomiędzy jest częściowo zasłonięty.
Dodaj jedno światło otoczenia, aby rozjaśnić obiekty w grze i jednokierunkowe światło, aby zaakcentować odblaskowe powierzchnie, które dodasz później. Umieść to bezpośrednio po tagu a-scene
, który zmodyfikowałeś w poprzedniej instrukcji.
<!-- Lights! --> <a-light type="directional" castshadow="true" intensity="0.5" color="#FFF" position="2 5 0"></a-light> <a-light intensity="0.1" type="ambient" position="1 1 1" color="#FFF"></a-light>
Bezpośrednio pod światłami w poprzedniej instrukcji dodaj ciemne niebo. Zauważ, że ciemnoszary #111
pasuje do odległej mgły.
<a-sky color="#111"></a-sky>
To kończy podstawowe modyfikacje nastroju i szerzej, ustawienia sceny. Sprawdź, czy Twój kod dokładnie pasuje do kodu źródłowego dla kroku 2 na Github. Następnie dodamy kulę low-poly i zaczniemy dostosowywać estetykę kuli.
Tworzenie kul
3. Stwórz kulę Low-Poly
W tym kroku stworzymy obracającą się, odblaskową kulę, jak pokazano poniżej. Kula składa się z dwóch stylizowanych sfer low poly z kilkoma sztuczkami sugerującymi odblaskowy materiał.

Zacznij od zaimportowania biblioteki low-poly do tagu head
. Wstaw następujący tekst między wierszami 4 i 5.
<script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/aframe-low-poly.min.js"></script>
Utwórz karuzelę, opakowanie i pojemnik na kule. carousel
będzie zawierać wiele kul, wrapper
pozwoli nam obracać wszystkie kule wokół osi środkowej bez obracania każdej kuli z osobna, a container
– jak sama nazwa wskazuje – będzie zawierał wszystkie elementy kul.
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <!-- place orb here --> </a-entity> </a-entity> </a-entity>
Wewnątrz pojemnika na kulę dodaj samą kulę: jedna kula jest lekko przezroczysta i przesunięta, a druga jest całkowicie lita. Dwie połączone powierzchnie odbijające światło.
<a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> </a-entity>
Na koniec obróć sferę w nieskończoność, dodając następujący znacznik a-animation
bezpośrednio po lp-sphere
wewnątrz jednostki .orb
w ostatniej instrukcji.
<a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation>
Twój kod źródłowy opakowań kul i sama kula powinny dokładnie odpowiadać poniższemu.
<a-entity> <a-entity rotation="0 90 0" class="wrapper" position="0 0 0"> <a-entity class="container" position="8 3 0" scale="1 1 1"> <a-entity class="orb" data-> <lp-sphere seed="0" shadow max-amplitude="1 1 1" position="-0.5 0 -0.5"></lp-sphere> <lp-sphere seed="0" shadow max-amplitude="1 1 1" rotation="0 45 45" opacity="0.5" position="-0.5 0 -0.5"></lp-sphere> <a-animation attribute="rotation" repeat="indefinite" from="0 0 0" to="0 360 0" dur="5000"></a-animation> </a-entity> </a-entity> </a-entity> </a-entity>
Sprawdź, czy Twój kod źródłowy jest zgodny z pełnym kodem źródłowym kroku 3 na Github. Twój podgląd powinien teraz odpowiadać następującym.


Następnie dodamy więcej oświetlenia do kuli, aby uzyskać złoty odcień.
4. Rozświetl kulę
W tym kroku dodamy dwa światła, jedno kolorowe i jedno białe. Daje to następujący efekt.

Zacznij od dodania białego światła, aby oświetlić obiekt od dołu. Użyjemy światła punktowego. Bezpośrednio przed #orb0
ale wewnątrz #container-orb0
, dodaj następujące światło punktowe przesunięcia.
<a-entity position="-2 -1 0"> <a-light distance="8" type="point" color="#FFF" intensity="0.8"></a-light> </a-entity>
W podglądzie zobaczysz następujące elementy.

Domyślnie światła nie zanikają wraz z odległością. Dodając distance="8"
, zapewniamy, że światło zanika całkowicie w odległości 8 jednostek, aby zapobiec oświetleniu całej sceny przez światło punktowe. Następnie dodaj złote światło. Dodaj następujące bezpośrednio nad ostatnim światłem.
<a-light class="light-orb" distance="8" type="point" color="#f90" intensity="1"></a-light>
Sprawdź, czy Twój kod dokładnie odpowiada kodowi źródłowemu w kroku 4. Twój podgląd będzie teraz odpowiadał następującym.

Następnie dokonasz ostatecznej modyfikacji estetycznej kuli i dodasz obrotowe pierścienie.
5. Dodaj pierścienie
W tym kroku wyprodukujesz ostateczną kulę, jak pokazano poniżej.

Dodaj pierścień w #container-orb0
bezpośrednio przed #orb0
.
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.9" radius-outer="2" opacity="0.25"></a-ring>
Zauważ, że sam pierścień nie zawiera koloru, ponieważ kolor zostanie nasycony przez światło punktowe w poprzednim kroku. Co więcej, parametr material="side:double"
jest ważny, ponieważ bez niego tył pierścienia nie byłby renderowany; oznacza to, że pierścień zniknie na połowę swojego obrotu.
Jednak podgląd zawierający tylko powyższy kod nie będzie wyglądał inaczej. Dzieje się tak, ponieważ pierścień jest obecnie prostopadły do ekranu. W ten sposób widoczny jest tylko „bok” pierścienia (który ma grubość 0). Umieść poniższą animację pomiędzy znacznikami a-ring
w poprzedniej instrukcji.
<a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 0 0" to="0 360 0" dur="8000"></a-animation>
Twój podgląd powinien teraz odpowiadać następującym:

Twórz zmienną liczbę pierścieni z różnymi osiami obrotu, prędkościami i rozmiarami. Możesz użyć następujących przykładowych pierścieni. Wszelkie nowe pierścienie należy umieścić pod ostatnim a-ring
.
<a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="2.4" radius-outer="2.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 45 0" to="360 45 0" dur="8000"></a-animation> </a-ring> <a-ring color="#fff" material="side:double" position="0 0.5 0" radius-inner="1.4" radius-outer="1.5" opacity="0.25"> <a-animation attribute="rotation" easing="linear" repeat="indefinite" from="0 -60 0" to="-360 -60 0" dur="3000"></a-animation> </a-ring>
Twój podgląd będzie teraz odpowiadał następującym.

Sprawdź, czy Twój kod jest zgodny z kodem źródłowym w kroku 5 na Github. Na tym kończy się wystrój kuli. Po zakończeniu kuli dodamy interaktywność do kuli. W następnym kroku dodamy widoczny kursor z animacją kliknięcia po wskazaniu na klikalne obiekty.
Tworzenie interaktywnych kul
6. Dodaj kursor
W tym kroku dodamy biały kursor, który może wyzwalać klikalne obiekty. Kursor jest przedstawiony poniżej.

W tagu a-camera
dodaj następującą jednostkę. Atrybut fuse
umożliwia tej jednostce możliwość wyzwalania zdarzeń kliknięcia. Atrybut raycaster
określa, jak często i jak daleko należy sprawdzać obiekty, które można kliknąć. Atrybut objects
akceptuje selektor w celu określenia, które elementy można kliknąć. W tym przypadku wszystkie obiekty klasy clickable
są klikalne.
<a-entity cursor="fuse: true; fuseTimeout: 250" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.03; radiusOuter: 0.04" material="color: white; shader: flat; opacity: 0.5" scale="0.5 0.5 0.5" raycaster="far: 20; interval: 1000; objects: .clickable"> <!-- Place cursor animation here --> </a-entity>
Następnie dodaj animację kursora i dodatkowy pierścień dla estetyki. Umieść następujące elementy wewnątrz obiektu kursora jednostki powyżej. Dodaje to animację do obiektu kursora, dzięki czemu kliknięcia są widoczne.
<a-circle radius="0.01" color="#FFF" opacity="0.5" material="shader: flat"></a-circle> <a-animation begin="fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.2 0.2 0.2" dur="250"></a-animation>
Następnie dodaj clickable
klasę do #orb0
, aby dopasować następujące elementy.
<a-entity class="orb clickable" data->
Sprawdź, czy Twój kod pasuje do kodu źródłowego dla kroku 6 na Github. W podglądzie przeciągnij kursor z nich na kulę, aby zobaczyć animację kliknięcia w akcji. Jest to pokazane poniżej.

Zauważ, że klikalny atrybut został dodany do samej kuli, a nie do kontenera kuli. Ma to na celu zapobieganie sytuacji, w której pierścienie stają się obiektami, które można kliknąć. W ten sposób użytkownik musi kliknąć na kule, które tworzą samą kulę.
W naszym ostatnim kroku w tej części dodasz animację, aby kontrolować stany włączenia i wyłączenia kuli.
7. Dodaj stany kuli
W tym kroku będziesz animować kulę w stanie wyłączonym i wyłączonym po kliknięciu. Jest to pokazane poniżej.

Na początek zmniejszysz się i opuścisz kulę na ziemię. Dodaj znaczniki a-animation
a do #container-orb0
zaraz po #orb0
. Obie animacje są wyzwalane kliknięciem i mają tę samą funkcję ease-elastic
i zapewnia lekkie odbicie.
<a-animation class="animation-scale" easing="ease-elastic" begin="click" attribute="scale" from="0.5 0.5 0.5" to="1 1 1" direction="alternate" dur="2000"></a-animation> <a-animation class="animation-position" easing="ease-elastic" begin="click" attribute="position" from="8 0.5 0" to="8 3 0" direction="alternate" dur="2000"></a-animation>
Aby jeszcze bardziej podkreślić stan wyłączenia, usuniemy złote światło punktowe, gdy kula jest wyłączona. Jednak światła kuli są umieszczone na zewnątrz obiektu kuli. W ten sposób zdarzenie kliknięcia nie jest przekazywane do świateł po kliknięciu kuli. Aby obejść ten problem, użyjemy lekkiego JavaScript, aby przekazać zdarzenie kliknięcia do światła. Umieść następujący tag animacji w #light-orb0
. Światło jest wyzwalane przez niestandardowe zdarzenie switch
.
<a-animation class="animation-intensity" begin="switch" attribute="intensity" from="0" to="1" direction="alternate"></a-animation>
Następnie dodaj następujący detektor zdarzeń kliknięcia do #container-orb0
. To przekaże kliknięcia do świateł kuli.
<a-entity ...>
Sprawdź, czy Twój kod jest zgodny z kodem źródłowym kroku 7 na Github. Na koniec otwórz podgląd i przesuń kursor na kulę i poza nią, aby przełączać się między stanami wyłączonymi i włączonymi. Jest to pokazane poniżej.

Na tym kończy się interaktywność kuli. Gracz może teraz włączać i wyłączać kule do woli, z oczywistymi stanami włączania i wyłączania.
Wniosek
W tym samouczku zbudowałeś prostą kulę z włączonymi i wyłączonymi stanami, które można przełączać za pomocą kliknięcia kursora przyjaznego dla zestawu słuchawkowego VR. Dzięki wielu różnym technikom oświetlenia i animacjom można było rozróżnić te dwa stany. To kończy elementy projektu wirtualnej rzeczywistości dla kul. W kolejnej części samouczka zapełnimy kule dynamicznie, dodamy mechanikę gry i skonfigurujemy protokół komunikacji między parą graczy.