Показать сообщение отдельно
Старый 07.12.2008, 12:41   #2
Юзер
 
Регистрация: 02.10.2006
Сообщений: 121
Репутация: 34 [+/-]
JASS – Наиболее полное руководство

Часть первая

Вместо предисловия
Чтобы сделать свою карту хорошей мало просто сделать красивый рельеф, продумать сценарий, расставить декорации, войска. Для хорошей карты нахватает триггеров. К сожалению, большинство стандартных триггерных действий сделаны неправильно. Неправильно с точки зрения JASS. Эта статья для тех, кто желает понять JASS. Возможно те, кто сейчас читает эту статью с целью изучить JASS, уже ни раз пытались читать другие статьи, но никак не могли понять их. Эта статья поможет понять JASS. Прежде всего, хочу сказать, что эта статья не является переделкой чужой статьи. Эта статья рекомендуется только для тех, кто уже хорошо знает триггеры. Так как статья получилась очень большой, я разделил её на 3 части. А после прочтения вы можете задать свой вопрос по статье или по JASS.
Что есть JASSи для чего он нужен
JASS - это интерпретируемый язык программирования движка WARCRAFT 3. А что же такое за слово? Интерпретируемый? Интерпретируемым называют тот язык программирования, который выполняется во время действия программы (в этом случае, во время игры). А точнее говоря, он интерпретируется перед игрой и затем выполняется. Само название JASS это сокращение от англ. Just Another Scripting System. В WARCRAFT 3 используется вторая версия этого языка (то есть JASS 2). Нужен JASS в основном для уменьшения нагрузки на движок варкрафта и на компьютер пользователя соответственно. Очень часто JASS используют для создания «триггерных» заклинаний (далее спеллов). Существует ошибочное мнение, что JASS нужен только дотам.
Небольшой пример неправильного использования триггеров
А теперь от теории к практике. Допустим, нам поставлена задача. Сделать так чтобы вокруг героя появилось 12 светлячков. Для этого мы скорее будем использовать полярную проекцию:
Код:
События:
Неважно, какие события – главное действия =)
Условия:
Тоже на свой вкус
Действия:
For each (Integer A) from 1 to 12, do (Actions)
   Цикл - Действия
Боевая единица  - Create 1 Светлячок for 
Игрок 1 (красный) at ((Position of (Triggering unit)) offset by 256.00 towards ((Real((Integer A))) x 30.00) degrees) facing Стандартная ориентация зданий degrees 
Для тех, кто не понял что это за триггер (хотя я сомневаюсь, что вы с таким знанием триггеров пошли бы учить JASS) поясню. Первое действие это цикл, котрый выполняется 12 раз. Действие, которое выполняется в этом цикле (12 раз) – это создание боевой единицы. В этом действии создается боевая единица на расстоянии 256 от точки нашего триггерного юнита (Position of (Triggering unit)) под углом Integer A * 30. Если кто не знает, Integer A является своеобразным идентификатором количества выполнений цикла. То есть если цикл выполнился 5 раз, то и Integer A будет равен 5 (это если выполнение начиналось именно с 1, а в нашем случае оно начинается с 1 до 12). Почему именно 30? А потому что 360/12=30. Итак, мы отвлеклись от сути, вокруг триггерного юнита создается 12 светляков на расстоянии 256. Все вроде хорошо, но представим, что нам нужно выполнять это действие каждую 1 секунду (а хорошо, если 1, а не меньше). После некоторого времени постоянного выполнения этих действий вы можете заметить, что компьютер начинает подтормаживать всё сильнее и сильнее (это заметно на слабых компьютерах). Виной тому неправильность триггерных действий с точки зрения JASS. Давайте детально разберемся, почему же это происходит. Ну во-первых если смотреть на действие Create Units (лучше не пробуйте этого делать) на JASS, то можно заметить кучу лишнего, затормаживающего игру. Например, это действие предназначено для создания нескольких юнитов. Наш цикл создает по только по одному юниту за выполнение. К тому же цикл сохраняет в отдельной переменной последнюю созданную единицу. По-сути это нам тоже не нужно. И ещё в этом действии есть некоторые недочеты, о которых вы узнаете позже. Ну а если смотреть на ((Position of (Triggering unit)) offset by 256.00 towards ((Real((Integer A))) x 30.00) degrees), то там 3 серьезных недоработки, о которых вы также узнаете позже. Итого выходит, сколько ошибок только в 1 действии?! Вот для того чтобы убрать эти недоработки используют JASS.

Введение в JASS

Комментарии в JASS
Можно сделать любую строку комментарием. Для этого достаточно поставить перед ней 2 косые черты. И любой код ставший комментарием не выполняется!
Примеры:
Код:
//Это комментарий
Код:
//local type name – этот код не выполняется
Можно так же ставить комментарии после строки кода. Тогда код перед комментарием выполняется!
Код:
local type name //Это тоже комментарий
Переменные в JASS
Итак, вы поняли, для чего нужен JASS (я на это надеюсь). Теперь пришло время поговорить об одном из «кирпичей» программирования. А именно – переменных. Из редактора варкрафт вы знаете, что существуют переменные и для чего они нужны. К этим переменным вы можете обратиться из любого триггера. На самом деле в варкрафт существует 2 вида переменных. Глобальные и локальные. Глобальные – это те, с которыми вы уже знакомы, те, которые вы используете в своих триггерах постоянно. К ним вы можете обратиться из любого триггера. В JASS к глобальным переменным нужно обращаться с префиксом udg_ .Но есть и локальные. Локальные переменные доступны только в JASS. И самое главное – к локальным переменным можно обратиться только из того триггера, в котором они созданы. Но как же создать локальные переменные? Для начала создайте пустой триггер и конвертируйте его в текст (Редактор триггеров ->Правка ->Конвертировать в текст). Очистите весь код в конвертируемом триггере. В дальнейшем все «эксперименты» вы будете проводить именно в этом триггере…
Создание локальной переменной
В создании локальной переменной нет ничего сложного:
Код:
local type name
Здесь type обозначает тип создаваемой переменной, а name ее имя. Например:
Код:
local integer myvariable
Также вы можете сделать локальной переменной массив, добавив
array после типа:
Код:
local integer array myvariable
Итого вы создали локальный массив типа integer. Массивы в JASS не имеют заданного ограничения.
Присваивание значения локальной переменной
Для присваивания значения локальной переменной используется оператор set:
Код:
set myvariable = 10
Если это массив, то нужно указать номер элемента:
Код:
set myvariable[0] = 10
Удаление локальной переменной
В конце триггера все локальные переменные должны быть удалены (обнулены). Для удаления локальных переменных типа integer нужно присвоить им значение 0.
Код:
set myvariable = 0
Ели это string переменная, то нужно присвоить ей значение «»
Код:
set myvariable = “”
Если это handle переменная (о типах речь пойдёт позже), то нужно присвоить ей значение null
Код:
set myvariable = null
И соответственно, если переменная является массивом, то нужно указать номер элемента
Код:
set myvariable[0] = 0
Правила обращения с локальными переменными
Для начала, как я и говорил, переменные должны быть объявлены (созданы). И должны быть уничтожены (обнулены) в конце триггера (обычно). Не стоит забывать и о достаточно частой ошибке:
Код:
//Где-то в коде создается боевая единица
set myunit = NULL
call RemoveUnit(myunit)
//Попытка удалить юнита 
В этом коде сначала удаляется (обнуляется) локальная переменная и затем производится попытка удалить юнита. А переменная которая ссылается на этого юнита уже удалена! И юнит не удаляется. Никогда так не делайте!!!
Типы в JASS
Всего в JASS существует 6 основных типов переменных:
boolean – Логическая переменная может иметь значения только ДА и НЕТ
code – В этой переменной содержится функция
real – В этой переменно содержатся числа с плавающей запятой (например, 2,67)
string – Строки
integer – Целые числа
handle – Указатель на игровой объект (например, область, боевая единица). Манипулируя с переменной, мы изменяем не переменную, а сам объект. Является родительским ко всем «сложным» типам. Например тип handle является родительским типу unit
Все остальные типы (unit, unit-type, item, effectи т.д. являются потомками handle)

Работаем
__________________
Вот так вот...
serializer вне форума