Я рассчитываю создать систему, которая распознает определенные типы зданий и комнат, которые вы можете создать в игре, например, как Terraria обнаруживает «резиденции». В этой игре дом можно построить в мире на основе плиток, построив зону блоков, удовлетворяющую ряду условий:
- Зона полностью изолирована от "снаружи" размещенными игроком блоками.
- Зона может соответствовать прямоугольнику 5х7.
- в закрытом помещении есть по крайней мере один стол, один источник света и стул.
- Из зоны есть дверь.
- Terraria имеет как передний, так и фоновый слой плитки. Весь фон зоны должен быть заполнен размещенными игроком блоками.
Как я могу эффективно определить, когда игрок построил область подходящего размера, и как я могу эффективно проверить, что эта область содержит всю необходимую мебель / компоненты?
Пример внутренней зоны, которая удовлетворяет всем жилищным требованиям:
spatial-partitioning
Бернардо Беккер
источник
источник
Ответы:
Я не знаком с Terraria, но это легко сделать с помощью алгоритма заливки .
Вместо пикселя вы проверяете плитки, и для каждой проверенной плитки вы оцениваете, может ли алгоритм продолжить проверку других плиток, сохраняя в массиве или списке, какие объекты были найдены во время процесса.
Алгоритм начинается с тайла, где находится персонаж. Вы можете начать каждую 1 секунду, 2 ... это вопрос настройки, чтобы найти лучший интервал.
Это также хорошая идея, чтобы не запускать алгоритм слишком долго, что можно сделать, ограничив количество плиток, которые алгоритм может запустить за цикл, в противном случае ваш алгоритм вызовет длинные лаги, когда персонаж находится в открытой области.
редактировать
Как указано в комментариях, вы можете использовать другие подходы к тому, когда запускать алгоритм, например, когда игрок меняет плитку, или плитки, имеющие
am I modified?
переменную, которая, еслиtrue
запускает алгоритм. Однако вы должны быть осторожны с этим подходом:Вы могли бы реализовать какой-то подход к обнаружению этих модификаций на тайлах, которых нет у вашего персонажа, но выполнение алгоритма на интервалах является самым простым подходом и менее подверженным ошибкам. Только убедитесь, что не выполняете заливку на каждом кадре.
Конец редактирования
источник
isRoom()
Как сказал @Ferreira da Selva, попробуйте алгоритм заливки. Тем не менее, вы можете использовать несколько различных критериев при запуске алгоритма, чтобы определить, является ли он вложенным.
Например, для каждой плитки вы проверяете, есть ли фоновая плитка, а если нет, то вы знаете, что она не вложена. Или вы можете заставить его выполнить отложенное выполнение, разделив его на несколько кадров, что снизит нагрузку на процессор и уменьшит отставание. Или вы можете создать ограничение размера комнаты, которого игрок должен будет придерживаться.
Использование комбинации из них позволит вам сделать это более эффективно и эффективно.
источник
Есть две трудные проблемы в информатике. Именование вещей, аннулирование кэша и ошибки «один на один».
Это проблема аннулирования кэша.
Если у вас есть запись «is this inside», то всякий раз, когда блок помещается или удаляется, довольно легко обновить его и его область с помощью заливки.
Чтобы оптимизировать это, вы можете захотеть иметь набор уровней «внутренности».
«Ячейка» - это область, окруженная размещенными игроком блоками (до определенного размера).
«Комната» - это клетка с фоновыми плитками.
«Внутри» - комната с дверью, светом и стулом.
Когда вы размещаете размещенный игроком блок переднего плана, делайте обход по часовой стрелке / против часовой стрелки, чтобы увидеть, образовалась ли новая ячейка. Когда вы удалите размещенный игроком блок переднего плана, проверьте, не разбивает ли он какие-либо ячейки - если так, посмотрите, сформирована ли новая ячейка, объединяя их.
Когда новая ячейка сформирована или не сформирована, проверьте, является ли она комнатой или внутренней частью.
Клетки могут отслеживать, сколько фоновых плиток им нужно для помещения. Затем простой подсчет, когда ячейка сформирована, фоновая плитка добавлена или удалена из ячейки, может определить, является ли это комнатой.
Точно так же Клетки могут отслеживать, сколько стульев и источников света (и фактически объектов всех видов) находятся внутри них. Тогда внутренняя проверка тривиальна.
Подсчет входов также может быть сделано.
Таким образом, мы дополняем карту «ячейками». Когда плитки добавляются или удаляются, мы проверяем ячейку местоположения и увеличиваем / уменьшаем количество в ячейке.
Используйте ход по часовой стрелке / против часовой стрелки, чтобы определить внутреннюю и внешнюю часть ячейки при добавлении или удалении блока переднего плана. Поскольку размер ячеек ограничен, эта прогулка займет ограниченное количество шагов.
В качестве бонуса у вас теперь есть дешевый способ говорить о «роскошных» комнатах, или «комната благословлена святым фонтаном», или что-нибудь еще о комнате, так как комнаты имеют количество каждого типа объекта в них. (Или, поскольку комнаты ограничены по размеру, просто сделайте итерацию; это удалит кеш).
Каждое местоположение находится не более чем в одной ячейке, поэтому вы можете хранить идентификатор ячейки каждого местоположения на главной карте.
источник
При использовании алгоритма заливки также создайте переменную, которая будет увеличиваться с каждой проверенной плиткой, поэтому, если она больше 35 (7 * 5, максимальный размер комнаты), она просто прекращает проверку!
источник