Займёмся вопросом отрисовки плиток. Вроде бы это не стоит делать сейчас, так как визуальное представление должно быть отделено от кода. Но дело здесь в том, что есть один нюанс, который действительно повлияет на код.
Вся подборка по рогаликам:
1. Проблема кодирования
Рассмотрим пример карты, составленной из плиток:
Чтобы её хранить, в каждую клетку карты надо записать какое-то число. Например, 1 это вода, 2 это трава, 3 это дорога, 4 это дерево, и т.д.
Итого, если мы хотим тратить на одну клетку один байт, мы можем иметь до 256 разных плиток в пределах одной карты, и в принципе этого должно быть достаточно.
Но плитки, подобные указанным выше, выглядят прилично только до определённого размера. Если их сделать побольше, то границы между ними будут выглядеть слишком искусственно.
Поэтому на границах между двумя средами или материалами применяются плитки, в которых отрисованы переходы:
Здесь можно увидеть скруглённые углы, специально отрисованные границы между водой и сушей, между песком и травой, бордюры.
Но это значит, что мы уже не можем иметь одну плитку песка. Нам нужны:
- плитка песка
- плитка песка, которая граничит с водой в разных вариантах
- плитка песка, которая граничит с травой в разных вариантах
Для песка, травы, воды и их сочетаний нужно уже примерно столько плиток (здесь они упакованы неоптимально, но вы можете понять идею):
Следовательно, количество плиток резко увеличивается (хотя по-прежнему это всего лишь три материала: песок, вода, трава). И каждой плитке нужно назначить своё число. И предыдущая оценка в 256 плиток становится совсем пессимистичной.
2. Проблема видимой доступности
Если персонаж движется по плиткам травы и песка, то он вполне себе может стоять на плитке, которая совмещает траву и песок.
Но совсем другое дело, если это плитка земли и внешней стены какого-либо сооружения. Часть стены можeт быть отрисована двумя способами:
В первом варианте стена занимает часть пустой клетки (песочного цвета), и поэтому становится не вполне понятно – может персонаж заходить в такую клетку или нет? Если может, то не наложится ли его спрайт на стену? А если не может, то не будет ли выглядеть неестественно практически пустая клетка, в которую нельзя зайти?
Следовательно, предпочтительнее рисовать второй вариант, так как клетка, доступная для персонажа, остаётся полностью свободной.
Далее, если представить все возможные комбинации, которые могут присутствовать в клетках со стенами, то получим такое множество:
На самом деле возможны (или нужны) не абсолютно все комбинации, но я насчитал минимум 16 и дальше просто не стал. И это всего два материала.
3. Автоматизация
Я решил автоматизировать рисование плиток следующим образом:
Если есть есть материал 1 и материал 2, и X сочетаний между ними, то каждая клетка карты хранит только 1 или 2, как будто никаких сочетаний нет.
А вот когда карта рисуется на экране, тогда для каждой клетки делается проверка – что хранится в её соседях? И в зависимости от этого в клетке дополнительно дорисовываются фрагменты стены.
Например: значение текущей клетки это "здание". Справа от неё находится пустая клетка "пол". Значит, в правой части текущей клетки дорисовываем вертикальный фрагмент стены, который отделит здание от пола. Аналогично проверяем левую сторону, а также верх, низ и углы.
Для проверки данного решения я сделал скрипт, который можно смотреть онлайн:
https://js.do/nandakoryaaa/smartmap
Первоначально есть только серый квадрат, это пол. На нём с помощью мышки можно рисовать стены, а также стирать их (при нажатии на плитку пола появляется стена, а при нажатии на плитку стены – пол).
Для каждой клетки карты выполняется 8 проверок (по числу соседей). Понятно, что данный механизм довольно громоздок.
Я попытаюсь решить эту задачу более эффективным способом.