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).
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 t
i d
(bardzo prosta: za każdy t
i d
wartości mogę uzyskać 3d położenie + góra / przód / lewy wektory). samochód jest teraz przyklejony do drogi
3) sprawdź boczne przemieszczenie d
samochodu. 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 t
pozycji 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).
źródło
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.
źródło