Всем привет!
Сделал небольшой
генератор подземелий по примеру
этой статьи. Возможно, кому-то кроме меня он еще пригодится, поэтому решил оформить это все экстеншеном и выложить сюда.
Подземелья генерируются примерно такого типа:
1.

2.

3.

Красными выделены основные комнаты. Белым - коридоры. Синим выделены побочные комнаты, они являются частью "системы коридоров" или даже самими коридорами. Я бы мог так же выделить их белым, но для наглядности оставил синим цветом. Кроме того подсвечены главные и побочные выходы из основных комнат. Побочные выходы можно использовать в качестве потайных стен, потому что даже если выход не будет найден, то все равно гарантирована достижимость до всех комнат. Главное использовать желтые выходы - они основные.
Используя этот генератор вы получаете объект подземелья в виде ds_map. В этом объекте имеются: а) сетка, на которой отмечены главные, побочные комнаты, коридоры и выходы; все это определено константами; б) граф, с узлами в виде главных комнат; в графе отмечены основные и побочные проходы; в) список всех основных и побочных комнат с указанием их размеров и местоположения.
В экстеншене определено несколько функций для основного использования.
Три метода для генерации подземелья. Начиная от самого простого с минимум настроек и заканчивая полным методом генерации.
pg_create_dungeon(seed)
pg_create_dungeon_ext(seed, number, ellipse_width, ellipse_height, size, ways)
pg_create_dungeon_full(seed, number, ellipse_width, ellipse_height, min_width, max_width, min_height, max_height, main_width, main_height, ways, ways_length)
- seed - задает семя подземелья
- number - количество комнат для генерации (всего, т.е. основных и побочных)
- ellipse_width, ellipse_height - ширина и высота эллипса, в пределах которого производить генерацию; меняя эти параметры вы получаете подземелья различной формы; я обычно ставлю 50/20
- size - размер случайно генерируемых прямоугольников; приблизительно такого размера будут генерироваться комнаты; мое оптимальное значение - 12
- min_width, max_width, min_height, max_height - тоже размер случайно генерируемых прямоугольников, но более детальный
- main_width, main_height - размер основных комнат; все комнаты равны или больше этого размера будут помечены, как основные
- ways - процент создаваемых побочных коридоров; может быть от 0 и больше; используйте 0, если побочные коридоры вам не нужны; обычное значение - 15%
- way_length - максимальная длина побочных коридоров; для себя я подобрал оптимальное значение в 50
При успешной генерации методы возвращают объект dungeon в виде ds_map. Объект имеет следующие поля:
dungeon[? "seed"] //семя подземелья
dungeon[? "width"] //ширина всего подземелья в клеточках
dungeon[? "height"] //высота всего подземелья в клеточках
dungeon[? "grid"] //сетка, на которой отмечена основная информация
dungeon[? "rooms"] //ds_map, содержащая в себе все комнаты в подземелье
dungeon[? "main rooms"] //ds_list с ключами от основных комнат карты "rooms"
dungeon[? "side rooms"] //ds_list с ключами от побочных комнат карты "rooms"
dungeon[? "graph"] //ds_map, содержащая в себе граф/пути в подземелье
dungeon[? "main ways"] //ds_list с ключами от карты "graph" для основных путей
dungeon[? "side ways"] //ds_list с ключами от карты "graph" для побочных путей
Следующий метод уничтожает объект подземелья и освобождает всю выделенную память.
pg_destroy_dungeon(dungeon)
- dungeon - объект подземелья в виде ds_map
Данный метод возвращает сурфейс с нарисованным подземельем. Отрисовывает он его как на скринах.
pg_draw_dungeon(dungeon, tile_size, exits)
- dungeon - объект подземелья
- tile_size - размер рисуемых клеточек, я обычно ставлю 4
- exits - рисовать ли выходы, true/false
Методы для сохранения/загрузки подземелья в файлах. Метод загрузки возвращает загруженный объект подземелья.
pg_save_dungeon(filename, dungeon)
pg_load_dungeon(filename)
- filename - имя файла для чтения/записи
- dungeon - подземелье для записи
Несколько утилитарных методов, проверяющих является ли ячейка (x, y) коридором, комнатой, выходом и т.д. В экстеншене определены константы (DG_EMPTY, DG_SIDE_ROOM, DG_MAIN_ROOM, DG_CORRIDOR, DG_EXIT, DG_SIDE_EXIT), используя которые можно добиться того же самого.
pg_is_corridor(grid, x, y)
pg_is_exit(grid, x, y)
pg_is_side_exit(grid, x, y)
pg_is_empty(grid, x, y)
pg_is_main_room(grid, x, y)
pg_is_side_room(grid, x, y)
Если есть какие-то вопросы или замечания, пишите.
