Ефективно простежуючи безліч ворогів навколо перешкод


20

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

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

Мені було цікаво, чи може бути занадто важким для продуктивності обчислити шлях до гравця за допомогою A *, а потім використати алгоритм стікання, щоб запобігти збиткові. Спочатку моя гра повинна була бути хвильовою стрілялкою, але я вирішив замість цього зробити її на рівні в жилах «Гарячої лінії Майамі», тому, швидше за все, у мене буде менше ворогів, з випадковою ордою, і я просто зроблю вони сильніші.

Це життєздатне рішення? Я використовую Java з Slick2D в якості мого ігрового двигуна. Або є краще рішення / алгоритм, який вирішує обидві ці проблеми?


7
Як я описав у редагуванні, "чи це занадто важко", це питання, яке потрібно задати своєму профілеру, оскільки це буде залежати від вашої реалізації, цільового обладнання, бюджету продуктивності та контексту вашої гри - все те, що ви та ваш профілер знаєте тісно, ​​але Інтернет-незнайомці цього не роблять. Якщо ви хочете ефективно опрацювати зграї зграй, ми можемо запропонувати стратегії, які допоможуть у цьому, але тільки ваше власне профілювання може відповісти на те, що достатньо ефективно для ваших потреб. Якщо ви профіліруєте та визначите конкретну проблему ефективності, ми також можемо допомогти вам знайти, як вирішити цю проблему.
DMGregory

1
Те, як ви їх реалізуєте, впливає на продуктивність. Наприклад, лише запуск A * на лідерах і покладання на flocking для підписників.
Пікалек

Якщо ваша гра в основному базується на боротьбі з цими ворогами, алгоритм, який ви використовуєте, матиме величезний вплив на те, як виглядає гра. Тож вам слід спробувати різні підходи, наприклад, чи відчуваєте ви, як вороги прекрасно знають рівень та позицію гравця у всі часи, і вони відслідковують його, як керує всезнаючим AI? - інші підходи можуть полягати в тому, щоб вороги бігали в загальному напрямку, де гравець шумів і тільки по прямій зорі бігав до нього, або кричав і повідомляв інших ворогів, де гравець ...
Falco

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

Відповіді:


49

Це звучить як випадок використання для потокових полів.

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

Якщо всі ваші плитки / кромки мають однакову вартість переходу, то для цього можна скористатися простим пошуком. В іншому випадку алгоритм Дейкстри (як A * без мети / евристики) працює.

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

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

Це важить все краще і краще, чим більше ворогів у вашій зграї. Для одного ворога це дорожче, ніж A *, оскільки він здійснює пошук по всій карті (хоча ви можете заздалегідь виявити, як тільки ви дістанетесь до всіх агентів проходження маршруту). Але якщо ви додаєте більше ворогів, вони отримують все більше і більше вартості проходження маршруту шляхом обчислення сегментів спільного шляху один раз, а не знову і знову. Ви також отримуєте перевагу від того, що BFS / Dijkdtra простіші за A * і зазвичай дешевші для оцінки на оглянуту клітинку.

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

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


Ця техніка звучить справді акуратно. Я перевірю це.
Дарін Бодо

15
Можна використовувати гібридний алгоритм, який будує поле часткового потоку, не шукаючи більше карти, ніж повторювані дзвінки на A *, і ніколи не шукаючи одну і ту ж саму позицію двічі. Основна ідея полягає в тому, щоб вибрати довільного ворога і почати пошук A * від гравця до цього ворога, позначаючи клітини, коли ви стикаєтеся з ними так само, як у звичайному генерації потокового поля. Як тільки пошук знайде ворога, виберіть іншого ворога (якого ви ще не знайшли) в якості цілі, пересортуйте відкритий набір відповідно до нового евристичного характеру та продовжуйте пошук. Зупиніться, коли знайдете всіх ворогів.
Ільмарі Каронен

1
А як уникнути зіткнень? Це (дещо) згадується в ОП (уникаючи обрізання, коли вони досягають гравця). Мені здається, вам доведеться повторювати повний djikstras кожен раз, коли щось рухається (або додайте в якусь додаткову логіку)
Марс,

2
@Mars OP розмовляє про злітання, тому я б припустив, що всі особи можуть рухатися з однаковою швидкістю; Єдине місце, де будуть зіткнення, - це вузькі місця, які вимагають, щоб частина зграї зупинилась і чекала. Однак насправді не потрібно змінювати маршрутизацію - проста черга, ймовірно, працюватиме досить добре у більшості випадків, а деяка зміна контуру (деякий псевдовипадковий вибір альтернативних шляхів із схожими витратами) буде працювати для створення більш природної зовнішності потоки, які також уникають цілої зграї, намагаючись пройти через один конкретний проміжок однієї плитки :)
Луаан

3
@Luaan У грі на основі плитки ви здивуєтеся, як часто трапляються зіткнення. Особисто я вважаю варіант "черги" менш оптимальним. Крім того, якщо підрозділи не можуть пройти один через одного, вам доведеться перерахувати, коли одиниці почнуть отримувати своє остаточне положення та купу інших крайових справ. Флокинг важкий;)
Марс

8

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

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

Тут найкраще працювати з машинами з кінцевим станом і читати книгу "Програмування гри AI за прикладом" Мата Бакленда. У книзі запропоновані перевірені методи для вирішення вашої проблеми та детально розроблена математика. Вихідний код книги доступний в Інтернеті; книга є на C ++, але деякі переклади (включаючи Java) доступні.


2
З нечасто оновлюваним підходом A * може бути корисним поетапне оновлення оновлень, зберігаючи бюджет на те, скільки ворогів дозволено повторно проходити на одному кадрі. Таким чином, ви можете зберегти свою пікову вартість проходження маршрутів за обмежений обсяг кадрів і більш надійно обробляти багато шляхів ШІ, амортизуючи їх загальну вартість протягом декількох кадрів. AI, що використовує несвіжий шлях для кадру або двох, коли бюджет для кадру був перевищений, або відпадає від мертвого рахунку, якщо він близький, зазвичай не буде зривним.
DMGregory

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

4

Це не тільки можливо, я вважаю, що це було зроблено в комерційній грі в 90-х - BattleZone (1998).

У цій грі були 3D-одиниці з вільним рухом без плитки та конструкцією основи на плитці.

Ось як, здавалося, працює:

По-перше, A * або щось подібне (ймовірно, це зміна A * із суворими обмеженнями щодо того, який довгий шлях він може знайти, тому він ніколи не забирає занадто багато ресурсів, але не завжди знаходить шлях аж до місця призначення) може бути використаний для пошуку шляху, щоб ховертанк дістатися до місця призначення, не застрягаючи в перешкодах на основі плитки.

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


1
То який хороший спосіб впоратися слідуючи стежці, але не точно? Якщо я дозволяю хитрому повороту, мені потрібно мати змогу запобігти зіткненню ворогів із кутом перешкоди. Чи слід тримати зграйну поведінку як для ворогів, так і для перешкод і додавати A * для вирішення цих ситуацій?
Дарин Бодо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.