WarCraft 3: 8. События с малым периодом

Осваиваем jass (0-1)

8. События с малым периодом

Читатель, предлагаю рассмотреть еще один пример. Напрямую он не связан с jass, но зато расширит твои познания в триггерных заклинаниях.
Иногда в триггерах возникает задача делать действия в течении очень малого периода времени. Проблема в том, что в вар3 действия типа wait работают крайне коряво. Минимальный период для этого действия 0.1 доля секунды. Иногда этого бывает недостаточно. К тому же действие wait ужасно не стыкуется с командами цикла.
Если ты сделаешь цикл такого типа:
Цикл от 1 до 100
   (какое-нибудь действие)
   wait game time (0.1)
конец цикла
По идее, цикл должен завершиться через 100*0.1=10 секунд, а на самом деле пройдет больше времени. Можешь проверить сам. Поэтому циклы + wait-ы оказываются непригодными для организации действий на малых периодах. А ведь эти действия ой как полезны.
Ну, раз wait-ы нам помочь не могут, остается надеяться на другой метод - использование события Time periodic, которое, к счастью, позволяет генерировать запуск триггера с периодом до 0.01 секунды. К сожалению, это событие не связано с каким-то конкретным объектом. Поэтому, если нам нужно организовать какое-нибудь триггерное заклинание, работающее для множества объектов, придется переходить к массивам (примерно как с триггерной защитой).
Итак, рассмотрим такую задачу: заклинание паладина Благодать срабатывает мгновенно. К юниту-цели не летит никакой снаряд и в настройках редактора объектов невозможно сделать так, чтобы заклинание работало как снаряд. Но мы попробуем сделать это.
Итак, при запуске заклинания-пустышки, должен создаваться юнит-снаряд, который начинает движение к цели. Снаряд будет двигаться не сам по себе - мы это будем делать при помощи триггеров. Причем скорость снаряда у нас будет такой, какую мы захотим сделать, не ограничиваясь пределами в игровых константах.
Идея состоит в том, чтобы при каждом использовании заклинания, мы будем заносить в массивы u и u2 юнит-снаряд и юнит-цель, а массивы u_level - уровень заклинания. Допустим, у нас в данный момент уже имеется n юнитов-снарядов, летящих к своей цели, тогда все данные про новый снаряд мы будем заносить под номером n+1. Т.е. u[n+1] , u2[n+1], u_level[n+1]. Далее, при запуске у каждого снаряда, переменную num увеличиваем на 1 (а когда снаряд долетит - будем уменьшать). Т.е. переменной num будет храниться общее число юнитов-снарядов в любой момент времени.
Далее, у нас будет триггер с событием
Every 0.05 seconds of game time
Мы не случайно взяли период 0.05. Именно такой период нужен, чтобы организовать плавное движение юнита. Ведь триггер выполнится 20 раз в секунду - как раз такова частота обновления информации человеческого глаза. Меньший период уже не требуется.
Действие этого триггера: делаем цикл от 1 до num по всем юнитам-снарядам. Для каждого юнита-снаряда определяем направление движения (угол между юнитом снарядом и целью), определяем расстояние до цели. Если расстояние до цели больше определенного числа, то производим перемещение юнита-снаряда в сторону юнита цели (при помощи полярных координат).
Если же расстояние до цели стало меньше какого-то значения, то нужно во-первых, уничтожить юнит-снаряд,во вторых, произвести нужные действия с целью (добавить жизнь - своим, отнять жизнь у умертвий).
Можно было сделать так: дать юниту снаряду заклинание Благодать (настоящее) и когда он долетит, заставить применить его на цели, а затем уже удалить снаряд. Но поскольку действия с целью вполне можно совершать при помощи триггеров, я и сделал их триггерно (добавить 200*уровень спела жизней своим или отнять 100*уровень спела жизней врагам).
Высылаю пример и предлагаю посмотреть, как он устроен.
Примечание: действия по передвижению юнита-снаряда сделаны в виде функции на jass. Вообще говоря, эти действия можно было делать и при помощи обычных триггеров, но при этом возник бы очень неприятный эффект - утечка памяти. Что это такое, чем вызвано и как с этим бороться - напишу в следующий раз.
Примечание2: я не останавливаюсь подробно на примерах и предлагаю исследовать их самостоятельно. Предполагается, что Читатель уже знает и умеет использовать массивы, циклы и т.п. Во всяком случае, рассмотреть их применение можно в статьях по триггерам. Тем не менее, остановимся подробнее на так называемых полярных координатах. Они вызывают вопрос у многих картостроителей.
Подробности о принципах работы тех или иных типов данных можно узнать в статье Передача и хранение данных в варкрафте. -прим. ScorpioT1000

Просмотров: 14 341

Это сообщение удалено
Monflame #2 - 5 лет назад 1
Самое интересное то, что если использовать способность "Магический Щит" из примера статьи 7-й, а затем кастануть на юнит с этим щитом заклинание "Благодать" из примера этой [8-й] статьи, то получаем очень интересный результат: вместо того чтоб наш юнит исцелился, он теряет ровно столько НР = максимальное кол-во НР юнита-цели "минус" кол-во НР, которое должно восстанавливается для данного юнита при использовании заклинания "Благодать".
Хочу заметить, что без магического щита здоровье этого же юнита восстанавливается при использовании "Благодать" нормально (т.е. ничего нигде не отнимается).
В моем переработанном примере:
магический щит дает 1000 ед.
благодать - 500 ед.
В чем прикол?