Генерация ландшафта как в MineCraft

image

Всем доброго времени суток.
Я хотел бы поделиться личным опытом по поводу генерации ландшафтов. Всё началось с того что я поиграл в Minecraft и больше всего меня поразил ландшафт, это был случайно генерируемый и при этом красивый ландшафт. Вообще признаюсь честно давно я не получал такого эстетического удовольствия глядя на уходящие в даль кубообразные холмы.

Конечно мне стало интересно, а как же такое вообще работает, на каких именно алгоритмах и все в этом духе. Долго ковыряясь с самой игрой, а так же облазив многие сайт с модами я узнал не так много, как хотелось бы, но позже нашел статью в блоге разработчиков о там как они раньше создавали свой ландшафт. Естественно я тоже решил попробовать создать свою версию ландшафта. Скажу честно, даже после прочтения той статьи пришлось долго искать на предмет других алгоритмов генерации ландшафтов, эрозии, биомов и сглаживания.

И так собственно о том, как я делал. Сначала я попробовал делать на основе шума Перлина (строил карту высот и по ней уже создавал 3д ландшафт), получилось достаточно интересно, но как видно не очень-то и похоже на Minecraft.

В 2д варианте это выглядело вот так.
Упрощенный пример кода для шума Кена Перлина.

for x:=-20 to 20 do
for y:=-20 to 20 do begin
n := x + y * 57;
n := (n shl 13) xor n;
ObjectCount:=ObjectCount+1;
Engine.AddProxy(PerlinCube,RootCube,'Cube'+IntToStr(ObjectCount),FileListBox1.FileName,x,2*(1 - ((n * (n * n * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824),y,0,1,0,1,1,1);
Map2[x,y]:='Cube'+IntToStr(ObjectCount);
end;




В 3д смотрится лучше, да и то из за добавленного уровня воды.


После прочтения статьи модифицировал, так как примерно было раньше в самой игре. Для каждого столба блоков высота равнялась (общ_высота + (шероховатость*детали))*64+64. От себя я добавил простое сглаживание. Получилось гораздо лучше.

Вот упрощенная часть кода для небольшого куска:

pod:=4;
nerov:=2;
melk:=1;

for x:=-20 to 20 do
for y:=-20 to 20 do begin
nerov:=Random(3);
melk:=Random(2);
Map1[x,y]:=((pod+(nerov+melk))*5+5)-25;
end;

Engine.AddUCube(RootCube,'PerlinCube',FileListBox1.FileName,x,(1 - ((n * (n * n * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824),y,0,1,0,1,1,1);

for x:=-20 to 20 do
for y:=-20 to 20 do begin
ObjectCount:=ObjectCount+1;
Engine.AddProxy(PerlinCube,RootCube,'Cube'+IntToStr(ObjectCount),FileListBox1.FileName,x,map1[x,y],y,0,1,0,1,1,1);
Map2[x,y]:='Cube'+IntToStr(ObjectCount);
end;



Я заснял поэтапно.

1. Построен кусочек карты.


2. Добавлен шум Перлина.


3. Первый цикл сглаживания.


4. Второй цикл сглаживания.


5. В конце немного деревьев что было не так уныло.


Результатом я доволен, правда для полноценной игры вроде Minecraft он не дотягивает, но для 2д аркады в самый раз. Именно туда я прикрутил генерацию разреза ландшафта и отбрасывал кубы которые выше или ниже границы что бы было более удобно с точки зрения геймплея аркады.


Ссылки.
Кому интересно вот ссылка на перевод статьи о ландшафте Minecarft.
Очень понравилась статья о шуме Перлина ссылка.
Так же напомнили про очень интересную статью по генерации ландшафтов ссылка.
Поделиться публикацией

Комментарии 16

    +3
    На всякий случай спрошу, а то в посте нет ссылки, вот эту статью видели?
      +1
      Видел, но в minecraft'е, насколько мне известно не использовали описанных там алгоритмов. Хотя думаю все таки внести стоит, так что спасибо что напомнили.
        +2
        Да, когда я писал статью, я еще не знал точно, каким именно образом строится ландшафт в Minecraft. Мое предположение о его фрактальной природе оказалось ошибочным. Впрочем, рекомендую взглянуть на обновление 1.8, которое должно выйти на днях (уже доступен пререлиз) — в нем генерация стала еще лучше (и похоже, что как раз благодаря фрактальным алгоритмам). Сравните сами (обе карты размером 20000x20000 клеток):

        Было раньше:


        Стало теперь:
          +3
          Обновление посмотрю в ближайшее время, но судя по скриншотам, скорее всего используется гибридный алгоритм. Вообще с каждым обновлением генерация становиться все более реалистичной.
          Кстати напомнило концепцию roguelike игр, когда при каждой новой игре происходит генерация всего игрового мира.
            +1
            Собственно Minecraft создавался как подобие Dwarf Fortress (которая и Roguelike в том числе, но и ещё кое-что большее :) и там генерация уровней тоже выше всяких похвал.
      +3
      Настоятельно рекомендую вам сменить фотохостинг, а то он там всякую заразу предлагает установить.
        +1
        Сменил фотохостинг, этот должен быть нормальным.
        0
        MineCraft — великая игра, без сомнений.
          0
          Пока за вычетом игры, к сожалению. Сейчас МК больше похож на редактор или технодемку.
          Впрочем, Нотч обещает продвижки и в этом направлении.
            0
            Ну может, для кого то и за вычетом игры, но есть туева хуча серверов. На которых люди вполне неплохо, именно играют, а не редактируют.

            Мы с друзьями, допустим, подняли свой сервак и так же успешно рубимся. Ведь фан никто не отменял.
            Ну и не стоит забывать что это бетка, про полноценную игру, пока, никто не пишет.
          +1
          Мдя, визуализация убивает — зелёное монотонное нечто…
          Мы с приятелем с этим тоже столкнулись — решили тем, что сделали боковые грани кубов на пол-тона ниже, чем верхние… ;)
            0
            Согласен, страшновато смотрится. Думаю в последствии либо добавить биомы, либо сделать как в самом Minecraft, т.е. для боковых граней добавить текстуры иного цвета.
            Кстати по этому в 2 д я думаю это смотрится более привлекательно.
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Тоже можно, но в первую очередь думаю просто сделать небо с солнцем, а то белое пространство немного отвлекает )
            0
            а никто не подскажет, может существует готовый алгоритм генерации 2д ландшафта с равномерным распределением всех типов поверхности по всей карте? тоесть есть допустим лес, степь, пустыня, горы, снега и тд и нужно покрыть всю карту этими ландшафтами равномерно, но рандомными кусками — чтобы карта была не однообразной.
              0
              Вообще я лично таких алгоритмов не видел, вас же интересует не только ландшафт но и биомы. Как вариант можете попробовать использовать готовые алгоритмы комбинируя их, т.е. можете взять фрактальный алгоритм и к нему самостоятельно добавить биомы. В самом просто варианте можно, поделить случайным образом карту на климатические зоны и распределять биомы по высоте, не самый лучший вариант но тоже не плох.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.