Сейчас 14:14:21 Четверг, 28 ноября, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
[СТАТЬЯ] Триггеры в JASS
VedunДата: Четверг, 19 Апреля 2007, 23:03:59 | Сообщение # 1
2 уровень
Группа: Проверенные
Сообщений: 39
Награды: 0
Репутация: 47
Блокировки:
JASS – триггеры в виде кода.
Недавно я подумал, что уже довольно давно не писал статей и решил написать статью на тему триггеры в понимании JASS.

Собственно, вот то, что из этого вышло.

Итак, триггер. Вспомним, из чего он состоит.


  • События.
  • Условия.
  • Действия.

И начнём мы с общего анализа триггера в текстовом виде. Для примера создадим триггер с названием Sample. Добавим в него событие Игрок красный выигрывает (Игрок - Victory). Теперь – условие: Игрока красного контролирует человек (Player Controller Comparison). Ну и в качестве действия выведем на экран строку: «Вы выиграли!!!» (действие Игра – Text Message). Теперь у нас есть триггер. Переведя его в текст, мы получим это:
Code
function Trig_Sample_Conditions takes nothing returns boolean <br />      if ( not ( GetPlayerController(Player(0)) == MAP_CONTROL_USER ) ) then <br />          return false <br />      endif <br />      return true <br /> endfunction <p> function Trig_Sample_Actions takes nothing returns nothing <br />      call DisplayTextToForce( GetPlayersAll(), "Вы выиграли!!!" ) <br /> endfunction <p> //======================================================== <br /> function InitTrig_Sample takes nothing returns nothing <br />      set gg_trg_Sample = CreateTrigger(  ) <br />      call TriggerRegisterPlayerEventVictory( gg_trg_Sample, Player(0) ) <br />      call TriggerAddCondition( gg_trg_Sample, Condition( function Trig_Sample_Conditions ) ) <br />      call TriggerAddAction( gg_trg_Sample, function Trig_Sample_Actions ) <br /> endfunction

У нас есть три функции. Начать стоит с самой последней (InitTrig_Sample). Как видно, её название состоит из приставки InitTrig_ и названия триггера. InitTrig – инициализация триггера. В этой функции триггер регистрируется в игре. Это происходит в первой троке:
Code
set gg_trg_Sample = CreateTrigger(  )

gg_trg_Sample – это что то вроде глобальной переменной (ubg_), но используется она только для триггеров. То есть создаётся новый триггер, который записывается в переменную.
Следующая строка – регистрация события. Собственно, чтобы добавить событие, нужно вызвать соответствующую функцию (в нашем случае TriggerRegisterPlayerEventVictory) и передать в неё все параметры (gg_trg_Sample, Player(0)).

*Примечание.
Событие Map initialization – особый случай и о нём мы поговорим позднее.

Далее идёт добавление условия:

Code
call TriggerAddCondition( gg_trg_Sample, Condition( function Trig_Sample_Conditions ) )

Здесь принцип несколько другой, чем для добавления событий. Функция добавления условий одна (TriggerAddCondition). В неё мы передаём триггер и функцию с условиями. Теперь посмотрим на саму функцию с условиями.
Там всё чрезвычайно запутанно. Но ведь в этом и цель ВЕ – запутать всех и вся =). В конце концов весь этот код можно свести к одной строчке:

Code
return GetPlayerController(Player(0)) == MAP_CONTROL_USER

*Примечание.
Добавлять условия в функцию InitTrig_*** ВЕ будет только тогда, когда эти условия добавлены именно в блок с условиями триггера. Если же, например, мы использовали действие if / then / else, то функция с условиями создастся, но в функцию инициализации триггера она не добавится. В триггере можно создавать сколько угодно отдельных функций, которые не должны нигде указываться.

Добавлено (19-04-2007, 11:03 Pm)
---------------------------------------------

С условиями разобрались. Посмотрим теперь на действие. Собственно, здесь всё аналогично условию (за исключением названия функции =). Так что объяснять всё подробно нет смысла.

Вот вкратце об устройстве триггеров. Теперь немного поговорим об оптимизации. Я уже немного говорил об этом (условие), но теперь стоит сказать зачем это вообще надо.
Ну, первый факт, это конечно удобство. Ведь если каждое условие будет создавать новую функцию, в которой будут тонны ненужных операторов… Всё это в конце концов приведёт к хронической головной боли. Далее. Лишняя нагрузка – лишний геморрой. Да и к тому же гораздо проще разобраться в триггере (постороннему человеку) когда он решит поподробней рассмотреть наработку =).
Но вот хуже всего в ВЕ реализованы циклы, которые перебирают всех юнитов в определённой области. Предположим, мы хотим убить всех юнитов на карте. Опущу подробности такого сложного триггера =) и приведу его сразу на JASS:

Code
function Trig_KillAllUnit_Func001A takes nothing returns nothing <br />      // Здесь действия цикла <br />      call KillUnit( GetEnumUnit() ) <br /> endfunction <p> function Trig_KillAllUnit_Actions takes nothing returns nothing <br />      // Здесь действия функции <br />      call ForGroupBJ( GetUnitsInRectAll(GetPlayableMapRect()), function Trig_KillAllUnit_Func001A ) <br /> endfunction

К сожалению, объединить данную конструкцию в одну функцию нельзя. Но можно сделать её несколь-ко красивее. Например, так:

Code
function KILL takes nothing returns nothing <br />      call KillUnit(GetEnumUnit()) <br /> endfunction <p> function Trig_KillAllUnit_Actions takes nothing returns nothing <br />      call ForGroupBJ( GetUnitsInRectAll(GetPlayableMapRect()), function KILL ) <br /> endfunction

В такие функции-циклы нельзя передавать параметры. То есть, для передачи данных в них надо использовать переменные (или аналогичные способы передачи данных, о которых я расскажу в следующих статьях).

Теперь отдельный разговор о событии Map Initialization. На самом деле, это даже не событие. Оно никак и нигде не регистрируется. Такие триггеры исполняются во время инициализации потоков игры. Соответственно серьёзные ошибки в таких триггерах могут привести к краху этих самых потоков.

И в конце ещё одно примечание.
Код из действия Custom Script остаётся неизменным при переводе с GUI на JASS.

Вот я и рассказал о триггерах. Если дойдут руки до следующей части о триггерах, опишу их создание динамически (что очень часто бывает чрезвычайно полезным). А пока на этом всё. Жду комментов.

 

  • Страница 1 из 1
  • 1
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz