Повільна ефективність на реалізацію A * у грі в оборону вежі


9

Я роблю гру Tower Defense у Flash без попередньо визначеного шляху.

Хоча моя сітка розміром 40x40 (невелика?), A * бореться при перерахунку кожного разу. Тож я зробив власну модифікацію, щоб полегшити перерахунок, і кількість доторканих комірок знизилася до 900 (при зміні біля кореня). Він все ще замерзає на дуже короткий, але помітний час, коли розміщують нову вежу.

Це проблема з реалізацією, або 40x40 просто занадто багато?

Редагувати:

Структура мого коду:

  • Усі дані зберігаються у 2d масиві комірок.
  • Кожна комірка містить батьківський у напрямку шляху (1-8 за годинниковою стрілкою) та побітово кодований масив своїх дітей на шляху (кожен біт представляє дитину).
  • Пошук здійснюється A * з оцінкою евклідової відстані.

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

1
Коли я впроваджував A * востаннє, я пам'ятаю, що він проходить через сітку 64x64 не менше ніж 1 мс. Так що так, схоже, це проблема з вашою реалізацією. Я пропоную опублікувати свій код або суть його, щоб ми могли допомогти вам далі.
Марк Мюллер

Дивіться редагування, яке я додав
Дани

1
Якщо 40x40 занадто повільний, швидше за все, ви робите щось дуже неправильно. Або опублікуйте свій код або профайлюйте його. Крім того, масштабуйте його і подивіться, що станеться - якщо сітка 80х80 займає більше чотирьох разів довше, у вас там щось надзвичайно зламане.
ZorbaTHut

Чи може заголовок бути трохи більш інформативним?
tenpn

Відповіді:


4

Я не можу коментувати, але перший профіль у Flex, все інше - здогадка.


Як я можу профілювати флеш-проект у flex?
Дані

Так і ні. Я не думаю, що ви завантажуєте флеш-проект безпосередньо. Я думаю, що ви можете мати змогу профайлювати SWF без джерела, і все-таки отримаєте інформацію про рівень функції, хоча. Я б здійснив пошук в Google для "профілювання флеш-проекту у флексі" тощо. Я це і зробив: flexblog.edchipman.ca/…, що виглядає перспективно.
Джонатан Фішофф

Дякую, дійсно допоміг мені знайти проблематичну частину (не було в алгоритмі, дивіться коментар до питання)
Dani

13

Я припускаю, що TD - це "захист вежі"

Я думаю, що A * дещо переживає за це.

На початку гри затоплення заповніть ігрову зону від точок виходу, щоб створити карту руху:

 |---------|
 |5|4|3|3|3|
 |5|4|3|2|2|
->5|4|3|2|1->
 |5|4|3|2|2|
 |5|4|3|3|3|
 |---------|

а рух завжди до квадрата з меншим значенням.

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

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

Більш простим підходом було б повторне проведення заливки.


6
Повторне заповнення заливки коштує дорожче, ніж робити A * для невеликої кількості одиниць - приблизно, довжина плати - принаймні в алгоритмічному вираженні (а оскільки це Flash, неалгоритмічні константи, як компонування пам’яті, ймовірно, можуть ' t використовуватися дуже ефективно). Однак це дуже хороша модель для багатьох комунікаційних одиниць і називається спільною дифузією - scalablegamedesign.cs.colorado.edu/wiki/Collaborative_Diffusion .

@Joe Wreschnig: приємне посилання. Я раніше застосовував цю техніку, але ніколи не знав, як її називати. Дякую.
tenpn

@ Джо, доки на карті є хоча б кілька бар'єрів, я не думаю, що це було б неефективніше, ніж викликати A *. Тобто, я вважаю, що лише для широко відкритої, майже бар'єрної вільної карти з кількома одиницями може бути гірше.
edA-qa mort-ora-y

@edA: За визначенням, заливна заливка повинна врешті торкатися кожної доступної точки на карті; A * забезпечує перевірені верхні межі кількості точок, які він повинен торкатися, що є, максимум, у кожній доступній точці на карті і зазвичай набагато менше. Заливка є більш простим алгоритмом для оптимізації таких речей, як компонування пам'яті, але, як я вже сказав, у Flash це, мабуть, не має значення.

@Joe, це те, що я стверджую, що навіть із лише кількома вежами A *, ймовірно, торкнеться майже всіх просторів. Але для N монстрів потрібно лише перевищити total_squares / N, щоб бути менш ефективними, ніж заливка.
edA-qa mort-ora-y

2

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


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

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

0

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


0

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

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


На це відповіли майже рік тому, і його натрапили лише через редагувальну роботу Грейс. (Це не мало нічого спільного з занадто великою кількістю персонажів.)

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