Як я можу виявити «кімнати» у 2D-бічній грі прокрутки?


24

Я хочу створити систему, яка розпізнає певні типи будівель і приміщень, які ви можете створити в грі, як, наприклад, Terraria виявляє "резиденції". У цій грі будинок може бути побудований у світі на основі плитки, побудувавши зону з блоків, що задовольняють набору умов:

  1. Зону повністю ізолюють «ззовні» розміщеними гравцями блоками.
  2. Зона може вмістити прямокутник 5х7.
  3. у закритому приміщенні є хоча б один стіл, одне джерело світла та стілець.
  4. З зони виходять двері.
  5. У Terraria є передній і передній шар плитки. Весь фон зони повинен бути заповнений розміщеними гравцями блоками.

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

Приклад внутрішньої зони, яка відповідає всім вимогам житла:

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


5
Не могли б ви детальніше розробити? Що ви маєте на увазі під "типами будівель" і що таке "резиденція" в Terraria? Майте на увазі, що не всі грали в цю гру, також зосередьтесь на одному питанні, якщо ви хочете, щоб люди допомогли, і переконайтеся, що на це запитання визначена відповідь (а не думки)
TomTsagk

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

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

Відповіді:


37

Я не знайомий з Terraria, але це легко зробити за допомогою алгоритму заливки .

Замість пікселя ви перевіряєте плитки, і для кожної перевіреної плитки ви оцінюєте, чи алгоритм може продовжувати перевірку інших плиток, зберігаючи в масиві чи списку, які об’єкти знайдені під час процесу.

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

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

Редагувати

Як зазначено в коментарях, ви можете використовувати інші підходи щодо того, коли запустити алгоритм, наприклад, коли гравець змінює плитку, або плитки, що мають am I modified?змінну, яка, якщо true, запускає алгоритм. Однак ви повинні бути обережними з таким підходом:

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

Ви могли б реалізувати якийсь підхід для виявлення цих модифікацій на плитках, у яких ваш персонаж відсутній, але виконання алгоритму з інтервалами - це найпростіший підхід і менш схильний до помилок. Просто переконайтеся, що не виконувати заливку на кожному кадрі.

Кінець редагування


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

20
Чому б ви запускали це на фіксованому інтервалі? Звичайно, ви можете просто запустити його, коли розміщується блок (або знищується, якщо це можливо, і обидва ці випадки, ймовірно, можуть бути виконані в амортизованому постійному часі на блок) або при завантаженні певної частини карти, а потім зберігати результат від там.
NotThatGuy

3
@immibis: Я впевнений, що Terraria не вимагає від вас змінити слово. Я також не очікував, що гра змінить свою кімнату, визнаючи поведінку залежно від того, хто поставив плитку. Що робити, якщо я, наприклад, будую кімнату, що прилягає до скелі?
Flater

3
Terraria вимагає поставити фонні стіни і не утворюватиме будинок із природним брудом / скелею. Він дійсно перевіряє лише розміщені гравцем блоки.
loa_in_

3
Щоб зберегти процесор, я б тільки запустив алгоритм зміни блоку і зберігав би стан для кожного блоку. З цим все простоisRoom()
Герр Дерб

3

Як сказав @Ferreira da Selva, спробуйте алгоритм заповнення заливів. Хоча при використанні алгоритму ви можете використовувати кілька різних критеріїв, щоб визначити, чи він укладений.

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

Використання комбінації цих засобів дозволить вам зробити це більш ефективно та ефективно.


3

У інформатиці є 2 важких проблеми. Іменування речей, недійсність кешу та помилки окремо.

Це проблема недійсності кеша.

Якщо у вас є запис "це всередині", щоразу, коли блок або розміщений блок, оновити його та його регіон досить легко за допомогою заливки.

Для оптимізації цього, можливо, ви хочете мати набір ярусів "внутрішності".

"Осередок" - це область, оточена розміщеними гравцем блоками (до певного розміру).

"Кімната" - це клітина з фоновими плитками.

"Всередині" - це кімната з дверима, світлом і стільцем.

Коли ви розміщуєте розміщений на передньому плані блок для гравців, виконайте ходьбу за годинниковою стрілкою / проти годинникової стрілки, щоб побачити, чи утворена нова комірка. Коли ви виймете розміщений на гравці блок переднього плану, вивчіть, чи він порушує будь-які комірки - якщо так, подивіться, чи утворюється нова комірка шляхом об'єднання двох.

Коли нова клітина сформована або неформована, перевірте, чи це кімната чи внутрішня частина.

Клітини можуть відслідковувати, скільки фонових плиток потрібно для приміщення. Тоді за простим підрахунком, коли формується комірка, додається або вилучається фоновий плитка з комірки, можна визначити, чи це кімната.

Так само Клітини можуть відслідковувати, скільки стільців та джерел світла (а насправді предметів усіх видів) знаходиться в них. Тоді внутрішня перевірка є тривіальною.

Підрахунок входів також можна зробити.


Отже, ми збільшуємо карту за допомогою "комірок". Коли плитки додаються або видаляються, ми перевіряємо комірку місця розташування та збільшуємо / зменшуємо кількість в комірці.

Використовуйте ходьбу за годинниковою стрілкою / проти годинникової стрілки для визначення внутрішньої та зовнішньої сторони комірки, коли додається або виймається блок переднього плану. Оскільки розмір комірок обмежений, ця прогулянка буде робити обмежену кількість кроків.

Як бонус, тепер у вас є дешевий спосіб поговорити про "багатючі" кімнати, або "кімнату благословляють святим фонтаном", або що-небудь ще про кімнату, оскільки в номерах є кількість кожного типу об'єктів всередині них. (Або, оскільки кімнати обмежені за розміром, просто робіть ітерацію; це видаляє кеш).

Кожне місце розташування є щонайменше в одній клітинці, тому ви можете зберігати ідентифікатор комірки кожного місця на головній карті.


0

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


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