Динамічний алгоритм трасування для гри в оборону вежі


16

Я створюю Tower Defense і мені потрібен хороший алгоритм проходження шляху.

Я думав про Дайкстра, але мені потрібен той, який може бути динамічним; він повинен бути в змозі оновити себе, коли один край видалений або доданий без повного перерахунку.

Я кодую в C #, якщо це допомагає.

Відповіді:


8

Як правило, ви хочете використовувати A *, якщо немає чогось важливо іншого.


Якщо я не такий знайомий з A *, як би я вирішив динамічно мінливі середовища? Перерахувати за кожний кадр? При зіткненнях?
Джастін Л.

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

6
Якщо це мляво, мої рекомендації: не обчислюйте шлях для кожної мафії. Ймовірно, всі вони йдуть однаковим шляхом. Я лише згадую нове розміщення башти, і вежа знаходиться в поточному шляху . Вже тоді лише повторний виклик монстрів у точках на шляху до площі блоків, а не для мобів, які пройшли повз нього, і тому їх не хвилює. А потім, щоб зробити маршрутизацію коротшою, ви можете обмежити її, щоб знайти шлях до квадрата після заблокованого квадрата, оскільки шлях звідти ви вже знаєте.
seanmonstar

4
Насправді "моб" - це галузь (і MMO / MUD player) лінгво для "мобільного об'єкта".

3
Незважаючи на те, він давній, починаючи з MUD1, і досить стандартний, щоб з’явитися у багатьох публікаціях. en.wikipedia.org/wiki/Mob_%28computer_gaming%29

19

Мені потрібно було вирішити подібну проблему: пошук маршрутів на великій лабіринтній сітці з постійно мінливими "витратами" та бар'єрами.

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

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

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

Мій алгоритм був в основному чимось на кшталт (псевдо-код):

update_node method in Node class:
    $old <- $my_score
    find $neighbor node among all neighbors such that
        $neighbor.score + distance_to($neighbor) is minimal
    $my_score <- $neighbor.score + distance_to($neighbor)
    $next_node <- $neighbor
    if ($my_score != $old)
        for each $neighbor
            $neighbor.update_node()

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


1
Крім того, було б легко динамічно поширювати це по кадрах у міру зміни завантаження процесора.
tenpn

+1 для A * не є правильним алгоритмом для використання.
Ricket

5

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

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

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

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

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


4

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


1
Варто зазначити, що Tower Defense користується популярністю на мобільних телефонах, де набір маршрутів не швидкий. Особливо на дещо старих пристроях, таких як Sidekick або Android 1.6.
seanmonstar

1
Розробники використовують десятки десятиліть такі алгоритми, як A * і Dijkstra, на далеко менш потужному обладнанні (думаю, що Boy Boy). Будь-який новий телефон, достатній для екрана, достатнього для ігор, не повинен мати проблем, якщо, звичайно, реалізація є досить ефективною. Тут обговорюються деякі чудові
Майк

+1. Я дійшов такого ж висновку, коли розробляв власний клон DTD. Я намагався поступово оновлювати шляхи, але алгоритм став надто складним. Провівши день на ньому, я перейшов на повний перерахунок за кожну зміну. Це спрацювало, і за допомогою декількох налаштувань я зміг зробити це досить швидко.
finnw


2

Це може бути зайвим для вашого рішення, але подумайте про направлення назад, а не вперед.

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


1

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


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

так, спочатку автор не вказав, якого типу він хотів, тому я припустив, що це не динамічно.
Локтар

1

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

Зауважте, що деякі ігри TD мають заданий шлях і не дозволяють розміщувати вежі на ньому, тому вони вирішують простеження маршруту найпростішим способом: шляхом жорсткого кодування шляху і не дозволяють вам блокувати його :)


1

Просте рішення - обдурити.

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


1
Імовірно, він говорить про щось на кшталт Desktop TD, де користувач створює карту на льоту. І все-таки для "німих" ворогів це може бути гарним рішенням, щоб ви могли зробити ворогів з кращим AI трохи складніше.
кодерангер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.