Как я могу обнаружить «комнаты» в 2D игре с боковой прокруткой?


24

Я рассчитываю создать систему, которая распознает определенные типы зданий и комнат, которые вы можете создать в игре, например, как Terraria обнаруживает «резиденции». В этой игре дом можно построить в мире на основе плиток, построив зону блоков, удовлетворяющую ряду условий:

  1. Зона полностью изолирована от "снаружи" размещенными игроком блоками.
  2. Зона может соответствовать прямоугольнику 5х7.
  3. в закрытом помещении есть по крайней мере один стол, один источник света и стул.
  4. Из зоны есть дверь.
  5. Terraria имеет как передний, так и фоновый слой плитки. Весь фон зоны должен быть заполнен размещенными игроком блоками.

Как я могу эффективно определить, когда игрок построил область подходящего размера, и как я могу эффективно проверить, что эта область содержит всю необходимую мебель / компоненты?

Пример внутренней зоны, которая удовлетворяет всем жилищным требованиям:

введите описание изображения здесь


5
Не могли бы вы уточнить? Что вы подразумеваете под «типами строений» и что такое «резиденция» в Террарии? Имейте в виду, что не все играли в эту игру, также сосредоточьтесь на одном вопросе, если вы хотите, чтобы люди помогли, и убедитесь, что на этот вопрос есть определенный ответ (а не мнения)
TomTsagk

1
Под типами я подразумеваю разные используемые компоненты / плитки. Мой вопрос решен ниже. Я постараюсь больше проработать и конкретизировать будущие вопросы, спасибо за помощь.
Бернардо Беккер

1
Кроме того, убедитесь, что есть разница между комнатой и местом жительства . Ваш список маркеров предполагает, что вы видите их как одно и то же определение. Используя Terraria в качестве примера, враги не появляются в комнатах, даже если они не имеют права на проживание (например, пропустили стол или только 5x5 в измерении)
Flater

Ответы:


37

Я не знаком с Terraria, но это легко сделать с помощью алгоритма заливки .

Вместо пикселя вы проверяете плитки, и для каждой проверенной плитки вы оцениваете, может ли алгоритм продолжить проверку других плиток, сохраняя в массиве или списке, какие объекты были найдены во время процесса.

Алгоритм начинается с тайла, где находится персонаж. Вы можете начать каждую 1 секунду, 2 ... это вопрос настройки, чтобы найти лучший интервал.

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

редактировать

Как указано в комментариях, вы можете использовать другие подходы к тому, когда запускать алгоритм, например, когда игрок меняет плитку, или плитки, имеющие am I modified?переменную, которая, если trueзапускает алгоритм. Однако вы должны быть осторожны с этим подходом:

  • Что, если плитка, являющаяся частью комнаты, но не плитка, на которой находится ваш персонаж, будет изменена? Возможно, плитка была изменена другим игроком, или событие среды, или время жизни плитки закончилось. Ваш персонаж не будет знать о модификации и не будет выполнять алгоритм, чтобы обнаружить обновленную комнату, подверженную ошибкам.

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

Конец редактирования


9
Почему бы не заполнить флуд только среди фишек, размещенных игроками? Это может предотвратить или уменьшить бесконечное заполнение паводков на открытых участках (до тех пор, пока пещеры / особняки не заполнены "размещенными игроком блоками").
jimbo1qaz

20
Почему вы запускаете это с фиксированным интервалом? Конечно, вы можете просто запустить его, когда блок размещен (или уничтожен, если применимо, и оба этих случая, вероятно, могут быть выполнены в амортизированном постоянном времени на блок) или при загрузке определенной части карты, а затем сохранить результат из там.
NotThatGuy

3
@immibis: Я уверен, что Terraria не требует от вас смены пола. Я также не ожидал бы, что игра изменит свое распознавание комнаты, основываясь на том, кто разместил плитку. Что если я, например, построю комнату рядом со скалой?
Флэтер

3
Terraria требует, чтобы один установил фоновые стены и не сформировал бы дом с естественной фоновой грязью / скалой. Он действительно проверяет только блоки, размещенные игроком.
loa_in_

3
Чтобы сохранить процессор, я бы только запускал алгоритм при смене блока, а затем сохранял состояние для каждого блока. С этим все простоisRoom()
герр Дерб

3

Как сказал @Ferreira da Selva, попробуйте алгоритм заливки. Тем не менее, вы можете использовать несколько различных критериев при запуске алгоритма, чтобы определить, является ли он вложенным.

Например, для каждой плитки вы проверяете, есть ли фоновая плитка, а если нет, то вы знаете, что она не вложена. Или вы можете заставить его выполнить отложенное выполнение, разделив его на несколько кадров, что снизит нагрузку на процессор и уменьшит отставание. Или вы можете создать ограничение размера комнаты, которого игрок должен будет придерживаться.

Использование комбинации из них позволит вам сделать это более эффективно и эффективно.


3

Есть две трудные проблемы в информатике. Именование вещей, аннулирование кэша и ошибки «один на один».

Это проблема аннулирования кэша.

Если у вас есть запись «is this inside», то всякий раз, когда блок помещается или удаляется, довольно легко обновить его и его область с помощью заливки.

Чтобы оптимизировать это, вы можете захотеть иметь набор уровней «внутренности».

«Ячейка» - это область, окруженная размещенными игроком блоками (до определенного размера).

«Комната» - это клетка с фоновыми плитками.

«Внутри» - комната с дверью, светом и стулом.

Когда вы размещаете размещенный игроком блок переднего плана, делайте обход по часовой стрелке / против часовой стрелки, чтобы увидеть, образовалась ли новая ячейка. Когда вы удалите размещенный игроком блок переднего плана, проверьте, не разбивает ли он какие-либо ячейки - если так, посмотрите, сформирована ли новая ячейка, объединяя их.

Когда новая ячейка сформирована или не сформирована, проверьте, является ли она комнатой или внутренней частью.

Клетки могут отслеживать, сколько фоновых плиток им нужно для помещения. Затем простой подсчет, когда ячейка сформирована, фоновая плитка добавлена ​​или удалена из ячейки, может определить, является ли это комнатой.

Точно так же Клетки могут отслеживать, сколько стульев и источников света (и фактически объектов всех видов) находятся внутри них. Тогда внутренняя проверка тривиальна.

Подсчет входов также может быть сделано.


Таким образом, мы дополняем карту «ячейками». Когда плитки добавляются или удаляются, мы проверяем ячейку местоположения и увеличиваем / уменьшаем количество в ячейке.

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

В качестве бонуса у вас теперь есть дешевый способ говорить о «роскошных» комнатах, или «комната благословлена ​​святым фонтаном», или что-нибудь еще о комнате, так как комнаты имеют количество каждого типа объекта в них. (Или, поскольку комнаты ограничены по размеру, просто сделайте итерацию; это удалит кеш).

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


0

При использовании алгоритма заливки также создайте переменную, которая будет увеличиваться с каждой проверенной плиткой, поэтому, если она больше 35 (7 * 5, максимальный размер комнаты), она просто прекращает проверку!


7 * 5 - это прямоугольник минимального размера, который должен поместиться в комнате
Рик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.