W bardzo prostych grach wyścigowych 3D, w jaki sposób obsługiwane są kolizje?

9

Zastanawiałem się, jak dochodzi do kolizji w niektórych prostych grach wyścigowych 3D (szczególnie w grach takich jak Outrun 2 / Motoracer).

W klasycznych grach wyścigowych ze złożonym środowiskiem (otwarty świat), wydaje mi się, że odbywa się to za pomocą podstawowego pudełka (dla samochodu) do zderzenia samolotu (na tor, budynki i inne rzeczy). Całość zostałaby zoptymalizowana za pomocą niektórych obwiedni (tak właśnie się dzieje w wielu grach).

W grze takiej jak Outrun 2 / Motoracer rozgrywka jest tak prosta, że ​​programiści mogą jej nie potrzebować i wszystko można było znacznie uprościć. Dla tych, którzy nigdy nie grają, oto co jest tak specyficzne:

  • Samochód / rower jest zawsze przyklejony na drodze.
  • Droga ma zawsze ten sam rozmiar i ma bardzo prosty kształt.
  • Jedyne możliwości to podążanie tą drogą, nie jest możliwe zejście z niej lub zderzenie się z czymś innym (oprócz innych samochodów / motocykli, ale nas to nie obchodzi).
  • Kiedy zderzasz się z drogą, dochodzi do bardzo podstawowej kolizji zręcznościowej (samochód jest po prostu odsuwany od niej)

Oto, jak myślę, że można było zrobić kolizję:

Cały tor można uznać za gigantyczną krzywą 3D beziera. Z tej krzywej można wygenerować wielokąty drogowe (używając wektorów przednich, lewych i górnych wygenerowanych z krzywej). Inne elementy (takie jak domy, drzewa, ...) można również umieszczać i wyrównywać za pomocą tej metody.

Następnie, aby poradzić sobie z kolizjami (i narysować samochód):

1) Znajdź najbliższą pozycję na krzywej 3d od aktualnej pozycji samochodu 3d. Innymi słowy, przekształć pozycję samochodu 3D w pozycję krzywej Béziera. Każde położenie 3d na drodze można uznać za przemieszczenie wzdłuż krzywej 3d ( t) + przemieszczenie boczne ( d). Sprawdź obraz poniżej, jeśli nie jest wyraźny (jest to przykład 2d, ale dotyczy to łatwo 3d).

wprowadź opis zdjęcia tutaj

gdy t = 0 samochód znajduje się na początku odcinka toru, gdy t = 1 samochód jest na końcu. gdy d = -1 lub 1 samochód znajduje się na granicy toru, gdy d = 0 samochód znajduje się na środku drogi

2) dostosowanie samochodu do drogi przy użyciu ti d(bardzo prosta: za każdy ti dwartości mogę uzyskać 3d położenie + góra / przód / lewy wektory). samochód jest teraz przyklejony do drogi

3) sprawdź boczne przemieszczenie dsamochodu. jeśli wartość jest zbyt duża (d > 1)lub zbyt niski (d < -1)samochód jest poza torem. po prostu przypnij go, aby ustawić samochód we właściwym miejscu.

To również sprawia, że ​​wybijanie 3D jest bardzo proste, wystarczy narysować ścieżkę od aktualnej tpozycji samochodu do t + some_big_enough_value_to_avoid_visible_clipping.

A może całkowicie się mylę: byłoby o wiele szybsze i prostsze sprawdzenie kolizji samochodu (obwiednia) i bardzo uproszczonego zestawu wielokątów reprezentujących tor (bez budynków i tym podobnych). Świat 3D (i wynikowy model kolizji) zostałby po prostu wygenerowany wcześniej, przy użyciu narzędzia innej firmy (koniec krzywej 3D podczas uruchamiania gry, tylko kilka wielokątów).

tigrou
źródło

Odpowiedzi:

16

Pracowałem nad kilkoma komercyjnymi grami podobnymi do tych, które opisujesz.

W każdej z tych gier mieliśmy wielokąty tworzące niewidoczną „ścianę” wzdłuż boków toru i przeprowadzaliśmy tradycyjne testy kolizji z tymi ścianami. Oznaczało to, że mogliśmy mieć dodatkowe kolidujące zagrożenia z boku drogi, wewnątrz niewidocznych ścian, a także pozwolić nam zmieniać szerokość drogi szybciej niż zwykle przy podejściu wielowypustowym.

Ale powiedziawszy to, zrobiliśmy również to, co wymieniasz w moim zdaniem, w jaki sposób działałaby kolizja , aby uchronić się przed tunelowaniem / usterkami kolizji, a ten system był również intensywnie wykorzystywany do wyścigowej logiki AI. Wykorzystaliśmy go również do ustalenia, które samochody były na prowadzeniu, abyśmy mogli wyświetlić wskaźnik „1st / 2nd / 3rd / etc” na HUD. Czasami dane te były również wykorzystywane do odrodzenia samochodu po poważnej awarii.

Jedną z rzeczy, które przeoczyłeś w moim zdaniem, w jaki sposób zadziałałoby zderzenie, jest to, że pracując z takimi splajnami, zwykle dajesz żebra splajnów. Żebra to fragmenty danych wyrażające, jak daleko ścieżka rozciąga się na boki w każdym kierunku od splajnu. Tak więc dla splajnu o długości 100 metrów możesz mieć 50 żeber, co daje szerokość toru co dwa metry wzdłuż jego długości. Pozwala to na zmianę szerokości śladu wzdłuż jego zasięgu. W grach, nad którymi pracowałem, żebra te rozróżniały również „powierzchnię toru” i „powierzchnię do jazdy”. Tak więc miałbyś jeden zestaw szerokości drogi mówiący, jak daleko od środka splajnu masz ładny asfalt, a następnie inny szerokość mówiący, jak daleko piasek / trawa / cokolwiek wychodzi poza to. Dzięki temu gracze mogą pokonywać rozsądną odległość poza torem, ale nadal mają sztuczną inteligencję, która wie, gdzie jest prawdziwa nawierzchnia drogi.

Wiele gier, nad którymi pracowałem, zawierało również inne dane w żebrach; jedna gra upiekła informacje o oświetleniu torów w żebrach, aby łatwo obliczyć, czy obszar był w cieniu (który następnie wykorzystano do renderowania samochodu, decydując, czy narysować flarę obiektywu, i inne efekty). Kolejne zawierało informacje o tym, które umiejscowienia kamery filmowej mogą zobaczyć tę część splajnu, więc nie musieliśmy wykonywać obliczeń dotyczących pola widzenia podczas powtórek. Jeszcze inna zawierała informacje o tym, ile pasów znajdowało się na splajnie, w którym kierunku poszli, oraz o przemieszczeniu poziomym, w którym znajdował się każdy pas. To pozwoliło nam uwzględnić samochody drogowe, które mogłyby prawidłowo jeździć w obrębie pasów drogowych. Żeberka są fantastyczne do przechowywania różnego rodzaju danych, których możesz potrzebować na temat swojej drogi.

Żeberka są zwykle przechowywane w tablicy powiązanej z splajnem. Ze względu na prędkość normalna implementacja będzie miała równomiernie rozmieszczone żebra, więc gdy poznasz odległość obiektu wzdłuż splajnu, możesz obliczyć najbliższy indeks żeber w tablicy, dzieląc odległość wzdłuż splajnu przez odległość między żebrami. W przeciwnym razie utkniesz podczas wyszukiwania binarnego przez tablicę żeber, aby znaleźć prawidłowe dane dotyczące szerokości drogi.

Twój opis uboju daje dobry podstawowy opis tego, jak można zastosować podejście do splajnu, ale w rzeczywistości jest nieco bardziej skomplikowany, niż sugerujesz - jeśli używasz splajnów do uboju w ten sposób, długie obroty szpilki do włosów często nie rysują przeciwnej strony zakrętu, ponieważ mierząc odległość wzdłuż toru, przeciwna strona zakrętu może znajdować się bardzo daleko, nawet jeśli jest mierzona zaledwie kilka metrów od linii prostej. Ponadto odległości, w których można zobaczyć geometrię świata, są zwykle różne niż odległości, w których można zobaczyć siatkę torów, więc te też nie pasują do tego systemu. Z mojego doświadczenia wynika, że ​​w większości przypadków lepiej nie polegać na logice śledzenia, aby ustalić, czy model powinien zostać narysowany; jest o wiele bardziej niezawodny i powoduje, że mniej błędów korzysta ze standardowych testów ścięcia aparatu.

Trevor Powell
źródło
Pouczająca i pouczająca
0

W moim wyścigu OpenGL początkowo użyłem dwóch kółek do zdefiniowania granic toru, ale wydawało mi się to zbyt wielkim problemem. Po prostu używam glReadPixel do odczytu koloru piksela. Jeśli samochód gracza ma ponad zielony piksel (trawa), ruch jest dalej ograniczony. Wpływ na wydajność ma bardzo mały wpływ.

ztech79
źródło
Brzmi to tak, jakbyś opisywał grę 2D (koła, kolidujące ze sobą kolory pikseli). Czy tak jest Zatem odpowiedź jest nie na temat.
Kromster
Mam na myśli grę w rzutowaniu perspektywicznym. glReadpixel może być stosowany w trybie 2D orto lub perspektywy 3D.
ztech79