Який найпростіший спосіб генерувати рівну місцевість для 2d гри?


23

Який найпростіший спосіб генерувати рівний ландшафт для 2d гри, наприклад "Moon Buggy" або "Route 960"?

Я отримав відповідь на сайті stackoverflow.com про створення масиву випадкових висот і розмиття їх пізніше. Так, це цілком нормально. Але краще було б дати кілька очок і отримати плавну криву.

Відповіді:


13

Один із способів досягти цього можна наступним чином:

  • Створіть точку посередині екрана, з випадковою висотою; тепер у вас є два розділи, по одному на кожній стороні цієї точки
  • Для кожного розділу розділіть на два місця, поставивши крапку в середині цього розділу, з (діапазонною) випадковою висотою між двома його сусідами
  • Повторіть n разів.

Що трапляється, це деталізація в декорації стає точнішою з кожною ітерацією.

Як ви керуєтесь крайовими справами, залежить від вас: ви можете припустити, наприклад, точки (0, висота / 2) та (ширина, висота / 2).

Сподіваюся, це допомагає!

EDIT: Ось малюнок, який я зробив для ілюстрації:

terraingen

Це та сама ідея!


12

Припускаючи, що ви хочете насправді рівний ландшафт, я б запропонував відступити від відповідей на шумі та зрозуміти, звідки вони беруться. Сигнал "шуму" - це по суті сума нескінченно багатьох синусоїд випадкових амплітуд, причому "середня" амплітуда на заданій частоті задається функцією частоти f . Таким чином, ви можете отримати більшість загальних «шумових» визначень. Наприклад, броунівський рух має 1 / f ^ 2частотна характеристика (тобто середня амплітуда на заданій частоті обернено пропорційна квадрату частоти): це означає, що точки поблизу мають досить білу кореляцію між собою, оскільки високочастотні компоненти сигналу сильно амортизований. Навпаки, класичний фрактальний шум (зміщення середньої точки, шум Перліна тощо) має частотну характеристику 1 / f ; Між точками, що знаходяться поблизу, є більше варіацій, але кореляція все ще є дещо. Пройшовши крок далі, білий шум має постійну частотну характеристику - взагалі немає кореляції між будь-якими точками.

Якого блага це робиш? Ну, ви можете отримати плавний сигнал, який все ще має трохи галасливого вигляду, просто підсумувавши жменю синусоїд, але переконавшись, що вони мають відповідну амплітуду на будь-якій заданій частоті. Ви хочете, щоб частоти були "випадковими", щоб жодна з них не мала спільного множини (інакше ви отримаєте періодичний компонент до загальної форми ваших пагорбів), тому я б запропонував щось на зразок наступної процедури (завершити з робочим прикладом):

  1. Виберіть навмання 4 (справжні) числа в діапазоні [1..10] - це будуть частоти ваших синусоїд. Я 'розкатав кістки' на random.org і отримав: f 0 = 1,75, f 1 = 2,96, f 2 = 6,23, і f 3 = 8,07. Нічого магічного в цифрі 4 (ви можете використовувати більше, але використання меншої кількості почне робити окремі синусоїди більш очевидними) або діапазон від 1 до 10 тут (це просто спосіб переконатися, що ваш найвищий і найнижчий рівень частоти не надто далеко один від одного). Можливо, має сенс вибрати одну частоту в діапазоні [1..2], а решту в діапазоні [2..10], просто щоб у вас був відомий «домінуючий» синусоїд.
  2. Для кожного з цих чотирьох (або скільки) частот F I , вибрати амплітуду я де - то в інтервалі між -C / F я і C / F I для деякої константи C . Вибране тут значення контролює загальну амплітуду вашої хвилі - для зручності я вибрав C = 1. Потім мені потрібні були випадкові числа в діапазоні [-1 / 1.75 (= -0.571) .. 1 / 1.75 (= 0.571) ] і аналогічно в діапазонах [-0.338 .. 0.338], [-0.161 .. 0.161] та [-0.124 .. 0,124]. Перекочуючи кістки чотири рази знову, я отримав в 0 = -0.143, а 1 = -0.180, 2 = -0.012, іa 3 = 0,088. (Зверніть увагу, що це, мабуть, не зовсім найкращий спосіб зробити цей крок - оскільки максимально можливе значення функції - це сума амплітуд abs ( a 0 ) + abs ( a 1 ) + abs ( a 2 ) + abs ( 3 ), це могло б мати більше сенсу ділити кожен з ваших чотирьох через я значень на цю суму , як тільки ви згенерували їх, а потім помножити кожен один на C , так що ви можете бути впевнені , що точна максимальна функція може досягти в C .)
  3. Виберіть чотири «зсуви» o i , кожне в діапазоні [0..2π] (0..6.28) - вони змінять початкові точки ваших хвиль, щоб вони не починалися з 0. Я отримав o 0 = 1,73, o 1 = 4,98, o 2 = 3,17, і o 3 = 4,63.
  4. 'Накреслити' функцію 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 ) ) - тут k - ще одна константа, яка керує горизонтальним 'розтягуванням' ваших функцій. Вам доведеться з’ясувати, що це для вашої власної програми; для зручності я щойно вибрав k= 1, і тому моя загальна функція - 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)).

Ось результат мого прикладу запуску, як зображено в Wolfram Alpha, - зауважте, що він фіксує розмір своїх графіків для цілей відображення, але що ви повинні мати достатній контроль над горизонтальною і вертикальною розтяжкою результату через константи, про які я згадував вище :

Простий випадковий синусоїд


10

Алгоритм переміщення середньої точки може генерувати чудові 2d місцевості.

приклад місцевості

Між переміщенням середньої точки та тим, що пропонує @tykel, є тонкі відмінності. Алгоритм Тікеля підрозділяє горизонт і вибирає нову висоту. Це створює місцевість, де вершини рівномірно розташовані. Люди чудово підбирають закономірності, тому генерований рельєф здасться створеним, а не природним.

Потужність середини походить від вибору середини, а потім переміщення по нормалі цієї лінії. Це призводить до того, що вершини змінюються вгору та вниз, а також в бік. У результаті місцевість є фрактальною, і людина сприймає фрактали як природні.

Випадкове зміщення висоти може призвести до спуску місцевості, якщо ви введете ще пару параметрів (горизонтальне зміщення, максимальний нахил тощо). Це підкреслює ще одну із сильних сторін MPD; це дуже просто настроювати. Два параметри, чіпкість і рівень деталізації.


7

Ви можете використовувати функції шуму для генерації випадкових висот. Найпростіший з них - значення шуму, який працює точно так само, як і ваш опис: ви генеруєте кілька випадкових цілих висот, а потім інтерполюєте висоти між ними. Найпоширенішим методом інтерполяції є кубічне відображення S-кривої:

Припустимо, у вас є висота h0в точці x0і висота h1в точці x1. Потім для отримання висоти в будь-якій точці x( x0<=x<=x1) ви використовуєте

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;

Висоти, отримані таким чином, будуть плавними, випадковими, але не дуже цікавими. Щоб покращити свою місцевість, ви можете використовувати фрактальний шум . Це працює так: припустимо, ви створили функцію, h(x)яка повертає висоту за заданою координатою (використовуючи метод вище). Ця функція має частоту, визначену частотою вихідних міжгірських висот. Щоб зробити з нього фрактал, ви комбінуєте функції з кількома частотами:

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

У цьому прикладі я поєдную чотири частоти - оригінальну, подвійну, 4-кратну та 8-кратну оригінальну, при цьому більш високі частоти мають меншу вагу. Теоретично фрактали проходять весь шлях до нескінченності, але на практиці потрібно лише кілька термінів. fbmУ формулі позначає дробове броунівський рух - це ім'я цієї функції.

Це потужна техніка. Ви можете грати з множником частоти, з вагами різної частоти або додавати деякі функції для спотворення шуму. Наприклад, щоб отримати більше відчуттів, h(x)можна змінити 1-abs(h(x))(припускаючи -1<=h(x)<=1)

Однак, хоча все це приємно, ця методика має серйозні обмеження. При підході, що базується на "висоті", ви ніколи не можете мати "перегини" на місцевості. І я уявляю, що це дуже приємна особливість мати у грі, подібній до "Moon Buggy".

Додавання приємних нависів - важке завдання. Одне, що я можу придумати, - ви можете почати з фрактальної "висоти", а "тесселяти" її в ряд сплайнів або кривих Безьє. Тоді лінія місцевості буде визначена декількома «ключовими точками». До цих ключових моментів застосуйте трохи тремтіння - це призведе до випадкової деформації місцевості, ймовірно, утворить якісь цікаві форми. Однак самопересічення рельєфу місцевості може стати проблемою при такому підході, особливо при великій кількості тремтіння.


4

Існують два популярні методи генерування карт висоти місцевості.

Деякі відповіді, наведені тут, вже засновані на алгоритмі алмазного квадрата, але знання назви полегшує пошук додаткової інформації. У шуму Перліна також є і інші напрямки використання, тому його все одно добре перевірити.


В ОП йдеться про 2D-пейзажі в стилі маріо, але все-таки це хороші зв’язки.
tenpn

1

Моєю ідеєю було б створити функцію згладженого шуму. Спочатку з методом intNoise (int), який повертає "випадковий" int, але це залежить від введення. Якщо два рази використовувати один і той же вхід, результат буде однаковим.

Потім використовуйте метод згладжування, щоб зробити floatNoise (float), який використовує два цілі числа навколо вводу для побудови випадкового значення.

Потім використовуйте позицію X як вхід, а Y як вихід. В результаті вийде згладжена крива, але з випадковою висотою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.