Добавлен , опубликован

Осваиваем World Editor: триггеры

Содержание:

Переменные, выражения, функции

Если Вы изучали языки программирования, то что такое переменная Вам объяснять не нужно. Можете смело пропустить этот раздел статьи.
Переменные (variables) ассоциируются с определенными игровыми объектами. Т. к. я не исключаю, что эту статью читают люди, никогда не занимавшиеся программированием, я опишу понятие переменной.
Иногда (даже очень часто) нам требуется запомнить какую-то информацию. Например, допустим мы хотим реализовать тот же прием, что и в кампании за нежить ТФТ - помните в первой миссии люди бегут к областям, а нежить должна их перехватить. Если человек добегает до области, он исчезает из игры и считается спасшимся. Если спасется более 10 человек, нежить проигрывает. Чтобы реализовать такое, нам нужно запоминать количество спасшихся юнитов. Создаем переменную i, и в нее будем записывать число спасшихся людей. При входе человека в регион r, мы его убираем, а значение i увеличиваем на 1. Если i>10, нежить проигрывает.
Во многих случаях можно обойтись без переменных, но при должном умении переменные дают возможность намного упростить решение триггерных задач. Более того, некоторые задачи - такие как работа со спецэффектами, диалогами, таблицами записей, мультибоардами и др. - по нормальному просто невозможна без переменных.
Не бойтесь использовать много переменных! В большинстве случаев гораздо удобнее составлять карту из "кусков" - наработок / разработок. И это отличный пример использования переменных ради удобства. Гораздо удобнее настраивать наработку с помощью переменных (хотя не факт, что настройка делаются именно с помощью переменных), чем лезть в её код, хотя в обоих случаях будет один и тот же результат (зато разные временные затраты и количество потраченных нервов). Еще это может сэкономить количество функций в триггере, если в паре с переменными (массивами) использовать циклы. Но об этом позже. Сейчас же запомните, что не следует бояться переменных, пусть их даже будет много, хотя, конечно, не стоит создавать их тоннами (очень на многом можно сэкономить). Но у всего есть своя цена - будет глупо, если вместо того, чтобы воспользоваться одной переменной, мы напишем 100 строк кода, только для того, чтобы не вводить новую переменную.
У переменных есть типы, соответствующие разным "видам" данных. Ведь число отличается от юнита, верно? Мы ведь не можем сделать с числом то, что можем сделать с юнитам (например, отдать приказ числу). Поэтому и появилась необходимость в типах, чтобы не возникало таких "ошибок". Вот список основных типов. Использовать другие типы приходится достаточно редко, но принцип тот же, поэтому разобрать самостоятельно не должно вызвать трудности.
  • Логический (boolean)
  • Целое число (integer)
  • Рациональное число (real)
  • Строка (string)
  • Юнит (unit)
  • Типы юнита (unit type)
  • Квест (quest)
  • Спецэффект (special effect)
  • Регион (region)
  • Игрок (player)
Для переменной каждого типа есть специальные функции. Например, в переменную целого типа с помощью этих функций можно помещать такие параметры, как количество юнитов у определенного игрока (в том числе и количество юнитов определенного типа как на всей карте, так и на определенном регионе / у определенного игрока), количество золота или леса у игрока, количество еды, которую производят фермы и т. д. В рациональные переменные можно помещать число Пи, количество жизней или маны у определенного юнита, угол поворота юнита, координаты юнита на карте и т. д.
Примечание: разница между целочисленной и рациональной состоит в том, что целочисленная может содержать только целые числа, в то время как рациональная - любое дробнорациональное. Но лично я рекомендую использовать их по назначению! Например, если Вы уверены, что какой-либо переменной будут присваиваться только целые значения, делайте её целой. Нагрузка на процессор при работе с этими типами разная - у рациональных она выше.
Но далеко не обязательно, чтобы значение переменной было конкретным значением, вроде i = 4. Переменной можно присвоить выражение. То есть, i = 2 * 2 запишет в переменную то же самое (конечно, я пишу это не в виде триггеров, но в общем, надеюсь, понятно). Можно дать значение какой-нибудь переменной в зависимости от другой переменной: что-нибудь вроде i = j * 5. В результате в i будет записано значение, "полученное" от j * 5. Такое выражение возвращает какое-то значение. Это нужно понимать. Возвращаться могут не только цифры, а любые объекты (но только те, у которых есть свой тип переменных): юниты, строки, игроки...
Примечание не сразу может быть понятно слово возвращает. Никто ни у кого ничего не брал в долг. Более подробно это можно описать следующим образом: вместо самого выражения будет подставлен результат его выполнения.
Также бывают массивы переменных. Массивы - это множество переменных с одинаковым именем и типом, но разными номерами (индексами). Обращаться к элементу массива нужно по образцу: <имя переменной> [<номер элемента массива>]. Пример:

    Set i[0] = 2
    Set i[1] = 5
    Set i[3] = 8
    Set i[5] = 7
Соответственно, i - массив типа integer. Не обязательно, чтобы индексы (эти самые номера) шли по порядку. Можно использовать отрицательные индексы. Однако массив ограничен - [-8192...8192]. То есть, элемента с номером 8193 существовать не может, а при попытке присвоить / читать такой элемент он просто вернет 0 (а значение не будет присвоено, никаких предупреждений об ошибках). Подробнее о массивах мы поговорим позже. Особенно их удобно применять в паре с циклами.
Теперь рассмотрим понятие функций и возвращаемых ими значений. Функция - некий "кусок" кода, который можно "вызывать". Это как выражение, только гораздо более расширенное - с его помощью можно получить количество юнитов в группе, количество жизней или маны у юнита и т. п. Она точно так же "возвращает" значения, хотя далеко не обязательно вообще что-либо возвращает (на этом мы останавливаться в пределах данной статьи не будем). Первый пришедший в голову пример: функция (действие), возвращающая уровень героя. В результате работы следующего "куска" триггера, в Level будет записан уровень героя Hero. Из редактора невозможно копировать русские буквы, поэтому все примеры триггеров будут в английском варианте (дабы не запутаться, переменные я буду подчеркивать).
Actions
    Set !!Level!! = (Hero level of !!Hero!!)
Возвращаемое значение не обязательно должно быть числом. Возвращаться может и юнит... Вот, например, следующий код:
Actions
    Unit - Create 1 Town Hall for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing (270.0) degrees
    Set !!TownHall1!! = (Last created unit)
В результате переменная TownHall1 ссылается на нового юнита. Blizzard довольно странно сделали некоторые вещи, и примером таких "странностей" может служить как раз этот код. (Last created unit), по сути, тоже является функцией. Неужели не было легче сделать так, чтобы сама функция создания юнита возвращала только что созданного юнита?..
Примечание: переменная ссылается на юнита! Не юнит переходит в переменную, а переменная ссылается на юнита. Грубо говоря, при её считывании она "вернет" этого юнита. Конечно, на одного и того же юнита могут ссылаться сразу несколько переменных.
Выражения могут быть использованы в паре с функциями, что чаще всего и делается.
Чтобы создать переменную, Вы должны быть в редакторе триггеров. Нажмите переменные (edit => variables...) или просто нажмите кнопку с крестиком. Здесь Вы сможете создавать переменные или изменять уже созданные. Редактор переменных можно запустить прямо во время создания некоторых триггеров, нажав на кнопку изменить (edit variables) (очередной пример неудачного перевода).
Переменная включает следующие параметры: имя (должно быть уникальным), тип, начальное значение (не обязательно). Возможно также создание массивов переменных (во время создания переменной устанавливаете флажок). После того, как переменная создана, появляется возможным использовать ее при создании триггеров.
Я бы хотел отдельно и подробно описать тип boolean, также называемый "бул" или логический тип. Не стоит забывать, что статья предназначена и для людей, не занимавшихся программированием.
Бул может принимать два значения: истина (true) и ложь (false). Где это можно применить? Давайте рассмотрим простой пример.
Где-то в середине игры нам нужно узнать, проходил ли герой в каком-то регионе за все время игры. Вроде бы, легко - просто делаем триггер, ставим как условие заход юнита в регион... а что потом? Нужно где-то сохранить "факт" захода юнита в регион. Первое, что приходит в голову (в том случае, если мы не знаем ничего о булинах) - сделать целочисленную (integer) переменную и дать ей значение 1 (а по умолчанию оставить 0). Вот тут-то и вспоминаем про булины. Гораздо лучше воспользоваться средствами, "заточенными" под эти цели - булинами. Ставим значение истина (по умолчанию - ложь) и все.
Примечание: конечно, можно использовать единицу и ноль, или даже строки "да" и "нет", но гораздо лучше воспользоваться булинами. Хотя бы по той причине, что именно булины используются во всех проверках (if'ы, условия). Да и потом - зачем извращаться, когда есть предназначенные для чего-то конкретного средства?
Кстати, булин в памяти занимает, меньше, чем число (integer), рациональное число (real) и, тем более, строка.
Вернемся к условиям. Чтобы условие "выполнилось", оно должно "вернуть" истину ("условия" бывают не только как условия в триггере). Чтобы "вернуть" истину, его "высказывание" (само условие) должно быть истинным. Рассмотрим пример "на словах": эта статья - статья о триггерах. Это правда? Правда. Если это рассматривать как условие, то при его проверке оно "вернет" истину. Рассмотрим пример на триггерах:
Conditions
    (Triggering unit) Equal to Footman 0000 <gen>
Это - условие. Если (Triggering unit) (что это такое, рассмотрим позже) это тот же юнит (Equal to), что и Footman 0000 <gen>, то это высказывание истинно и вернет истину. Рассмотрим еще один пример:
Conitions
    False Equal to False
Так как ложь действительно является ложью, это высказывание истинно, а значит вернет истину. Еще пример:
True !!Not equal to!! False
Думайте, оно вернет ложь? Нет, оно вернет истину. Обратите внимание: Not equal to! То есть, не равен. Это высказывание верно (действительно, истина не есть ложь), а значит вернет истину. Также есть Greater than or equal to, Less than or equal to, Less than, Greater than для работы с числами.

1
4
14 лет назад
1
с примерами было бы лучше. :(
3
4
13 лет назад
3
Без примеров нечего не понятно
1
0
13 лет назад
1
Отлично Спасибо
1
2
13 лет назад
1
bonifaciy, ARS, чё тут не понятного всё ясно и благорозумно.
1
0
13 лет назад
1
Всё тут понятно:)
0
8
13 лет назад
0
Вот это тяжко=(
1
12
13 лет назад
1
Спасибо понятно...
2
1
12 лет назад
2
Ммм придется потрудится всё это запомнить.
6
2
12 лет назад
6
Узнал кое-что новое, однако статья трудна для понимания для новичков.
2
1
11 лет назад
2
Можно сказать обматерили за нубовопросы на форуме и направили сюда, учим) а кому жить легко сейчас?)
2
25
11 лет назад
2
ashez, Технико, и правильно сделали. Сначала изучаем азы, потом пробуем делать сами, а лишь потом ЕСЛИ НЕ ВЫХОДИТ - идем на форум и ставим вопросы.
2 комментария удалено
Чтобы оставить комментарий, пожалуйста, войдите на сайт.