Низкая производительность при реализации A * в игре Tower Defense


9

Я делаю игру Tower Defense во Flash без предопределенного пути.

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

Это проблема реализации или 40х40 слишком много?

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

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

  • Все данные сохраняются в 2d массиве ячеек.
  • Каждая ячейка содержит своего родителя в направлении пути (1-8 по часовой стрелке) и битовый кодированный массив ее дочерних элементов в пути (каждый бит представляет дочерний элемент).
  • Поиск осуществляется по A * с оценкой евклидова расстояния.

Вам нужно быть более конкретным здесь. Мы не знаем, как выглядит ваш код, как он структурирован и т. Д., И поэтому мы не можем сделать какие-либо выводы о том, что делает его медленным.
Шон Джеймс

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

Смотрите правку, которую я добавил
Дани

1
Если 40x40 слишком медленный, есть вероятность, что вы делаете что-то очень неправильно. Либо опубликуйте свой код, либо профилируйте его. Кроме того, увеличьте масштаб и посмотрите, что произойдет - если сетка 80x80 занимает больше четырех раз, у вас есть что-то чрезвычайно сломанное.
ZorbaTHut

Название может быть немного более информативным, пожалуйста?
Tenpn

Ответы:


4

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


Как мне профилировать флеш проект во флексе?
Дани

Да и нет. Я не думаю, что вы загружаете флеш-проект напрямую. Я думаю, что вы могли бы профилировать SWF без источника и все же получить информацию об уровне функции, хотя. Я бы сделал поиск в Google для «профилирования проекта Flash во Flex» или тому подобное. Я сделал и получил это: flexblog.edchipman.ca/…, который выглядит многообещающим.
Джонатан Фишофф

Спасибо, действительно помогли мне найти проблемную часть (не было в алгоритме, см. Комментарий к вопросу)
Дани

13

Я предполагаю, что TD это «Tower Defense»

Я думаю, что 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, неалгоритмические константы, такие как макет памяти, вероятно, могут ' использоваться очень эффективно). Тем не менее, это очень хорошая модель для многих взаимодействующих устройств и называется коллективной диффузией - scalablegamedesign.cs.colorado.edu/wiki/Collaborative_Diffusion .

@ Джо Wreschnig: вау хорошая ссылка. Я использовал эту технику раньше, но никогда не знал, как она называется. Спасибо.
Tenpn

@ Джо, пока на карте есть хотя бы несколько барьеров, я не думаю, что это будет более неэффективно, чем вызов A *. То есть, я полагаю, что только для широко открытой, почти безбарьерной карты с небольшим количеством юнитов это может быть хуже.
edA-qa mort-ora-y

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

@ Джо, это то, что я утверждаю, что даже при небольшом количестве башен A *, вероятно, коснется почти всех пространств. Но для N монстров нужно только превышать total_squares / N, чтобы быть менее эффективным, чем заливка.
edA-qa mort-ora-y

2

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


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

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

0

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


0

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

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


На это ответили почти год назад, и столкнулись только из-за редакторской работы Грейс. (Это не имело никакого отношения к слишком

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