» » » Простой и быстрый алгоритм генерации ландшафта

 

Простой и быстрый алгоритм генерации ландшафта

Автор: admin от 10-01-2017, 14:00, посмотрело: 52

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

В какой ситуации удобен алгоритм

Недавно столкнулся с задачей: написать простую стратегию с трёхмерным ландшафтом. Так как я в данный момент обладаю маленьким опытом программирования на языке С++, мои попытки написать «diamond-square» закончились ошибками на ровном месте (ссылка на статью по «diamond-square» также будет в конце). Требовался простой в написании алгоритм, не дающий реалистичный ландшафт, так что данный метод поможет в первую очередь новичкам.

Алгоритм и результат

Прежде чем описывать сам алгоритм поделюсь его результатами:

Простой и быстрый алгоритм генерации ландшафта

Алгоритм заключается в том, что программа в случайных координатах заполняет карту прямоугольниками случайного размера. Карта имеет вид двухмерного массива, представляющего карту высот нашего ландшафта.

Для простоты создадим структуру прямоугольника:

struct tRect  
{
	int x1, y1, x2, y2;
}

Переменные x1 и y1 — левая нижняя координата прямоугольника, x2 и y2 — правая верхняя.

Пусть:

— Наша карта представлена в виде массива HM[mapsizex][mapsizey];
— mapsizey и mapsizex — переменные, определяющие размер вашей карты;
— genStep — переменная, отвечающая за количество наших прямоугольников;
— zscale — некий коэффициент растяжения карты в высоту. Можно заменить числом.
— recSizex и recSizey — пределы размеров прямоугольника.

Теперь необходимо заполнить нашу карту прямоугольниками:


for (int i=0; i<genStep; i++)
    {
        genRect.x1 = rand()%mapsizex;
        genRect.y1 = rand()%mapsizey;
        genRect.x2 = genRect.x1 + recSizex / 4 + rand()%recSizex;
        genRect.y2 = genRect.y1 + recSizey / 4 + rand()%recSizey;
        if (genRect.y2 > mapsizey) genRect.y2 = mapsizey;
        if (genRect.x2 > mapsizex) genRect.x2 = mapsizex; 
        for (int i2 = genRect.x1; i2<genRect.x2; i2++)
                for (int j2 = genRect.y1; j2<genRect.y2; j2++)
                    Map.HM[i2][j2]+= float(zscale) / float(genStep) + rand()%50 / 50.0;
    }

Рельеф со скриншота был получен значениями:

genStep = 1024
zscale = 512
mapsizex и mapsizey = 128
recSize = 10

Далее вы выводите карту на экран любым доступным вам способом. В моём случае — openGl+glfw.

Преимущества и недостатки алгоритма

Преимущества:


  • Простота и скорость в написании самого алгоритма

  • Скорость исполнения алгоритма


Недостатки:


  • Примитивность

  • При маленьком шаге заполнения карты ландшафт становится «квадратным»

  • Отсутствует возможность разбивать ландшафт на биомы по ходу генерации карты высот


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

Надеюсь, данная статья была Вам полезной.

-> Статья про генерацию игровых уровней
-> Статья про «diamond-square»

Источник: Хабрахабр

Категория: Программирование » Веб-разработка

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

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *