Юзер
Регистрация: 02.10.2006
Сообщений: 121
Репутация: 34
|
Часть вторая
Функции в JASS
Теперь можно поговорить о еще одном «кирпиче» программирования – функциях.
Функции – это набор команд который выполняется после вызова функции. Чтобы создать (объявить) функцию нужно написать следующий код:
Код:
Function name takes – returns –
//Код функции…
endfunction
Здесь name – это имя функции, takes – список переменных, которые функция «берет», returns – список переменных, которые функция возвращает. Для того чтобы указать, что функция ничего не берет/ничего не возвращает используют nothing. Например:
Код:
Function name takes nothing returns nothing
//Код функции…
endfunction
Если функция что-то возвращает, то в конце пишут return то, что функция возвращает, например:
Код:
Function name takes nothing returns integer
//Код функции…
Return 9 //Функция возвращает число 9
endfunction
Чтобы вызвать определенную функцию используют оператор call:
Код:
call RemoveUnit(myunit)
//Вызов функции удаления юнита
Подробнее о том, что функция берет и возвращает
Расскажу подробнее о структуре «возвращения» и «дачи» переменных функциям. Кода мы вызываем определенную функцию, нужно передать ей какие-то конкретные значения. А именно нам нужно удалить боевую единицу. Но для удаления мы должны вызвать функцию удаления юнита и передать только что вызванной функции переменную типа юнит. Ведь, как я и говорил, переменная ссылается на объект и без переменной юнит не удалится! Также чтобы вызвать функцию удаления предмета нужно передать этой функции (функции удаления предмета), которую мы вызываем, переменную типа предмет. Но как же передать переменной значения.
Код:
call RemoveUnit(myunit)
//Вызов функции удаления юнита
В этом коде мы вызвали функцию удаления юнита (RemoveUnit). Но для чего после вызова функции идет (myunit). Очевидно, это локальная переменная типа юнит. И для того чтобы передать функции значения нужно сразу после её имя поставить (список аргументов, которые она берет). Если аргументов несколь, то они перечисляются через запятую. В нашем случае это (myunit). Функции можно передать несколько переменных или значений. И так постепенно я веду к главному – зачем функции «брать» и «отдавать»? Дело в том, что функции можно передать только то, что она «берет». Если функция ничего не берет (nothing), то при вызове функции после ее имя надо поставить пустые скобки – (). А теперь подробнее о самом устройстве. Как уже говорилось функции можно передать только те аргументы (переменные или просто значения), которые она берет. Это значит, что уже знакомой нам функции RemoveUnit можно передать только 1 аргумент (переменную или значение) типа юнит. И не как иначе! Теперь о возвращении. Когда функция вызывает другую функцию, она может получить определенное значение. Например,
Код:
Function name takes nothing returns integer
Local integer i = 72-2*2 //Так тоже можно делать в JASS
Return i //Функция возвращает число 136
endfunction
А кому же -товернется эта переменная? Она вернется той функции, которая её вызвала. Это значит, что если нашу функцию вызвала какая другая функция, то этой вызывающей функции вернется это значение. И с этим значением теперь можно будет работать в вызывающей функции. Функция может вернуть только 1 значение (об исключениях позже). И пусть вас не смущаяют имена переменных:
Код:
Function name takes integer I, string S returns nothing
//…Код функции…
endfunction
Что это за имена I, S? На самом деле это имена аргументов и их типы. Это ни значит что все передаваемые аргументы должны быть такого же имя! Имена нужны только для работы с ними (прибавление, присваивание значения и т.д.). В области return располагается тип возвращаемого аргумента.
Правила обращения с функциями
Самые основные правила обращения с функциями:
Функция должна быть объявлена (создана) прежде, чем её «вызовут»
При вызове функции аргументов, передаваемых функции должно быть столько же, сколько она и берет.
Передаваемые аргументы должны быть таких типов, каких берет вызываемая функция.
Циклы в JASS
Скорее вы работали до этого с циклами в простом редакторе триггеров (в нашем первом примере была работа с циклом) и знаете, что циклы выполняются определенное количество раз – от опр. значения до опр. значения. В JASS циклы тоже есть, но они устроены немного по-другому.
Код:
loop
exitwhen int1 > int2
//Действия цикла
Int1 = int1 + 1
endloop
Здесь loop - это начало цикла endloop – конец цикла. exitwhen это условие после, которого выполнение цикла завершается. Можно делать любые условия.
Код:
loop
exitwhen bool = true
//Действия цикла
Int1 = int1 + 1
endloop
Return в JASS
Return в JASS используется не только для того чтобы вернуть какое-то значение, но и для того чтобы преждевременно выйти из триггера, не выполняя оставшихся действий. Это аналогично действию Skip Remaining Actions .
Утечки памяти в WARCRAFT 3
Всегда удаляйте локальные переменные. Если их не удалить, то эти переменные остаются в памяти компьютера. Вплоть до закрытия вара. В 1 примере мы говорили об ошибках создания боевой единицы. В этом действии просто куча утечек. В одном только действии полярной проекции 3 утечки. Это значит, что если триггер выполняется каждую секунду, то каждую секунду в памяти остается по 3 точки, которые должны быть удалены. Утечки оставляют неудаленные переменные
Функции правильные и неправильные
Оказывается, существуют правильные и неправильные функции. В архиве вара среди множества файлов можно найти 2 файла – common.j и blizzard.j . Все файлы с расширением j представляют собой набор jass кода. Дак вот, в blizzard.j существует множество функций с утечками памяти. К сожалению именно bj (сокращение от blizzard.j)
функции используются в обычных триггерных действиях. Помните, мы в первом примере говорили об ошибках 1 действия – CreateUnits. Вот именно подобными утечками обладает и эта функция. Но есть еще и common.j . В нем прописаны все функции и типы движка вара.
Идентификаторы
В редакторе триггеров вы манипулировали с юнитами посредством их имен. В JASS такое не пройдет. JASS работает не с именами, а с идентификаторами (ID). У каждой боевой единицы, заклинания, улучшения, декорации и др. есть свой уникальный идентификатор. Чтобы увидеть идентификаторы всех юнитов зайдите в редактор объектов и нажмите
Ctrl + D. Идентификатор представляет собой 4-ух значное строковое значение.
Устройство триггера в JASS
Создадим триггер следующего содержания:
Код:
События:
Время - Elapsed game time is 5.00 seconds
Условия:
Да равно Да
Действия:
Do nothing
Назовите его jasscode
Конвертируем его в код (Правка ->Конвертировать в текст)
Посмотрим на код…
Код:
function Trig_jasscode_Conditions takes nothing returns boolean
if ( not ( true == true ) ) then
return false
endif
return true
endfunction
function Trig_jasscode_Actions takes nothing returns nothing
call DoNothing( )
endfunction
//===========================================================================
function InitTrig_jasscode takes nothing returns nothing
set gg_trg_jasscode = CreateTrigger( )
call TriggerRegisterTimerEventSingle( gg_trg_jasscode, 5 )
call TriggerAddCondition( gg_trg_jasscode, Condition( function Trig_jasscode_Conditions ) )
call TriggerAddAction( gg_trg_jasscode, function Trig_jasscode_Actions )
endfunction
В этом коде функция Trig_jasscode_Conditions является функцией условий триггера. Если условие выполнено, то функция возвращает true и выполняются действия. Функция Trig_jasscode_Actions является функцией действий триггера. Это значит, что в этой функции будет выполнен весь код, если событие и условия верны. Если вы заметили, то имена обоих функций выглядят примерно так: Trig_НазваниеТриггера_что(действия или условия). На самом деле, эти имена можно поменять на любые, только тогда придется менять аргументы у функций в функции InitTrig_jasscode. А сама InitTrig_jasscode представляет собой функцию создания и инициализации триггера, set gg_trg_jasscode = CreateTrigger( ) создает новый триггер (напомню, что триггеры это тоже виды переменных), TriggerAddCondition( gg_trg_jasscode, Condition( function Trig_jasscode_Conditions ) ) добавляет в только что созданный триггер условия. Ну а TriggerRegisterTimerEventSingle создает триггеру событие, в котором поясняется выполнение после некоторого игрового времени (в этом случае 5 сек).
Замете, что к переменным типа триггер нужно обращаться с префиксов gg_trg_ .
[
__________________
Вот так вот...
Последний раз редактировалось ZeroCoolDark; 25.02.2009 в 13:19.
|