Tworzysz płynnie zapętlony poziom gry wieloosobowej 2D?

15

Niedawno pojawiła się dyskusja na temat tworzenia wieloosobowej gry 2D z przewijanym bokiem, która może mieć zapętlony poziom (Pomyśl o Starbound i jak zapętlają się ich światy).

Pomyślałem, że najprostszym sposobem będzie posiadanie prostokątnej mapy ze strefami wyzwalania, która mogłaby teleportować graczy z jednej strony na drugą. Jednak oczywistym problemem związanym z tym podejściem jest posiadanie wielu graczy jednocześnie na krawędzi mapy. Nie chcesz po prostu teleportować graczy przed sobą i potrzebujesz transportu, aby inni nie zniknęli.

Aby dołączyć ten pomysł i naprawić problem, wymyśliłem: strefę wyzwalania (czerwony kwadrat na obrazku), w której gracze będą mogli zobaczyć „strefę klonowania” (zielony kwadrat). W tym zielonym kwadracie obiekty z przeciwnej strony strefy wyzwalającej zostałyby skopiowane do odpowiedniej strefy klonowania (można to zobaczyć w kształtach A i B). Kiedy gracz dotrze do początkowej krawędzi „strefy klonowania”, zostaje teleportowany na drugą stronę mapy.

wizerunek

W tym przykładzie Gracz 2 pomyślałby, że widzi Gracza 1, jednak tak naprawdę zobaczyłby jego klon i odwrotnie.

Wydawało się to nieco ekstremalne i złożone w odniesieniu do problemu. Moje pytanie brzmi teraz: czy to rozwiązanie jest dobrym podejściem do rozwiązania problemu, czy też istnieje prostszy sposób rozwiązania tego problemu?

KenQueso
źródło
Czy gracze mogą cofać się do poprzedniego obszaru?
XiaoChuan Yu
tak, tam iz powrotem, więc daje to efekt „chodzenia po świecie”. Podobnie jak w świecie bez gwiazd
KenQueso,
2
Czy zastanawiałeś się nad tym, aby uczynić świat wielkim kręgiem? lub traktujesz poziom jako duży okrąg i przekładasz go na płaską scenę 2D?
Nzall,
nie zawsze możesz wyrównać pozycję kamery z kontrolowanym odtwarzaczem?
Ali1S232,

Odpowiedzi:

16

Ten system ze wszystkimi tymi wyzwalaczami wydaje się nieco zbyt skomplikowany i podatny na błędy.

Możesz zawinąć pozycję odtwarzacza za pomocą modulo z czymś takim playerPositionX = playerPositionX % mapWidth

W ten sposób, gdy gracz osiągnie zostaną przywrócone do 0.playerPosition == mapWidthplayerPosition

To rozwiązanie można rozszerzyć o cały system renderowania.

Exaila
źródło
1
czy nie miałoby to problemu zamykania się przez graczy, którzy widzieliby graczy, których resetowanie pozycji się teleportowało?
KenQueso,
Jak rozszerzyłbyś to na system renderowania?
Mikael Högström,
Możesz mieć gracza zawsze na środku kamery i zawijać mapę. Jak mapa w cywilizacji w trybie ziemskim. Innym podejściem może być przeniesienie widocznej części gracza na obie strony mapy.
Exaila,
4
@ MikaelHögström Renderuj jak zwykle, ale rzeczy blisko prawej krawędzi muszą być renderowane po raz drugi po lewej (tj pos - map_width. At ).
Mario,
1
W dowolnym miejscu w kodzie, w którym szukasz „jaki obiekt jest przy tej współrzędnej” lub „jakie są współrzędne tego obiektu”, zrobiłbyś to xcoord% mapWidth. Trudno powiedzieć bez twojego kodu, ale prawdopodobnie spowodowałoby to prawidłowe renderowanie.
Tin Man
13

Kanonicznym rozwiązaniem jest użycie portali . W twoim przykładzie jest tylko jeden poziom, z wyjątkiem portalu łączącego lewy i prawy koniec.

Cokolwiek porusza się po tym portalu, jego współrzędne zostaną przetłumaczone na drugi koniec portalu, więc jeśli coś porusza się w lewo przez portal, pojawi się ponownie po prawej stronie poziomu i odwrotnie.

Twój aparat musi również obsługiwać portale; jeśli portal znajduje się w kamerze, musi renderować części poziomu po obu stronach portalu. Jeśli znasz edytory obrazów do płynnej grafiki kafelkowej, tutaj jest to ta sama oferta.

Nużącą częścią jest to, że wszystko, co dotyczy dystansu lub ścieżki, musi również wspierać portale. Obejmuje to AI, algosfery widzenia, tłumienie dźwięku i tak dalej.

Zaletą portali jest to, że jest bardzo wydajny. Silnik kompilacji wykorzystał go do symulacji poziomów wielopiętrowych, mimo że nie jest to „prawdziwy” silnik 3d. Niektóre nowoczesne silniki wykorzystują portale również do tworzenia przestrzeni innych niż euklidesowe; Portal i antichamber to godne uwagi przykłady w 3D.

congusbongus
źródło
2
Jeśli posłuchasz komentarza do gry portalu, część sposobu działania portali jest realizowana poprzez klonowanie tego, co widać przez dziurę. (ale z powodów fizyki zamiast renderowania)
Kaczka Mooing
6

Pamiętaj, że to, co wyświetlasz na ekranie i co jest w pamięci, to dwie zupełnie różne rzeczy. Wyobraź sobie, że masz okno, które musisz wypełnić danymi o świecie. Wypełniasz okno od lewej do prawej. Podczas analizowania danych w celu wypełnienia świata, jeśli dotrzesz do końca świata, po prostu zapętl się z powrotem do początku swoich danych. Korzystanie z operacji modulo jest idealny. Pamiętaj, że musisz to zrobić dla wszystkiego . Pociski, promienie, gracze, fizyka; wszyscy muszą mieć zawinięte pozycje podczas przekraczania granic świata.

Każdy gracz udostępnia dane, ale ma swoją własną perspektywę. Ich okna są zapełniane w różny sposób w zależności od tego, gdzie stoją na świecie.

Oznacza to, że nie trzeba tworzyć klonów ani teleportować nikogo. Zasadniczo masz tworzenia klonów, po prostu renderowania postaci do siebie nawzajem ekranów.

MichaelHouse
źródło
3

Odłącz renderowanie od świata i możesz wykonywać zawijanie i poprawne renderowanie bez uciekania się do jakichkolwiek artefaktów klonowania lub teleportacji.

Po pierwsze, w swoim świecie masz świat o stałym rozmiarze, od 0do Width. Za każdym razem, gdy obiekt spadnie poniżej 0, zawijasz go do końca, a za każdym razem, gdy obiekt się kończy, Widthzawija go do początku. Oznacza to, że wszystkie logiczne obiekty w twoim świecie są zawsze w zasięgu 0...Width.

Po drugie, do renderowania zrobisz modulo na pozycji. Tak więc lewa strona ekranu to „Baza”, a prawa strona to „Baza + rozmiar”. Więc przeglądasz swój świat w poszukiwaniu czegokolwiek z tego zakresu. Będziesz faktycznie szukać zakresu modulo, który odwzorowuje go z powrotem 0...Width.

Sztuczka podczas wyszukiwania polega na zwróceniu pozycji obiektu względem Baselewej strony. Konwertuje to na lokalne współrzędne ekranu, dzięki czemu sam moduł renderujący nie musi martwić się o moduł, tylko wyszukiwanie.

Nie trzeba niczego klonować, ponieważ każdy mechanizm renderujący obsługuje obiekt tylko w jednym miejscu.

Jeśli twój świat jest produkowany w segmentach lub przy użyciu struktur 3D, musisz go podzielić na segmenty. Dlatego nie jest to jeden spójny blok, ale można go przenieść, aby dostosować się do tego renderowania. Nie potrzebujesz wielu bloków, co najmniej 2.

edA-qa mort-ora-y
źródło
1

Wydaje mi się, że jedynym rozsądnym podejściem byłoby wdrożenie twojego zawiniętego świata w podstawową strukturę danych całkowicie przejrzystą dla gry i użytkownika. Tak więc na niektórych poziomach niskiego poziomu masz funkcję mapCoordinate (), która zawija twoje rzeczywiste współrzędne do bazowego zasobu mapy ...

Więc jeśli twój rzeczywisty Świat ma tylko 10 jednostek szerokości, gracz i gra go nie poznają. Dla gracza świat jest nieskończony - a jeśli gra zapyta, co jest na pozycji 15 - podstawowa funkcja przetłumaczy to żądanie, modulo10 i da paczkę przedmiot na pozycji 5.

Tak więc dla całej logiki gry i wszystkiego innego jest tak, jakbyś miał nieskończony duży świat, w którym zdarzają się kopie wszystkiego.

Falco
źródło
1

To nie jest dokładnie to samo, ale zaimplementowałem coś podobnego w jamie gry. W grze gracze poruszali się na małym okrągłym poziomie, owiniętym wokół siebie, gdy gracz osiągnął pozycję „x” pi. Renderowanie było łatwe, ponieważ po prostu renderowaliśmy wszystko, a następnie obróciliśmy kamerę offsetową, aby śledzić, co się dzieje. Możesz zaimplementować coś podobnego, jak zasugerowano powyżej:

  • Podczas rysowania sprawdź pozycję kamery i określ, co należy narysować, biorąc pod uwagę pozycję kamery i jej zasięg widzenia.
  • W przypadkach, w których kamera widzi poza „krawędź” mapy, wybierz odpowiednią ilość treści z drugiej strony świata, aby narysować tę krawędź, zwykle po prostu dodając lub odejmując szerokość poziomu do ich pozycji.
  • Logika gry musi być świadoma tego szwu i dostosować się do niego, jak wspomniano w innych odpowiedziach. Szczególnymi przypadkami, o których należy pamiętać, są kolizje, w których jeden obiekt znajduje się po jednej stronie, ale koliduje z obiektem po drugiej stronie.
Chris
źródło