Введение:
Здравствуй,уважаемый читатель(если вы не против, что бы вас так называли)! Итак,если ты попал на эту статью(не важно каким образом,главное попал :)), то ты хочешь изучить Jass Если это не так,то может быть твоё попадание было случайным... Итак,если читатель уверен что он готов изучить Jass готов стараться, то его старания не пройдут даром.
Что же такое Jass?
Для начала,как и на каждом уроке немного теории: Что же такое Jass? Jass – это несложный, интуитивно понятный компилятор не требующий особых теоретических понятий о нем. Следует заметить, что он во многом схож другими языками программирования(с паскалем или Visual Basic к примеру) Так же он по мере изучения будет развивать ваше алгоритмическое мышление, углубит познания технического английского языка и позволит с большей легкостью изучать другие языки программирования. Код Jass записывается в “конвертированном в текст” триггере, в действии триггера ”CustomScript” и в специально выделенной секции нестандартного кода (Custom Script Code) Пока теории с вас хватит :)
Необходимые программы Программы: Для работы с Jass`ом нам необходим хороший редактор синтаксиса, я вам предлагаю JassCraft, довольно простой и удобный редактор кода,так же желательно писать код не в самом World Editor`е, а так же в стороннем редакторе,так как компилятор Jass в World Editor`е очень “грубый”, и может выкинуть вас из редактора без сохранения (что иногда очень обидно)(Хотя с изобретением Jass New Gen Pack в этом необходимость почти отпала) World Editor(место где мы будем проверять наш код) Принадлежности: Мозг(Без комментариев) Прямые руки(Без комментариев)
Функции:
Все функции в варкрафт делятся на 2 типа: Native и BJ Теперь по подробнее:
Native: Это функции, которые находятся непосредственно в самом движке вара, и не могут быть изменены или добавлены стандартными методами. Они находятся в common.j
BJ:
Это функции, которые являются дополнительными и могут быть созданы самим джазером, они состоят из native функции и/или других BJ функций. Они находятся в blizzard.j
PS: В папке с варкрафтом они не лежат(common.j и blizzard.j), они создаются при создании карты,и извлечь их можно через MPQ редактор Кому лень с этим возиться вот ссылка на архив
native функции не вызывают утечек если ими пользоваться правильно, а вот четверть функций BJ вызывают утечку даже при правильном с ними обращении.
Устройство функции с точки Jass:
Практически все действия в варкарафте идёт за счёт вызова функций Существуют специальный оператор вызова call Далее идёт название функции и в () перечисление аргументов (что берёт функция) Строение самой функции состоит из специальных слов,например:
function Test takes nothing returns nothing call TriggerSleepAction(1) endfunction
function - это слово обозначающее начало функции Test - это название функции,может быть любым(но не содержать русских слов) takes - это слово стоит перед списком параметров что берёт функция, в данном случае nothing = ничего returns - это слово стоит перед списком параметров того что функция возвращает, в нашем случае nothing = ничего call - это слово - оператор вызова TriggerSleepAction - native функция, тот же wait(ждать) в редакторе триггеров (1) - секунды, в () находиться аргумент функции, есть функции без аргументов(к примеру GetTriggerUnit() - Переключающийся юнит, т.к функция ничего не берёт,в аргументы ничего не пишеться)) endfunction - это слово обозначает конец функции
Для того что бы узнать что берёт или возвращает та или иная функция, выберите её в JassCraft всё станет ясно :)
Вот между function ... и endfunction и идёт вызов функций (действий)
Если вам нужно поставить комментарий к какому - нибудь действию - достаточно после вызова(можно в любом месте) поставить //, и Вар всё что после этих строк игнорирует(можно писать и русскими символами после комментариев)
Шаг 1: Локальные переменные Начнём с того что в редакторе World Editor существует 2 типа переменные: глобальные и локальные с первыми вы знакомы(они создаются в Редакторе Переменных), а со вторыми нет Локальные переменные работают ТОЛЬКО в пределах одной функции и соответственно не могут использоваться в других функциях и объявляются они всегда в НАЧАЛЕ кода(в гуи) и в НАЧАЛЕ функции в Jass Что бы объявить(по другому создать) локальную переменную есть соответствующее действие local unit u - это действие создаст локальную переменную типа юнит(unit),типов есть несколько(к примеру: integer(целоисчесленная), real(реальная),unit(боевая единица(юнит)),string(строка),effect(спецэффект) и другие(посмотреть их можно в common.j)) с именем u(оно может быть любым(но без русских символов)) :

Так же можно объявить переменную и сразу установить ей значение
local unit u = GetSpellAbilityUnit() ,как вы заметили добавилось GetSpellAbilityUnit() - это переведённый из триггеров "применяющий юнит",таким образом у нас при нестандартном спелле за юнита u будет обозначаться кастер:

Локальные переменные используются для хранения данных (как и друге переменные) Так же можно устанавливать значение локальной переменной относительно глобальной
Обратите внимание на приставку udg_ ,она обозначает что переменная глобальная:

Так же в локальную переменную можно заносить юнита, НО только после создания:

Но лучше будет использовать с целью оптимизации немного другое:
Вместо:

Это:

Как только вы нормально выучите локальные переменные и функции можно будет создавать юнитов через следующее:

Так же один ВАЖНЕЙШИЙ аспект:после использования локальные переменные нужно обнулять, что бы не создавалось утечек(обнуляются они в конце функции)
Но не все типы переменных нуждаются в обнулении(не нуждаются integer,real,string)
обнуление делается таким образом:

т.е мы присваиваем переменной u нулевое значение
Что бы создать массив переменных достаточно после типа переменной(unit,к примеру) добавить array,и тогда можно уже будет заполнять/обращаться к ячейкам массива всего ячеек 8192([0].....[8191]) Только не забываем их обнулять
Иногда бывает недостаточно обнулить переменную,перед этим нужно уничтожить объект Особенно это касается точек,т.к это самая распространённая утечка: точки уничтожаются таким образом call RemoveLocation() (в () - нужная точка) После этого можно обнулять переменную с нашей точкой , но никак не на оборот.
PS:Иногда бывают случаи когда локальные переменные использовать не стоит, например:GetTriggerUnit() работает быстрее чем то же самое но в переменной
Итак,вот мы и закончили освоение локальных переменных
Я выкладываю простую карту пример,в ней 1 простой триггер: при касте создаётся эффект восклицательного знака над головой кастера, не забывайте про оптимизацию(она там уже сделана,можете сделать на обычных триггерах(это что то вроде домашнего задания ;))
Пример
PS:(Желательно к прочтению,если вам нужно уметь оптимизировать, желательно хорошо знать вышеописанное,а то не сможете понять...):
Немного про BJ:
Одна из многих проблем этих функций в том, что в них создаются локальные переменные типа “handle” и не обнуляются в конце, и вызывают лишнее загрязнение памяти (иначе - "утечки"), и именно поэтому большинство джаззеров (включая меня) настроены против BJ. Я всегда пользуюсь native функциями (в 80% случаев), а юзаю BJ, только в том случае, если они не вызывают утечек, и содержат много других используемых функций (потому что иначе пришлось бы один и тот же массив функций писать в большинстве кодов, и это приводило бы к “очень большому коду” и “трудно читаемости”).
Также все функции требуют время на вызов, чем больше это время тем сильнее будет подтормаживать игра во время их вызова, но правда это время измеряется долями микросекунды, так что в не динамических триггерах это имеет малое значение, ну а вот в динамических...:
Это означает что плохо вызывать функции, которая вызывает другую нужную нам функцию. Например:
function DestroyEffectBJ takes effect whichEffect returns nothing call DestroyEffect(whichEffect) endfunction
По сути это функция делает то же что и в ней содержащаяся, так какой смысл юзать функцию DestroyEffectBJ? Если можно напрямую воспользоваться DestroyEffect. И это весьма слабый пример, некоторые функции вызывают функции, нужные нам только через 2-4 функции
Ладно,я вас и так сильно загрузил для начала,так что учите,думайте,творите.
PS: Если для вас последняя глава была трудной,и вы не поняли, не отчаивайтесь - вы сможете к ней вернуться в любое время,и попробовать снова.
В следующей главе я опишу ветвления Если/То/Иначе(If/Then/Else), и немного опишу возможности записи функций
By Just.Spirit(Spirit of Dragon,Dragon93) Так же благодарю:Jon,Warden
|