DotaGames.ru - вся для Minecraft, WoT

Среда, 24.04.2024 23:03

Меню сайта
    Главная страница Каталог файлов Каталог статей Баннеробмен Форум Фотоальбомы Гостевая книга Скачать Гарена клиент Предметы для Героев Dota 2
Категории раздела
Создание карт [27]
Статьи о Battle.net [1]
GGC (Garena) [4]
Интервью с топ-игроками [2]
Юмор [1]
Разное [4]
Наш опрос
Что лепим морфу первым артом?
Всего ответов: 218
Статистика
измерьте скорость интернета
Онлайн всего: 1
Гостей: 1
Пользователей: 0

Новости: 52
Файлы: 1010
Статей: 78
Фото: 107
Форум: /
Комментарии: 65
Гостевая книга: 1131

Друзья сайта
Карты Warcraft, Гайды Dota, Iccup, Карты для Майнкрафт 1.5.2, 1.4.7 Карты для Варкрафт 3, Гайды дота 2 Mp3, Новые хиты 2013 СКАЧАТЬ ПОПУЛЯРНЫЕ ПЕСНИ 2013
Главная » Статьи » Различные статьи » Создание карт

Осваиваем JASS
6. Устройство триггера с точки зрения jass
Теперь, когда ты уже изучил функции, остановимся подробнее на устройстве триггера. Я уже говорил, что при переводе триггера в текст, он преобразуется в несколько функций. Но что же такое триггер? Просто несколько jass функций? Не совсем так. Правильнее сказать триггер, все его события, условия, действия СОЗДАЮТСЯ при помощи jass-функций. Функции сами по себе, а триггер как бы объединяет их в единую структуру.
Давай рассмотрим этот процесс. Возьмем какой-нибудь триггер:
Триггер sample
События
Every 5.00 seconds of game time
Условия
((Triggering unit) is Здание равно Да
(Ability being cast) равно «Гальванизация»
Действия
Wait 2.00 game-time seconds
Play (no unit)'s stand animation
Вообще говоря, бессмысленный триггер, но важно не это. Во что он превратится, когда мы переведем его в jass? В следующий код:
function Trig_sample_Conditions takes nothing returns boolean
if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == true ) ) then
return false
endif
if ( not ( GetSpellAbilityId() == 'AUan' ) ) then
return false
endif
return true
endfunction

function Trig_sample_Actions takes nothing returns nothing
call PolledWait( 2 )
call SetUnitAnimation( null, "stand" )
endfunction

//===========================================================================
function InitTrig_sample takes nothing returns nothing
set gg_trg_sample = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_sample, 5.00 )
call TriggerAddCondition( gg_trg_sample, Condition( function Trig_sample_Conditions ) )
call TriggerAddAction( gg_trg_sample, function Trig_sample_Actions )
endfunction
Первая функция - это то во что превратились условия триггера. Можешь проверить, что эта функция возвращает значение ИСТИНА, если условия исходного триггера будут выполняться, и ложь в противном случае. Вторая функция - действия триггера. Об этом и так можно догадаться, если глянуть на названия триггеров "Trig_sample" - т.е. триггер с названием sample "_Conditions" - условия, "_Actions" - действия.
Что касается третьей функции, то у нее свое особое назначение. Посмотри на название "InitTrig_sample". Приставка Init - напоминает слово Initialization, т.е. это что-то связанное с загрузкой карты. Эта функция запускается при инициализации карты. Ее назначение - собрать наш триггер воедино, объединив события, условия и действия. Сейчас посмотрим на строки:
set gg_trg_sample = CreateTrigger( )
Что-то к чему-то прировняли... gg_trg_sample - это разновидность глобальной переменной типа ТРИГГЕР, которая будет отвечать за хранение нашего триггера в памяти компьютера во время игры. Такие переменные автоматически создаются, когда ты создаешь в редакторе новый триггер.
В начале игры все такие переменные пустые. Действие set gg_trg_sample = CreateTrigger( ) приводит к тому, что в игре создается НОВЫЙ ТРИГГЕР - настоящий триггер, который до этого не существовал. В нем пока нет ни условий, ни событий, ни действий. При этом переменная gg_trg_sample будет ссылаться на этот триггер.
Далее идет строка
call TriggerRegisterTimerEventPeriodic( gg_trg_sample, 5.00 )
Эта команда приводит к тому, что к нашему пустому триггеру добавляется событие "Every 5.00 seconds of game time". Т.е. у нашего триггера уже есть событие. Для добавления любого события есть своя команда, которую ты можешь посмотреть при переводе триггера в текст. Исключение Map Initialization, но это отдельный разговор.
Далее
call TriggerAddCondition( gg_trg_sample, Condition( function Trig_sample_Conditions ) )
Это специальная команда, которая добавляет нашему триггеру условие. Заметь, в качестве аргументов мы указываем триггер и функцию, в которой записано условие триггера.
Далее
call TriggerAddAction( gg_trg_sample, function Trig_sample_Actions )
По аналогии с предыдущей командой - эта добавляет в триггер действия.
Когда при загрузке карты будет автоматически выполнена функция InitTrig_sample, только тогда объект триггер будет загружен в память компьютера и начнет работать. Вот такая механика.
Частенько структура триггера может быть сложнее, чем в описанном примере. Например, применение условного оператора (в триггерном виде), действий типа Pick every unit and do <action> приводит к тому, что в триггере создаются новые функции - события и действия. Бывает, что триггер так загромождается ими, что при переводе в jass трудно разобраться, что к чему. Иногда код можно оптимизировать и сделать более простым.
Еще такой интересный вопрос: если мы создаем триггеры при загрузке карты, не можем ли мы воспользоваться теми же командами, чтобы создавать триггер ПРЯМО ВО ВРЕМЯ игры. Ответ положительный - можем. И иногда это бывает очень удобно.
Читатель, если ты прочитал все что было до этого и разобрался в этом, то считай, что ты уже не новичок. Хотя еще не хватает практики собственной работы. И теперь мы сможем приступить к изучению продвинутого jass, который значительно расширяет возможности создания сценариев.

7. Динамическое создание триггера
Читатель, давай рассмотрим пример, который покажет некоторые возможности jass, недоступные в редакторе триггеров.
Вот например, известно, что определить, когда юнит получает повреждения можно лишь при событии Unit takes damage, которое можно создать лишь для конкретного юнита. Жуть как неудобно. А если возникает задача по ходу игры узнать, когда ударили юнит и сколько повреждений нанесли? Попробуем решить эту задачу исходя из того, что мы узнали о jass. Предлагаю скачать пример, который я выслал в данном сообщении и посмотреть его устройство.
Пример называется Magic Shield.w3x. В нем реализовано заклинание волшебной брони для создания защиту, которая поглощает определенное число повреждений юнита, а затем исчезает. Причем юнитов с броней может быть сколько угодно. Как это реализовать?
Если мы можем динамически создавать новые триггеры прямо по ходу игры, почему бы не сделать так, что когда юнит применяет заклинание защиты, мы СОЗДАДИМ триггер, который будет отлавливать, повреждения. Делается это достаточно просто:
делаем триггер Magic Shield, который сработает при произнесении заклинания брони. Для юнита создается триггер с событием unit takes damage где в качестве проверяемого юнита выступает кастер. В качестве действия для нового триггера, нужно указать какую-нибудь функцию. Я использовал функцию "Adv_Trig_Actions", которая записана в специальном месте для пользовательских функций. Эта функция определяет действия, которые произойдут, когда юнит получит повреждения.
Правда имеются с триггером и некоторые сложности. Во-первых, где-то надо хранить информацию о том, что у такого-то юнита имеется такой-то запас брони. Локальные переменные тут не годятся, т.к. информацию мы сохраняем в одном триггере, а действие реализовано в другом. Поэтому в качестве хранилища информации пришлось использовать массивы. При применении заклинания, в массив MS_units заносится кастер, в массив MS_power заносится количество повреждений, которые может поглотить броня, в массив MS_trigs заносится триггер, созданный для отлавливания повреждений кастера. В переменной MS_num – общее число юнитов с данной защитой. Т.е. к примеру, произнес юнит заклинание брони. Мы проверяем. Не ли такого уже в массиве. Если нет – увеличиваем MS_num на 1, а затем заносим данные об этом новом юните в элементы массивов MS_units[MS_num], MS_power[MS_num] , MS_trigs[MS_num] . Если же юнит уже находится внутри массива под номером N, это значит он уже применил ранее заклинание щита. Тогда нам не нужно заново создавать для него триггер, отлавливающий повреждения. Мы просто обновим уровень защиты в переменной MS_power[N] .
В этом смыл действий основного триггера, который происходит во время применения заклинания защиты. А как насчет дополнительного триггера, создаваемого по ходу игры?
Прежде всего, когда мы отловили дополнительным триггером нанесенные повреждения юниту, нужно найти номер этого юнита в массиве. Скажем, его номер N. Далее, мы сопоставляем полученные юнитом повреждения и уровень защиты юнита MS_power[N] . Если защиты больше – мы просто уменьшаем уровень защиты на количество повреждений, а затем восстанавливаем юниту потерянную жизнь. Если же уровень защиты меньше количества повреждений, то мы должны восстановить юниту число повреждений, равное остатку защиты, после чего удалить триггер MS_trigs[N] .
Чтобы удалить данные из N-того элемента массива, мы просто заменяем значение N-того элемента на значения последнего элемента с номером MS_num. После чего уменьшаем MS_num на 1 – ведь элементов стало меньше.
Кстати, при каждом ударе по юниту с защитой, также появляется спецэффект.
Обрати внимание на действие
call DestroyTrigger(<ссылка на триггер>)
У него нет аналога для обычных триггеров. Это действие уничтожает выбранный триггер, убирая его из памяти компьютера прямо во время игры.
Вообще-то пример получился не очень простым. Для работы заклинания требуются 3 массива и еще одна переменная. При каждом запуске или ударе по юниту с броней происходит цикл, в котором проверяется, есть ли такой-то юнит в массиве... Неудобно. Но что делать – как напрямую сопоставить юниту какие-то значения? Вообще-то сопоставить можно. Есть custom value, но для нашего примера его явно недостаточно.
На самом деле есть на jass есть замечательный прием, который позволяет сопоставить любому игровому объекту какие-то значения. Но для того, чтобы узнать как, нам придется углубиться в jass. И тогда мы сможем этот пример значительно улучшить.
Категория: Создание карт | Добавил: TOTKTO3HAETBCE (10.09.2011)
Просмотров: 627 | Рейтинг: 0.0/0
Аим Чит на нож Карты для МайнкрафтКарты для Minecraft
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Friends
Карты Warcraft, Гайды Dota, Iccup, Карты для Майнкрафт, Карты для Варкрафт 3, Гайды дота 2 Dota 6.78c Mp3, Новые хиты 2013 СКАЧАТЬ ПОПУЛЯРНЫЕ ПЕСНИ 2013 Аим Чит на нож Карты для МайнкрафтКарты для Minecraft
Последняя версия:
Top 5


Admin
Репутация: 17
Постов: 196
Релизов: 978


srac
Репутация: 0
Постов: 15
Релизов: 31


HopZor^^
Репутация: 0
Постов: 1
Релизов: 1


was_can
Репутация: 0
Постов: 0
Релизов: 1


Fonix
Репутация: 0
Постов: 0
Релизов: 0

DotaGames.ru - вся для Minecraft, WoT

DotaGames.ru - Warcraft III Карты | Модели | ИконкиMinecraft карты| © 2011-2013 | Сделать бесплатный сайт с uCoz | Sitemap | Sitemap-Forum
Копирование материалов на другие сайты запрещено!Mp3, Новые хиты 2013СКАЧАТЬ ПОПУЛЯРНЫЕ ПЕСНИ 2013

Warcraft III, Minecraft - Карты, модели, иконки, спеллы, наработки, звуки, модмейкинг, статьи, Батл нет