Всем доброго времени суток.Я хотел бы поделиться личным опытом по поводу генерации ландшафтов. Всё началось с того что я поиграл в Minecraft и больше всего меня поразил ландшафт, это был случайно генерируемый и при этом красивый ландшафт. Вообще признаю честно давно я не получал такого эстетического удовольствия глядя на уходящие в даль кубообразные холмы. Конечно мне стало интересно, а как же такое вообще работает, на каких именно алгоритмах и все в этом духе. Долго ковыряясь с самой игрой, а так же облазив многие сайт с модами я узнал не так много, как хотелось бы, но позже нашел статью в блоге разработчиков о там как они раньше создавали свой ландшафт. Естественно я тоже решил попробовать создать свою версию ландшафта. Скажу честно, даже после прочтения той статьи пришлось долго искать на предмет других алгоритмов генерации ландшафтов, эрозии, биомов и сглаживания. И так собственно о том, как я делал. Сначала я попробовал делать на основе шума Перлина (строил карту высот и по ней уже создавал 3д ландшафт), получилось достаточно интересно, но как видно не очень, то и похоже на землю. В 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(TGLCustomSceneObject(RootCube.FindChild('PerlinCube',true)),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(TGLCustomSceneObject(RootCube.FindChild('PerlinCube',true)),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.Так же очень понравилась статья о шуме Перлина ссылка.