-
AncientPenguin | Дата: Воскресенье, 19-08-2012, 17:31:29 | Сообщение # 1 |
загрузка наград ...
Группа: Избранные
Сообщений: 449
Репутация: 526
Статус: Не на сайте
|
Уроки JASS Основы синтаксиса, урок № 3. “Функции”
Введение
Перейдем к чему то более интересному, чем голый синтаксис. Начнем с того что, пожалуй, пригодится в любой карте, а именно с системы движения.
Для начала подумаем, какие данные нам необходимо сохранить для того чтобы заставить дамми юнита двигатся? Ну для начала надо сохранить самого дамми, так же нам понадобится его скорость, направление в котором его двигать и условия его остановки.
Для того чтобы сохранить дамми и скорость потребуется две переменные unit и real соответственно. Направление можно сохранить двумя способами: 1)Сохранить угол и двигать полярными координатами 2)Сохранить вектор и по нему двигать Хоть векторы и быстрее воспользуемся пока полярками, это попроще да и не придется много геометрии вспоминать. Для того чтобы сохранить угол нам понадобится переменная типа real. Теперь подумаем когда нам нужно остановить нашего дамми, тут несколько вариантов, можно по истечении времени или при пролете определенной дистанции, можно при столкновении с точкой или еще как. Воспользуемся пока вариантом с пройденной дистанцией.
Разумеется, необходимо сделать эту систему mui, как говорила моя учительница по алгебре «математики народ ленивый» и программисты тоже, поэтому чтобы не создавать на каждый спел по набору глобальных переменных, делаем сразу mui. Что же для этого нужно? А вот что:
Ассоциативные массивы
Рассмотрим сразу на примере, нам необходимо для каждого дамми хранить юнита, скорость, угол и пройденное расстояние. Создаем вместо обычных переменных массивы (глобальные):
unit dummy[8000] real angle[8000] real velocity[8000] real distance[8000] integer count = 0
Последняя переменная нужна для хранения количество занятых ячеек в массивах, изначально 0.
Теперь открываем нестандартный код (ткнуть мышью в название карты в редакторе триггеров), будем создавать функцию для запуска дамми:
Code function CreateProjectile takes unit dummy, real vel, real angle, real dist returns nothing /* Так как нумерация в массиве начинается с 0, кол-во элементов в массиве (в нашем случае переменная udg_count) будет равно "последний элемент + 1" т.е. первый свободный элемент в массиве*/ set udg_dummy[udg_count] = dummy set udg_velocity[udg_count] = vel set udg_angle[udg_count] = angle set udg_distance[udg_count] = dist set count = count + 1 // увеличиваем размер массива endfunction
У всех объектов варе есть функция для удаления, ну и пока прет вдохновение тоже напишем функцию для удаления наших дамми.
Code function DestroyProjectile takes integer index returns nothing set udg_count = udg_count - 1 // Уменьшаем размер массива /* Ставим последний элемент массива на место того который удаляем */ set udg_dummy[index] = udg_dummy[udg_count] set udg_velocity[index] = udg_velocity[udg_count] set udg_angle[index] = udg_angle[udg_count] set udg_distance[index] = udg_distance[udg_count] endfunction
Функция DestroyProjectile принимает индекс удаляемого элемента и ставит на его место последний.
Движение
Вот мы и подошли к самой сочной части урока, будем учить даммиков летать, но дамми как известно птица гордая и пока не пнешь не полетит, так начнем же создание триггера для раздачи ускорения даммикам.
Создаем триггер, создаем периодическое событие – каждые 0,03 секунд. Теперь нажимаем правка -> конвертировать в текст И начинаем кодить действие триггера:
Code local integer i = 0 local real x local real y // Пробегаемся циклом по всем дамми loop exitwhen i >= udg_count /* Формула полярных координат */ set x = GetUnitX(udg_dummy[i]) + udg_velocity[i] * CosBJ(udg_angle[i]) set y = GetUnitY(udg_dummy[i]) + udg_velocity[i] * SinBJ(udg_angle[i]) call SetUnitPosition(udg_dummy[i],x,y) // двигаем юнита set udg_distance[i] = udg_distance[i] - udg_velocity[i] // вычитаем пройденное расстояние if udg_distance[i] <= 0 then // если дамми пролетел нужное растояние то удаляем его call DestroyProjectile(i) set i = i - 1 endif i = i + 1 endloop
Осталось только создать дамми и он полетит. Создаем триггер с событием: юнит начинает применять способность, условие: способность = … ну вы поняли. Теперь конвертируем его в текст и пишем действие:
Code local real vel = 25 // скорость local unit caster = GetTriggerUnit() // юнит применивший способность local location casterloc = GetUnitLoc(caster) local location targetloc = GetSpellTargetLoc() // точка в которую запустили абилку local real angle = AngleBetweenPoints(casterloc,targetloc) // находим угол между точками local real dist = DistanceBetweenPoints(casterloc,targetloc) // и расстояние между ними local unit dummy = CreateUnitAtLoc(GetOwningPlayer(caster),'h000',casterloc,angle) // создаем юнита call CreateProjectile(dummy,vel,angle,dist) // запускаем его // обнуляем/удаляем все что нужно set caster = null call RemoveLocation(casterloc) call RemoveLocation(targetloc) set casterloc = null set targetloc = null set dummy = null
прим. ‘h000’ это рав код юнита. В JNGP его можно узнать нажав ctrl + D в редакторе объектов, в обычном WE пожалуй только создав действие или условие в котором задействован нужный тип юнита и переведя триггер в текст (например условие: тип юнита применившего способность = нужный тип юнита).
Домашнее задание.
Сделать чтобы дамми двигался не по прямой, а летел в юнита. Для этого нужно сохранять вместо угла юнита-цель и высчитывать угол между ними при движении. Подсказка: Функции которые пригодятся, но которых нет в данном уроке: GetLocationX(location), GetLocationY(location) – возвращает X и Y точки; GetSpellTargetUnit() – возвращает юнита в которого запустили способность.
|
| | |
-
влад10011 | Дата: Понедельник, 20-08-2012, 00:33:29 | Сообщение # 2 |
загрузка наград ...
Группа: V.I.P.
Сообщений: 1265
Репутация: 1039
Статус: Не на сайте
| | |