Найти в Дзене
ZDG

Пирог #13. Решение проблемы плиток

В предыдущей части поднимался вопрос рисования плиток с автоматическим определением границ. Хотя первый вариант кода работал, там был фундаментальный недостаток. Стены дорисовывались поверх плитки с нужных сторон, и вполне могли накладываться друг на друга. Так как рисовались просто цветные прямоугольники, от наложения они никак не страдали. И это существенно упрощало алгоритм. Но теперь возьмём нормальную графику. Я выяснил, что нужно вот столько вариантов для плитки одного материала: Обратите внимание на выделенные цветом части – они могут присутствовать или отсутствовать в разных комбинациях внутри содержащей их плитки. А это значит, что общее количество комбинаций плиток получится совсем ни в какие ворота. Кроме того, теперь нельзя просто брать части плиток и накладывать их друг поверх друга, как это было с прямоугольниками. Это сразу будет заметно. Потратив некоторое время на размышления, в результате я пришёл к следующей схеме: Ровно столько плиток нужно для отображения всех комб

В предыдущей части поднимался вопрос рисования плиток с автоматическим определением границ.

Хотя первый вариант кода работал, там был фундаментальный недостаток. Стены дорисовывались поверх плитки с нужных сторон, и вполне могли накладываться друг на друга. Так как рисовались просто цветные прямоугольники, от наложения они никак не страдали. И это существенно упрощало алгоритм.

Но теперь возьмём нормальную графику. Я выяснил, что нужно вот столько вариантов для плитки одного материала:

Обратите внимание на выделенные цветом части – они могут присутствовать или отсутствовать в разных комбинациях внутри содержащей их плитки. А это значит, что общее количество комбинаций плиток получится совсем ни в какие ворота.

Кроме того, теперь нельзя просто брать части плиток и накладывать их друг поверх друга, как это было с прямоугольниками. Это сразу будет заметно.

Потратив некоторое время на размышления, в результате я пришёл к следующей схеме:

-2

Ровно столько плиток нужно для отображения всех комбинаций. Положение каждой плитки в хранилище определяется её двоичным порядковым номером, а порядковый номер определяется наличием у неё соседей сверху, справа, снизу и слева (именно в таком порядке, от младшего бита к старшему).

Например, у плитки 0000 нет ни одного соседа, она полностью замкнута на себя. У плитки 0001 есть один сосед сверху, и это подтверждается визуально. То есть внешний вид плитки привязан к её порядковому номеру, а порядковый номер сообщает нам в двоичном виде, с какой из 4-х сторон у плитки есть соседи.

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

Исходя из порядкового номера плитки, можно определить, каких именно диагональных соседей надо проверять, и составить из них ещё один двоичный номер. На этот раз порядок такой (от младшего бита к старшему): справа вверху, справа внизу, слева внизу, слева вверху.

Получив эти номера, я просто записал их в виде массива. Индекс массива это порядковый номер плитки, а значение – порядок проверки её диагональных соседей.

Нет, всё ещё проще. Угол плитки, который может требовать дорисовки, всегда открытый, а любой открытый угол определяется по наличию двух единиц подряд в порядковом номере:

в последнем варианте единицы находятся в начале и конце
в последнем варианте единицы находятся в начале и конце

Поэтому я проверяю номер по соответствующей маске из двух единиц и в случае совпадения уже происходит проверка соседа и дорисовка.

Реализацию новой версии можно смотреть онлайн здесь:

https://js.do/nandakoryaaa/smartmap2

-4

Сразу скажу, что визуально ничего не изменилось, там по-прежнему всё рисуется прямоугольниками внахлёст, но только лишь потому что это прототип. Изменился сам алгоритм расчёта, и при переходе на нормальную графику всё будет функционировать правильно.

Рогалик | ZDG | Дзен

Можно отметить следующие оптимизации:

В удачном варианте нужно проверить только 4-х соседей, получить в результате порядковый номер плитки, и если он финальный, то отрисовать плитку и всё.

В неудачном варианте придётся дополнительно проверять до 4-х соседей по диагонали и дорисовывать уголки, но это делается только если установлены соответствующие биты в порядковом номере, то есть именно когда необходимо для каждого отдельного случая.

Читайте также: