ГлавнаяБлогКарты Warcraft 3Гайды для первой ДотыГайды для Доты 2 [ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: XOPYC  
JASS
Дата: Пятница, 07.01.2011, 13:06 | Сообщение # 1
Лейтенант
Проверенные
Сообщений: 65
Награды: 0
Репутация: 15
И снова здравствуйте!Я заранее извеняюсь если тема не отразила суть,но всёже.Я с другом делаю карту он по большей части рельеф,а я триггеры.И однажды он мне задал вопрос,на который я сразу же ответил JASS!Это его заинтересовало,но я понятия не имею как писать на джасе и самое главное как на него перейти.И если там есть свои особы обозначения ,то как их узнать?Вобщем,если вы мне сможете всё это пояснить я буду очень рад.
 
Дата: Пятница, 07.01.2011, 13:19 | Сообщение # 2
Генералиссимус
Ньюсмейкер
Сообщений: 2438
Награды: 8
Репутация: 85
т.к. Нельзя рекламировать соперников.
Нельзя воровать статьи и т.д.
А написание подобной статьи очень трудоёмкий процесс...
То я поищу нет ли статьи о Жасс коде у РазАрта
Или напишу свою, прошу понять, что это требует времени.

Для того, чтобы понять на сколько глубоко надо расмотреть этот вопрос, ответьте на пару вопросов:
1)Вы знаете хоть 1 язык программирования?
2) понимаете суть переменных и масивов?

 
Дата: Пятница, 07.01.2011, 13:31 | Сообщение # 3
Генералиссимус
Модераторы
Сообщений: 12998
Награды: 22
Репутация: 141
Эм... На всякий попытаюсь внести некоторую ясность в новый детектив Дона =)
1. Если вы знаете хотя бы 1 язык программирования, то изучить любой другой не сложно, т.к. синтаксис написания практически одинаковый.
2. Ну тут, как говорится, ноу комментс =)

Лишь для упрощения поисков желательно написать для чего конкретно вам нужен jass. Вообще написание на нём не очень сложное занятие, есть куча программ для этого. В то же время jass более функционален нежели триггеры. Но вот в визуальном плане выглядит он страшновато =)))


это Ксопик!
 
Дата: Пятница, 07.01.2011, 13:59 | Сообщение # 4
Генералиссимус
Ньюсмейкер
Сообщений: 2438
Награды: 8
Репутация: 85
Признаюсь, что писать сам я не стал и взял статью с другого сайта.
Автор статьи Sergey

Взял я самое важное на мой взгляд и то, что именно по могло мне, в создании моих карт.
Так же должен заметить, что это самая простая и понятная статья о jass какую я только видел.

И ещё небольшая, заме тка, перед тем, как вы приступите к чтению статьи от Сергея.
Не советую полностью превращать триггер в текст, досаточно использовать триггер "нестандартный код" (Custom Code)
И в него вписывать какой либо код.

Если вам интересно, как на Жасс записать тот или иной триггер - создайте тригер, задайте ему действие и через меню преобразуйте в текст.

Прямо таки переходить строго на джас не стоит. Тем более если вы ещё и гуи то плохо знаете, но локальные переменные очень важный момент и без них нельзя.
Ну а теперь... приятного чтения.

Локальные переменные


Локальные переменные – это воистину первый шаг в освоении jass. И это очень важный шаг. Умея работать с локальными переменными, ты сможешь заметно упростить себе решение многих триггерных задач.
Читатель, прежде чем начнем изучение, я советую тебе скачать файл, который приложен к данной статье. Скачай, затем открой в редакторе и запусти на исполнение. Суть примера в том, что если стрельнуть заклинанием файербол, над головой жертвы появляется спецэффект «восклицательный знак», который через несколько секунд исчезнет. Действие сделано на триггерах с применение локальных переменных.
С одной стороны можно задать вопрос – а зачем тут вообще нужны триггеры? Этого же эффекта можно достичь в редакторе объектов. Да, можно. Но главное не это. Вместо спецэффекта мы можем навесить и любое другое действие. Например, при ударе файербола, на юните будет появляться череда сменяющих друг друга спецэффектов. Такого в редакторе объектов уже не сделаешь.
А можно ли сделать этот эффект при помощи обычных триггеров? Конечно. Для одного юнита, это легко сделать. Например, запустил юнит файербол, мы:
Помещаем цель заклинания в переменную u типа юнит.
Ждем время, пока файербол долетит (которое равно расстояние до цели делить на скорость полета).
Создаем спецэффект на юните u, который записываем в переменную se типа спецэффект.
Через несколько секунд уничтожаем спецэффект se.
Все просто, но... Насколько такой триггер будет универсален? Предположим, несколько юнитов имеют заклинание файербол, и поочередно друг за другом применяют его, так что два триггерных действия (создание спецэффекта) выполняются в короткий промежуток времени. Тогда у нас произойдет триггерный конфликт. Ведь в одни и те же переменные u и se будут писаться параметры для разных файерболов. В итоге у нас могут появиться 2 спецэффекта над одним и тем же юнитом и один из этих спецэффектов останется навсегда. Все это произойдет из-за того, что без переменных вообще обойтись нельзя, а для разных запусков нельзя использовать одни и те же переменные.
Есть способ исправить эту проблему: для каждого запуска файербола помещать значения не в переменные, а в ячейку массива. Для каждого запуска сохранять значения в свои ячейки, каким-то образом отслеживать, что пришел момент создать спецэффект для такого-то юнита из массива или удалить такой-то спецэффект из другого массива. Это не очень удобный и достаточно громоздкий способ. В итоге, простая по сути задача – становится очень тяжелой.
В то же время, в том примере sample locs, эта задача решена очень легко. Чтобы узнать как – рассмотрим, что же такое локальные переменные.
Читатель, ты уже знаком с переменными в редакторе. Ты умеешь создавать их при помощи редактора переменных. Так вот, все переменные, которые создаются в редакторе переменных, будем отныне называть глобальными переменными. Глобальные переменные можно использовать во всех триггерах игры.
Оказывается, что кроме глобальных переменных, существует еще один вид – локальные переменные. Локальные переменные – это переменные, которые работают только внутри определенного триггера. Локальные переменные создаются при запуске триггера и уничтожаются после того, как выполнение триггера закончено. Если триггер запущен на исполнение несколько раз, то при каждом запуске создается свой набор локальных переменных, никак не связанный с другими наборами.
В каждом триггере можно определить набор локальных переменных. Для этого нужно применить команду из jass. В редакторе есть возможность вставить в триггер команду из jass – так называемый Custom Script (в дальнейшем cs). Читатель, давай посмотрим, как это сделано в примере – см триггер «Cast fireball method 1».
В самом начале триггера идут команды
Код
cs:   local unit u
cs:   local effect e

Это объявление того, что при запуске этого триггера будут созданы 2 локальные переменные: u типа юнит и e типа спецэффект. Создавать локальные переменные можно всех тех же типов, что и глобальные и в любом количестве. Можно даже создавать массивы локальных переменных.
Далее идет обычная триггерная команда:
Код
Set unit = (Target unit of ability being cast)

В глобальную переменную unit помещается юнит - цель нашего заклинания.
Дальше идет еще одна jass-команда:
Код
cs:   set u = udg_unit

Что это значит? Дело в том, что в jass есть такое правило: перед глобальными переменными ставится приставка udg. udg_unit - это наша глобальная переменная unit. Что касается локальных переменных, то их имена пишутся непосредственно без всяких приставок. Что же означает наша команда, записанная выше? u – локальная переменная, udg_unit – глобальная, set – это оператор присвоения.
Ответ таков: мы в локальную переменную u поместили то, что было записано в глобальную переменную unit (а в ней у нас был юнит-цель заклинания).
Оставим пока вопрос зачем, просто посмотрим, что будет дальше. А дальше идет команда
Код
Wait ((Distance between (Position of (Casting unit)) and (Position of (Target unit of ability being cast))) / 1000.00) game-time seconds

- ждать время, равное отношению расстояния между кастонувшим юнитом и юнитом-целью к 1000 (1000 – это скорость снаряда файербола). Т.е. ждать время полета. Далее идет команда на jass:
Код
cs: set udg_unit = u

Догадаетесь, что она означает? В глобальную переменную unit помещаем то, что записано в локальной переменной.
Далее проделана аналогичная схема с созданием спецэффекта. Созданный спецэффект помещается в глобальную переменную se, затем в локальную переменную e помещается что, что записано в se. Затем ждем период 3 игровых секунды и делаем обратное: записываем в se то, что записано в e. И уничтожаем спецэффект.
Итого, весь триггер напоминает тот, который мы создали бы, чтобы реализовать появление спецэффекта для одного юнита. Разница лишь в нескольких jass вставках. Но без этих вставок триггер НЕ УНИВЕРСАЛЕН, а со вставками – УНИВЕРСАЛЕН. Почему?
Давай вспомним про локальные переменные, которые мы создали. При каждом запуске триггера «Cast fireball method 1» будет создаваться набор из двух локальных переменных u и e. Причем для каждого запуска свой набор – не зависящий от других наборов. Запустим триггер 1000 раз – будет создано 1000 локальных переменных u типа юнит и e типа спецэффект.
В локальную переменную u мы поместили юнит-цель заклинания (сначала в глобальную unit, затем в локальную u). Через несколько секунд мы не можем гарантировать, что значение глобальной переменной unit не изменится. Ведь другой юнит может запустить файербол по другой цели – тогда значение переменной unit будет перезаписано. НО ЗНАЧЕНИЕ ЛОКАЛЬНОЙ ПЕРЕМЕННОЙ ДЛЯ ДАННОГО ЗАПУСКА НЕ ИЗМЕНИТСЯ. Ведь при следующем запуске триггера будет создан новый набор локальных переменных, а старые наборы не будут затронуты.
Итак, при помощи локальных переменных мы можем сохранить юнит-цель для каждого запуска заклинания файербол. А через некоторое время, равное времени полета файербола, мы должны создать на юните спецэффект. Мы делаем нужную паузу и затем помещаем в глобальную переменную unit ссылку на юнит из переменной u. И создаем спецэффект над юнитом из переменной unit.
Таким приемом мы можем гарантировать, что сколько бы файерболов не было выпущено, спецэффект будет создаваться над юнитом-целью и только над ним. Никаких сбоев не будет. Точно такой же прием с удалением спецэффекта через 3 секунды после создания. Все эти три секунды ссылка на спецэффект будет храниться в локальной переменной e. А затем мы перебросим ее значение в глобальную переменную se и удалим спецэффект.
Итак, как показывает пример, локальные переменные очень удобны для реализации УНИВЕРСАЛЬНЫХ отсроченных действий. Это свойство локальных переменных делает их незаменимыми при создании триггерных заклинаний. Причем добавить локальные переменные в триггер, как ты убедился, совсем не сложно.
Этот пример я специально сделал наиболее простым. jass команды, которые в нем используются – создать локальную переменную и присвоить значение переменной. Локальные переменные только для хранения данных. Для конкретных действий мы используем глобальные переменные unit и se. Также мы используем их как посредники – для переброски в них значений из локальных переменных и наоборот. Вообще говоря, в нашем примере можно обойтись и без глобальных переменных – одними локальными. Но проблема в том, что использование локальных переменных не предусмотрено в редакторе. Чтобы использовать эти переменные необходимо записывать команды на jass.
Теперь, Читатель, используй команду Правка->Конвертировать в текст, чтобы перевести весь триггер в «Cast fireball method 1» в jass. Не вдаваясь пока в устройство триггеров, обрати внимание на фрагмент, в который превратились наши триггерные действия. Каждая строчка триггерных команд превратилась в какую-то строчку jass-кода. Что касается строчек из custom script, они не изменились, т.к. они уже были написаны на jass. Теперь посмотри на триггер «Cast fireball method 2». Похоже? Да, это почти то же самое, только во втором примере я уже не использую глобальные переменные.
Обрати внимание на то, что в jass-код можно вставлять комментарии
любой текст
Если нужно отключить какую-то строчку кода, не обязательно ее стирать. Можно превратить ее в комментарий. Второй пример на самом деле не работает, т.к. я превратил в комментарий строчку, которая отвечает за события триггера.
Еще обрати внимание, что названия спецэффектов в jass-коде записываются немного иначе - вместо одного \, записывается два:
"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl"
Любой триггер можно конвертировать в jass-код, но обратную процедуру выполнить невозможно. Хотя есть такое действие – отменить последнюю команду редактора: ctrl-z. Если нужно, можно посмотреть, как выглядит код триггера, а затем вернуть триггер обратно.
Наконец, посмотри на третий триггер «Cast fireball method 3». Он делает то же самое, что и первые два. Но этот третий пример является как бы смесью первых двух. Как и во втором примере, здесь не используются глобальные переменные, но все команды, в которых используются локальные – пришлось переписать в виде cs.
Итак, первый шаг в мире jass уже сделан.
3. Применение локальных переменных
Закрепим то, что узнали. Чтобы создать локальную переменную, нужно вставить команду:
Код
local <тип переменной> <имя переменной>

Типы переменных – это строки. В некоторых случаях они совпадают с названием переменных в Редакторе переменных. Например unit, integer, real, string. Но иногда не совпадают как в случае с effect, который означает спецэффект.
Если вы не знаете, как называется такой-то тип переменных в jass, как это узнать? Можно использовать такой способ: создаете глобальную переменную нужного типа. Затем используете команду редактора Файл->Экспорт кода – сохраняете код сценария в файл. Затем смотрите содержание этого файла при помощи блокнота. Находите пункт
* Global Variables
- он будет в самом верху.
Там перечислены все глобальные переменные в сценарии и рядом записан их тип.
Можно еще использовать такой способ: сделать какую-то ошибку в jass-коде, после чего игра отключить и подключить триггер с ошибкой (disable/enable). Игра выдаст ошибку и в окне с ошибкой будет виден код сценария. Так что там же можно найти раздел Globals.
Примечания: попробуйте посмотреть таким способом как в jass называются типы «тип юнита», «тип предмета», «способность» или «бафф». И обнаружите, что они преобразуются к... типу integer. Тут нет никакой ошибки. Эти типы переменных существуют только в редакторе триггеров. В jass они представляют собой тип integer. Типы юнитов, способности и т.п. кодируются числами. Хотя, у них имеется и другой способ кодирования – специальными константами ‘hfoo’- означает тип юнита footman. Подобные названия объектов можно узнать переводя триггеры в jass или в редакторе объектов (если поставите галочку «Вид->Показывать названия переменных»
Команды по созданию локальных переменных всегда должны располагаться в самом верху триггерных действий (за исключением только комментариев), иначе будет выдана ошибка.
Можно создавать массивы локальных переменных при помощи команды
Код
local <тип переменной> array <имя переменной>

Например, массив юнитов:
Код
local unit array u

Обращение к элементам этого массива такое же как в триггерах:
Код
Set u[1] = …

- записываем в первый элемент массива такое-то значение. И т.п.
При создании переменных, можно сразу же записывать в них какое-то значение.
Код
local integer i =1

создаст переменную i и присвоит ей значение 1.
Предупреждение. Когда мы создаем глобальную числовую переменную, то ее значение автоматически приравнивается к нулю. Но для локальных переменных это не так. При создании локальной переменной ее значение не определено. Попытка их использования до того, как вы поместите в них какое-либо значение приводит к сбою. Пример ошибочного кода:
Код
local integer i
set i = i +1

Чтобы не было ошибки, сначала прировняйте значение переменной i к нулю.
Код
local integer i = 0
set i = i +1

Локальные переменные очень хорошо решают проблему хранения данных при отсроченных действиях, как мы разобрали в прошлом примере. Существует способ решения задач при помощи локальных переменных: способ движения от частного к общему. Алгоритм такой:
Создай обычный не универсальный триггер, который решает задачу для одного запуска.
Добавь локальные переменные и запиши в них все, что должно сохраниться во время паузы.
Помести данные обратно в глобальные переменные и делай нужные действия.
Локальные переменные выступают как хранилища на время пауз в триггере, глобальные переменные нужны для каких-то мгновенных действий. См. пример sample locs. Мы не можем угадать, что будет храниться в переменной unit в какой-то момент времени. Ее значение будет постоянно меняться в зависимости от игровых событий. Мы не можем помещать в эту переменную ДАННЫЕ ДЛЯ СОХРАНЕНИЯ, но можем использовать ее для мгновенных действий. В нашем случае работает только одно триггерное заклинание, но мы могли бы использовать ту же самую переменную unit для сотни точно таких же заклинаний.
Если хотите обойтись одними локальными переменными, то нужно либо весь триггер переводить в jass, либо переводить в cs те строки, где имеются ссылки на эти переменные.
Чтобы посмотреть, как выглядит та или иная команда в jass, можно использовать такой прием: создаем новый пустой триггер, создаем внутри него нужную команду и переводим триггер в текст. Затем этот текст можно будет вставить в cs один в один. Так что нет необходимости запоминать все команды на jass.
Итак, Читатель, ты уже достаточно узнал, чтобы создать свой собственный jass код. Правда, есть определенные тонкости который тебе нужно узнать. Во-первых, если в jass допущена ошибка, то при попытке сохранить карту или запустить ее будут выданы ошибки. При этом триггер тут же отключится и ты не сможешь его включить, пока не исправишь ошибки.
А теперь представь, что на данный триггер ссылается еще один. Что произойдет? Триггер отключился из-за ошибки и все триггерные команды, которые ссылались на него тоже отключатся.
Еще одна ситуация. Допустим, имеется триггер на jass или с cs, в котором идет ссылка на глобальную переменную unit. Затем, мы берем и меняем название глобальной переменной на unit2. Во всех нормальных триггерных действиях название старой переменной на новую произойдет автоматически. Но не в jass-коде! Там все названия останутся старыми. Т.е. нам нужно вручную менять везде udg_unit на udg_unit2, иначе будет выдана ошибка.
Поэтому при создании jass кода надо всегда соблюдать осторожность. Тем более что ошибки в jass не всегда бывают безобидными. Некоторые из них приводят к тому, что редактор вылетает без сохранения карты. Так что когда работаете с jass-кодом – ЧАЩЕ СОХРАНЯЙТЕСЬ!
Итак, Читатель, если есть время и желание, поработай над реализацией какой-нибудь из задач на jass. К примеру:
Заклинание разговор: когда применяешь его на юнит, на две секунды над ним появляется фраза плавающего текста «Привет».
Заклинание banish (триггерный аналог): на 20 секунд юниту-цели дается способность ethereal (дух).
 
Дата: Пятница, 07.01.2011, 14:36 | Сообщение # 5
Генералиссимус
Модераторы
Сообщений: 12998
Награды: 22
Репутация: 141
Вот и нифига се... Надо будет сегодня помучать редактор =)))

это Ксопик!
 
Дата: Пятница, 07.01.2011, 15:23 | Сообщение # 6
Генералиссимус
Ньюсмейкер
Сообщений: 2438
Награды: 8
Репутация: 85
Мельком пробежался по статье глазами и заметил, что тут ни слова об обнулении переменных.
Поправьте если ошибаюсь
Как понятно из статьи - при каждом срабатывании триггера формируются КАЖДЫЙ РАЗ НОВЫЕ переменные и в них записываются значения.
Переменные например типа юнит или эффект сильно засоряют память и их необходимо зачищать, чтоб карта не лагала.

Предположим у нас есть локальные переменные точки/региона или юнита и нам необходимо в конце триггера зачистить переменные т.к. они более не будут испольоваться.

Решение:

Code

local unit u  
local effect e
local point p
<действия...>
set p = null
set e = null
set u = null
 
Дата: Воскресенье, 27.03.2011, 14:53 | Сообщение # 7
Admin
Администраторы
Сообщений: 15097
Награды: 43
Репутация: 188
переношу

Warcraft 3 - это уже легенда
WC3 - это мини-легенда
Дота - это альтернативный путь развития варкрафта
 
Дата: Воскресенье, 27.03.2011, 21:04 | Сообщение # 8
Генералиссимус
Проверенные
Сообщений: 2873
Награды: 15
Репутация: 107
Jass нужен только для очень сложных спеллов, и то, в основном для многопользовательских карт. В большинстве случаев можно справиться стандартными средствами, но другое дело, строк будет намного больше. Так что, без джасса можно, но с джассом лучше. Я не умею, и думаю, вроде итак пока нормально все работает).
 
Дата: Понедельник, 20.06.2011, 16:09 | Сообщение # 9
Генералиссимус
Ньюсмейкер
Сообщений: 2438
Награды: 8
Репутация: 85
Quote (Vanzer)
В большинстве случаев можно справиться стандартными средствами, но другое дело, строк будет намного больше.

Обычно, если использовать не чистый жасс, а кустом скрипт + гуи, то строк будет больше.
Только Гуи - строк меньше.
Только Жасс... тут совсем другая история, там строк не больше, там строк тьма и фактом остается то, что это надо писать вручную с клавы.

Quote (Vanzer)
в основном для многопользовательских карт

Если честно... даже не могу вспомнить зачем применять локальные в сингл картах, разве что в триггерах, где может быть много вхождений до завершения триггера, например, захотели мы писать над каждым юнитом сколько нам за его убийство дали опыта и если убить мобов массовым скилом то триггер начнется ровно столько раз, сколько было убито юнитов, в итоге весь код запутается и будет выдавать что попало.

Вот в такой ситуации надо локальные переменные. А так... в основном для многопользовательских карт их юзаю.

Во всяком случае локальные переменные - это инструмент WE о котором надо хотя бы знать.

Мне вот непонятно, для чего раздел?


Сообщение отредактировал DonLaonda - Понедельник, 20.06.2011, 16:09
 
Дата: Суббота, 30.07.2011, 22:05 | Сообщение # 10
Генерал-лейтенант
Проверенные
Сообщений: 522
Награды: 5
Репутация: 26
DonLaonda, тебе за это деньги брать надо :)
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: