Jaka jest najprostsza metoda generowania gładkiego terenu dla gry 2D?

23

Jaka jest najprostsza metoda generowania gładkiego terenu dla gier 2D, takich jak „Moon Buggy” lub „Route 960”?

Otrzymałem odpowiedź na stackoverflow.com o wygenerowaniu szeregu losowych wysokości i rozmyciu ich później. Tak, jest całkiem w porządku. Ale lepiej byłoby podać kilka punktów i uzyskać gładką krzywą.

astropaniczny
źródło

Odpowiedzi:

13

Jednym ze sposobów na osiągnięcie tego jest:

  • Utwórz punkt na środku ekranu o losowej wysokości; masz teraz dwie sekcje, po jednej z każdej strony tego punktu
  • Dla każdej sekcji podziel na dwie części, umieszczając punkt pośrodku tej sekcji, z losową wysokością (dystansową) między dwoma sąsiadami
  • Powtórz n razy.

To, co się dzieje, to szczegółowość scenerii z każdą iteracją.

Sposób obsługi przypadków granicznych zależy od Ciebie: możesz na przykład przyjąć punkty w (0, wysokość / 2) i (szerokość, wysokość / 2).

Mam nadzieję że to pomoże!

EDYCJA: Oto zdjęcie, które wykonałem dla ilustracji:

terraingen

To ten sam pomysł!

Tim Kelsall
źródło
12

Zakładając, że chcesz naprawdę gładkiego terenu, sugeruję wycofanie się z odpowiedzi opartych na hałasie i zrozumienie, skąd pochodzą. Sygnał „szumu” jest zasadniczo sumą nieskończenie wielu sinusoid o losowych amplitudach, przy czym „średnia” amplituda przy danej częstotliwości jest podana w funkcji częstotliwości f . W ten sposób można uzyskać większość popularnych definicji „hałasu”. Na przykład ruch Browna ma wartość 1 / f ^ 2pasmo przenoszenia (to znaczy średnia amplituda przy danej częstotliwości jest odwrotnie proporcjonalna do kwadratu częstotliwości): oznacza to, że pobliskie punkty mają dość korelację ze sobą, ponieważ składowe wysokiej częstotliwości sygnału są silnie wytłumiony. Natomiast klasyczny hałas fraktalny (przesunięcie punktu środkowego, szum Perlina itp.) Ma charakterystykę częstotliwościową 1 / f ; istnieje większa wariancja między pobliskimi punktami, ale wciąż sporo korelacji. Idąc krok dalej, biały szum ma stałą odpowiedź częstotliwościową - nie ma żadnej korelacji między dowolnymi punktami.

Po co ci to? Cóż, możesz uzyskać gładki sygnał, który wciąż ma nieco głośny wygląd, po prostu zsumując garść sinusoidów, ale upewniając się, że mają odpowiednią amplitudę na danych częstotliwościach. Chcesz, aby częstotliwości były „losowe”, aby żadne z nich nie miały wspólnej wielokrotności (w przeciwnym razie otrzymasz okresowy komponent do ogólnego kształtu twoich wzgórz), więc sugeruję coś w rodzaju następującej procedury (zakończona z działającym przykładem):

  1. Wybierz losowo 4 (rzeczywiste) liczby z zakresu [1..10] - będą to częstotliwości twoich fal sinusoidalnych. „Rzuciłem kostką” na random.org i otrzymałem: f 0 = 1,75, f 1 = 2,96, f 2 = 6,23, a f 3 = 8,07. Nie ma nic magicznego w liczbie 4 (możesz użyć więcej, ale użycie mniejszej liczby spowoduje, że poszczególne fale sinusoidalne będą bardziej oczywiste) lub w zakresie od 1 do 10 tutaj (jest to tylko sposób na upewnienie się, że twoje najwyższe i najniższe częstotliwości nie są zbyt daleko od siebie). Sensowne może być wybranie jednej częstotliwości z zakresu [1..2], a reszty z zakresu [2..10], tak aby mieć znaną „dominującą” sinusoidę.
  2. Dla każdego z tych czterech (lub wielu) jednak częstotliwości f I wybrać amplitudy I znajduje się w zakresie pomiędzy -C / f i i C / F I dla pewnej stałej C . Wybrana tutaj wartość kontroluje całkowitą amplitudę fali - dla wygody wybrałem C = 1. Następnie potrzebowałem liczb losowych z zakresu [-1 / 1,75 (= -0,571) .. 1 / 1,75 (= 0,571) ], i podobnie w przedziałach [-0,338 .. 0,388], [-0,161 .. 0,161] i [-0,124 .. 0,124]. Czterokrotnie ponownie toczenia kości, mam do 0 = -0.143, a 1 = -0.180, 2 = -0.012, aa 3 = 0,088. (Zauważ, że prawdopodobnie nie jest to najlepszy sposób na wykonanie tego kroku - ponieważ maksymalna możliwa wartość funkcji jest sumą amplitud abs ( a 0 ) + abs ( a 1 ) + abs ( a 2 ) + abs ( a 3 ), bardziej sensowne może być podzielenie każdej z czterech wartości a i przez tę sumę po ich wygenerowaniu, a następnie pomnożenie każdej z nich przez C , aby mieć pewność, że dokładne maksimum, jakie może osiągnąć funkcja, to C .)
  3. Pick cztery „przesunięcia” o I , każdy w zakresie [0..2π] (0..6.28) - będą one dostosować Punktem wyjścia swoich fal tak, że nie wszystko zaczęło się od 0. Mam o 0 = 1,73, o 1 = 4,98, o 2 = 3,17, a o 3 = 4,63.
  4. „Rysuj” funkcję f (x) = a 0 sin ( f 0 (kx + o 0 ) ) + a 1 sin ( f 0 (kx + o 1 ) ) + a 2 sin ( f 0 (kx + o 0 ) ) + a 3 sin ( f 0 (kx + o 0 ) ) - tutaj k jest kolejną stałą, która kontroluje poziomy rozciągnięcie twoich funkcji. Musisz dowiedzieć się, co to jest dla twojej aplikacji; dla wygody właśnie wybrałem k= 1, więc moją ogólną funkcją jest f (x) = -0,143 sin (1,75 ( x + 1,73)) - 0,180 sin (2,96 ( x +4,98)) - 0,012 sin (6,23 ( x +3,17)) + 0,088 sin (8,07 ( x +4,63)).

Oto wynik mojego przykładowego uruchomienia, jak pokazano w Wolfram Alpha - zauważ, że naprawia on rozmiar swoich wykresów do celów wyświetlania, ale że powinieneś mieć dużą kontrolę nad poziomym i pionowym rozciągnięciem wyniku za pomocą stałych, o których wspomniałem powyżej :

Prosta losowa sinusoida

Steven Stadnicki
źródło
10

Algorytm przemieszczenie punktu środkowego może generować 2d piękny teren.

przykład terenu

Jest subtelna różnica między przesunięciem punktu środkowego a tym, co sugeruje @tykel. Algorytm Tykela dzieli horyzont i wybiera nową wysokość. Tworzy to teren, w którym szczyty są równomiernie rozmieszczone. Ludzie są dobrzy w doborze prawidłowości, więc generowany teren będzie wydawał się generowany, a nie naturalny.

Moc punktu środkowego pochodzi z wybrania punktu środkowego, a następnie przesunięcia wzdłuż normalnej linii. To powoduje, że piki zmieniają się w górę i w dół, a także na boki. Powstały teren to fraktale, a ludzie postrzegają fraktale jako naturalne.

Przypadkowe przemieszczenie wysokości może spowodować zejście terenu, jeśli wprowadzisz kilka dodatkowych parametrów (przemieszczenie w poziomie, maksymalne nachylenie itp.). Podkreśla to kolejną siłę MPD; jest bardzo prosty do dostrojenia. Dwa parametry, nierówność i poziom szczegółowości.

deft_code
źródło
7

Za pomocą funkcji szumów można generować losowe wysokości. Najprostszym z nich jest szum wartości, który działa dokładnie tak, jak opis: generujesz losowe wysokości całkowite, a następnie interpolujesz wysokości między nimi. Najczęściej stosowaną metodą interpolacji jest odwzorowanie sześciennej krzywej S:

Załóżmy, że masz wysokość h0w punkcie x0i wysokość h1w punkcie x1. Następnie, aby uzyskać wysokość w dowolnym punkcie x( x0<=x<=x1), używasz

t = (x-x0)/(x1-x0); // map to [0,1] range
t = t*t*(3 - 2*t); // map to cubic S-shaped curve
h = h0+t*h1;

Wysokości uzyskane w ten sposób będą gładkie, losowe, ale niezbyt interesujące. Aby poprawić swój teren, możesz użyć fraktalnego hałasu . Działa to tak: załóżmy, że wygenerowałeś funkcję, h(x)która zwraca wysokość przy danej współrzędnej (używając powyższej metody). Ta funkcja ma częstotliwość określoną przez częstotliwość pierwotnych wysokości intergerów. Aby zrobić z niego fraktal, łączysz funkcje z kilkoma częstotliwościami:

fbm(x)=h(x) + 0.5*h(2*x) + 0.25*h(4*x) + 0.125*h(8*x);

W tym przykładzie łączę cztery częstotliwości - oryginalną, podwójną, 4-krotną i 8-krotną oryginalną, przy czym wyższe częstotliwości mają mniejszą wagę. Teoretycznie fraktale sięgają nieskończoności, ale w praktyce wymaga tylko kilku określeń. fbmWe wzorze oznacza ułamkowego ruchu Browna - jest to nazwa tej funkcji.

To jest potężna technika. Możesz grać z mnożnikiem częstotliwości, z wagami o różnych częstotliwościach lub dodawać funkcje zniekształcające hałas. Na przykład, aby uzyskać bardziej „wypukłe” odczucie, h(x)można zmienić na 1-abs(h(x))(zakładając -1<=h(x)<=1)

Jednak chociaż wszystko to jest miłe, technika ta ma poważne ograniczenia. Dzięki podejściu opartemu na „linii wysokości” nigdy nie możesz mieć „nawisów” terenu. I wyobrażam sobie, że będą to bardzo fajne funkcje w grze podobnej do „Moon Buggy”.

Dodawanie ładnych zwisów jest trudnym zadaniem. Jedną rzecz, o której mogę myśleć - możesz zacząć od fraktalnej „linii wysokości” i „mozaikować” ją w serię splajnów lub krzywych Beziera. Następnie linia terenu zostanie zdefiniowana przez kilka „kluczowych punktów”. Zastosuj drgania w tych kluczowych punktach - spowoduje to przypadkowe odkształcenie terenu, prawdopodobnie tworząc ciekawe kształty. Jednak samo skrzyżowanie terenu może stać się problemem przy takim podejściu, szczególnie przy dużych wahaniach.

Nieważne
źródło
4

Istnieją dwie popularne metody generowania map wysokości terenu.

Niektóre podane tutaj odpowiedzi są już oparte na algorytmie Diamentowego kwadratu, ale znajomość nazwy ułatwia wyszukiwanie dodatkowych informacji. Hałas Perlina ma również inne zastosowania, więc i tak warto to sprawdzić.

sprzedać
źródło
OP mówi o krajobrazach 2D w stylu mario, ale nadal są to dobre linki.
tenpn
1

Moim pomysłem byłoby stworzenie wygładzonej funkcji szumu. Najpierw metoda intNoise (int), która zwraca „losową” liczbę int, ale która zależy od danych wejściowych. Jeśli użyjesz tego samego wejścia dwa razy, wynik będzie taki sam.

Następnie użyj metody wygładzania, aby utworzyć zmiennoprzecinkową (zmiennoprzecinkową), która używa dwóch liczb całkowitych wokół danych wejściowych do utworzenia wartości losowej.

Następnie użyj pozycji X jako danych wejściowych i Y jako danych wyjściowych. Rezultatem będzie wygładzona krzywa, ale o losowej wysokości.

XGouchet
źródło