Проектик этот — мой, случайно напомнивший о себе, пока наводился порядок в книжном шкафу. Тема его, тогда, 5 лет назад, казалась ужасно крутой и звучала так: «Методы генерации игровых карт». Чуть выше пример того, что у меня получалось. Как видите, это стилизованные под рогалик примеры уровней какой-то там несуществующей игры. Но обо всём по порядку.
Писалось всё это произведение в стареньком Dev-C++ версии 4.9. В общем, в то время я больше и не умел ничем пользоваться. Visual Studio я не признавал, так как он был громоздким, и создавал кучу каких-то файликов, а C++ Builder был необычен кучей открытых окон. В качестве магии, выводящей графику использовался QuickCG. Очень простая библиотечка — прослойка SDL — которую очень, наверное, умный человек писал для попиксельного вывода. Для создания old-school эффектов: огонь на пол экрана, эффект туннеля, raycasting, и т.д. К слову я и сейчас не знаю связки лучше за Dev-C++ и QuickCQ для того, чтобы учиться работать с графикой.
Программка позволяла делать ландшафты и уровни, правда ограничивались они размерами окна. Если верить описанию проекта, которое должно было быть как можно больше, и туда вливались океаны воды, то карты делятся на глобальные, местности, и специальные. И естественно мое творчество умело всё это делать.
Все способы создания глобальных карт я делил на 3 типа: рекурсией, фракталами и по карте высот. Следует сразу уточнить, что к третей группе относились способы, использующие шумы, или какие-то двумерные функции. Что такое рекурсия, я хоть и понимал, но не знал как толком использовать, про фракталы можно было и не говорить, поэтому генератор умел делать только карты, основанные на шуме перлина. Естественно тогда я не понимал никаких формул, а потому реализация была взята и сайта QuickCG, где таким образом делались тучки.
Алгоритм был прост: сначала генерировали шум. Получалось скучная серая картинка. Если скучно и серо — значит нужно раскрасить. Добавляется цвет. Для этого яркость шума объявляется высотой, и в зависимости от высоты окрашивается пиксель. Какое-то время я думал добавить и уровень песка — по получалось не очень. Итого в результате имели место 4 биома: вода, трава, горы и снег.
Потом добавлялись объекты, а именно деревья, города и реки. С деревьями всё просто: берем случайную точку на траве и сажаем туда дерево. На карте они обозначены тёмно-зелёными точками. Потом города. Они делались так же как и деревья, но могли располагаться возле воды, и иногда на траве и в горах. Обозначались они коричневыми кружочками.
С реками всё обстояло не намного сложнее. Выбирается точка на карте, выше уровня моря, и циклом спускается вниз, пока не попадёт в воду, или некуда будет спускаться. В последнем случае вокруг данной точки рисуется озеро.
На этом возможности генератора глобальных карт заканчивались. Идём дальше. Карты местности я делил на 3 вида: леса, водоемы и города.
Леса, по умолчанию, замусоривались листьям, и потом расставлялись деревья, состоящие из кроны, формы ромбика, и коричневой палки, пробивающей крону, и добавленной, чтобы игрок не проходил насквозь через деревья. Возможно вы заметили значок "@" на картинках — так вот это игрок. И им можно было управлять.
Чтобы создать реку, на краю карты выбиралась точка, направо и налево от нее создавалась вода, и веселым потоком, прокладывался путь к противоположной стороне окна, постоянно сдвигаясь либо вправо, либо влево, либо не сдвигаясь. Для экстерьера добавлялся домик, пару деревьев и пару жителей. Домик представлял собой прямоугольничек случайного размера, разукрашенный в 2 цвета, имитирующие черепицу освещенную и не освещённую солнцем.
И напоследок городок. Сначала весь город заращивается плиткой. Потом с неба кидаются дома. Если дом пробивает другой дом, то не беда, назовём это такой архитектурой. После домопада в город приходят жители. Становятся на свободные от домов места и ждут. А ждут они самого главного, без чего город не может существовать, а именно системы доставки воды. В данном случае оная представлена колодцем, которым мог появится как на главной площади, так и в месте закрытом домами.
И напоследок остались специальные карты, к которым я относил специальные зоны, такие как подземелья, пещеры и лабиринты.
Начнем с самого простого. Пещеры с самого начала заполнены непроходимой породой. В центре ставим пустоту и двигаемся в каком-то направлении. Например направо. Потом двигаемся вверх. Потом ещё куда-то. И так раз под 100. А потом становимся в центр и начинаем всё сначала. Через итераций 20-30 получим пещеру.
Дальше будут подземелья. Они тоже заполнены непроходимой породой, в которой вырезаются прямоугольные комнаты. Стены комнаты в случайных местах обваливаются. Если вдруг комната появится посреди другой комнаты — не беда — спишем на особенность архитектуры.
И напоследок лабиринт. Есть много случаев генерации лабиринтов: рекурсия, краскала, прима, нейросети. В моем случае использовался рекурсивный метод, стыренный с глубин интернета. Выбираем точку, выбираем направление — идем, выбираем направление — идем, не можем идти — возвращаемся назад. Несложно, но чтобы понять как оно работает у меня ушло много времени.
В общем проектик больше ничего не умел. Он не сохранял карты, он не мог отрендерить их в bmp., он мог только генерировать карты и сразу же их показывать. Маловато конечно, но для меня, того времени это было нечто. Вот такое было какое-то время увлечение. А потом появился raycasting типа Doom-а с брожением по лабиринту, потом генератор стал показывать в 3d и другие измерения. Но об этом как-то в другой раз.
На этом всё. Спасибо за внимание. Живите и процветайте.
ссылка на оригинал статьи http://habrahabr.ru/post/202186/
Добавить комментарий