[Уроки JASS]Создание системы движения, шаг первый. - Wc3-Maps Форум













[ Главная · Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: Strateg, Melissa  
[Уроки JASS]Создание системы движения, шаг первый.
-
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
Статус: Не на сайте
GetLocation же создаёт новые точки и не удаляет blink

Добавлено (20/08/2012, 00:33:29)
---------------------------------------------
оу оно же реал возвращает а не точку Х_Х


Look at my horse!
 
  • Страница 1 из 1
  • 1
Поиск:
Рейтинг@Mail.ru
Яндекс.Метрика

Copyright © 2010-2017
Вакансии :: Контакты
Мобильная версия сайта
chat