Предыдущая часть:
Карта оригинального Rogue состоит из 9 комнат, расположенных матрицей 3*3. Между комнатами прокладываются проходы. Рассмотрим, как это сделать. Традиционно я не буду смотреть в исходный код, а буду изобретать собственный велосипед (не факт, что получится хорошо).
Итак, каждая комната, в зависимости от своего места в матрице, имеет несколько выходов. Например, комната, расположенная в левом верхнем углу (UL), может иметь только два выхода: вправо (R) и вниз (D). А комната, расположенная в центре (C), может иметь 4 выхода: U, R, D, L.
Я составил схему с обозначениями всех комнат и выходов:
Комнаты имеют разный размер и располагаются со сдвигами, поэтому может возникнуть ощущение, что они расставлены случайно, но на самом деле каждая из привязана к своей позиции в матрице.
На данный момент нужно сосредоточиться на том, как построить проход от точки А до соседней точки Б, игнорируя всё остальное. Соседние точки это те, которые соединены пунктирными линиями.
Рассмотрим вблизи два соседних выхода на вертикальных стенках:
Каждый выход это некая координата на стенке комнаты, но так как карта состоит из клеток, то координаты выходов привязаны к клеткам. Между этими двумя клетками нужно построить маршрут, который также должен проходить по клеткам, например, такой:
Что мне пришло в голову, это выбрать случайный столбец клеток (вертикальную линию) между выходами, например:
Затем от каждого выхода провести горизонтальную линию до пересечения с этой линией:
И провести вертикальную линию между точками пересечения:
Вот и построен коридор. Это чисто в стиле Rogue, но можно пойти дальше и чуть усложнить, например провести не одну, а две или больше вертикальных линий:
В этом случае выход А упирается в ближайшую к нему линию, выход Б также в свою ближайшую, а вот эти линии можно уже соединить между собой в абсолютно любом месте горизонтальным отрезком, например:
Или:
После окончательного построения получаем вполне себе интересные коридоры:
Но к сожалению, этим методом нельзя получить такой коридор:
Попробуем сделать сетку из произвольного количества вертикальных и горизонтальных линий:
В этом случае каждый выход изначально может пересечься с одной из трёх вертикальных линий. Допустим, пересечения произошли так:
Теперь нужно найти другие точки пересечения, которые лежат на той же линии. Из точки L1 есть единственный путь вверх, а из R1 – вверх и вниз. Следующая итерация может получиться такой:
Из точки L2 доступны два пути в одном направлении, а из R2 – опять в разных. Но путь слева ведёт в тупик, так как оттуда уже никуда не выйдешь. Клетка, обозначенная как "x", блокирует доступ к другим клеткам. Таким образом, остаётся только идти вправо:
После этого у обоих веток остаётся одна доступная клетка, куда они и прибывают, замыкая маршрут:
Тему можно развить и дальше. Например, ветке R запрещено пересекаться с самой собой, но можно с L, и наоборот. Тогда можно получить, например, такую конфигурацию:
Этот метод выглядит довольно правдоподобным, но я пока не вполне понимаю, какие у него могут возникать граничные случаи, которые могут помешать. Так что в следующем выпуске буду писать сам алгоритм и тестировать его.
Читайте дальше: