Перейти к содержимому

MatroseFuchs

Разработчик
  • Публикации

    1 403
  • Зарегистрирован

  • Посещение

  • Бои

    7631
  • Клан

    [LESTA]

Все публикации пользователя MatroseFuchs

  1. Event Событие - объект который генерируется и рассылается по какому-либо действию пользователя (например клик мыши, нажатие клавиши и т.п.). Для распространения события используется метод dispatch. Событие либо происходит (что эквивалентно bool == true) либо отсутствует. Событие может срабатывать по различным условиям, а ловить (или слушать) событие могут как родители, так дети и сиблинги. Для этого нужно объявить это же событие в скоупах всех элементов, где планируется их ловить. (event valChanged) (event evKilled) ... (dispatch evKilled args={} dir="EventDirection.DOWN" (event $datahub.getEntity(entityId).health.evKilled)) event это событие по которому происходит dispatch. dir задаёт направление события по иерархии. По умолчанию dispatch отсылает событие только в рамках самого элемента. Чтобы отправить событие в родителя - нужно в dir указать EventDirection.UP. В ребёнка - EventDirection.DOWN. В сиблингов - достаточно просто объявить эвент в нужном сиблигне, а dir можно не указывать. Для dir в hud_replaces заведён dict со значениями. По умолчанию dir=0. (def constant EventDirection { NONE: 0, UP: 1, DOWN: 2 }) События в unbound могут генерироваться: Из core C++ части. Например в блоке slider генерируется event valueChanged когда изменяется его value. (dispatch valChanged on='valueChanged' dir=1) Из Scaleform части. Например событие клика по display object'у (block (style (width = 100) (height = 100) (backgroundColor = 0xff00ff00) ) (bind alpha "0.5" init=false on='click') ) Различия использования подписки на события с помощью on и event Биндинг-конструкции могут подписываться на события двумя способами: Передача имени события в аргумент on. (bind eventArgs "$event" init=false on='eventScope') Передача вложенного объекта event (trace "$event" init=false (event "eventScope")) Событие может быть сгенерировано: в scalefom, например событие мыши click или событие клавиатуры keyDown в core c++ части unbound, например блок slider генерирует событие sliderPositionChanged когда изменятся положение ползунка в верстке, т.е. событие объявлено в scope элемента и генерируется в его определении. (def element TestView() layout = true entrance=true (scope (event eventScope) ) (element Button (dispatch eventScope on='click') ) ) Но по сути своей это не генерация события, а превращение из события scalefom/core c++ (в данном примере 'click') в событие скоупа (в данном пример eventScope) Рассмотрим различия между этими двумя способами. Если событие генерируется в scaleform или в core c++ unbound, то подписаться можно только с использованием аргумента on. Если событие объявлено в scop'e элемента, то существует 2 случая подписки в зависимости от расположения подписки. Подписку в scope можно осуществлять и через on и через event Подписку вне скоупа можно осуществлять только через event Таким образом подписываться через аргумент on можно на те события которые генерирует target-объект. Отдельно рассмотрим случай подписки на события scop'а при создании элемента. (element Button (scope (label = 'default text') (bind label 'leftClick' init=false on='evBtnLeftClickEvent') (bind label 'rightClick' init=false on='evBtnRightClickEvent') ) ) События 'evBtnLeftClickEvent' и 'evBtnRightClickEvent' генерируются в определении element'а Button. Если использовать конструкцию event, то события должны быть объявлены в родительском скоупе
  2. Element Объект верхнего уровня. Имеет собственное имя, может быть вызван (в том числе извне документа, в котором находится) и переиспользован (с помощью Controllers или прямого объявления). Имеет свой обособленный scope, в который может принимать извне присланные значения. Элемент может быть 2 видов: участвовать в layout (иметь стили) и не участвовать. Это регулируется свойством layout=true или использование алиаса def layout:
  3. Controllers Контроллер -- сущность, выполняющая один тип действий с заданным объектом. У контроллеров $Instance, $FxInstance и $Repeat - объект указывается в поле renderer; контроллер $Animation направлен на родительский объект; контроллер $Sector сам является объектом. $Instance Добавляет на сцену экземляр element'a. renderer задаёт элемент, с которым контроллер будет производить операции. Доступен для биндинга. layout отвечает за то, будет ли работать layout система. Значение по умолчанию false args при вызове передаёт в рендерер значение из скоупа, в котором находится. exprs выполняется на стороне рендерера, но имеет доступ к родительскому скоупу. Может содержать выражения и биндинги. Через этот атрибут позволяет слушать в ребенке переменные из родительского скоупа. enabled задаёт выражение для срабатывания контроллера. Контроллер сработает, если выражение == true. trigger задаёт выражение для срабатывания контроллера. Контроллер сработает, если выражение изменит значение. event, аналог enabled, но реагирует на Events В некоторых случаях не требуется выделять отдельный элемент, тогда блоки можно вложить в атрибут (exprs и выставить layout=true у контроллера. recreate - метод, который пересоздает инстанс $FxInstance Временно добавляет на сцену экземпляр элемента, который будет удалён со сцены через «lifetime» секунд. renderer, args, exprs, enabled, layout - поведение аналогично поведению в $Instance контроллере bindcall create - определяет эвент (событие) срабатывания для контроллера. Контроллер вызывается когда в скоупе ловится указанное событие. В примере выше мы обращаемся напрямую к $datahub, поэтому переменную или эвент отдельно для этого события можно не заводить (но так делать не рекомендуется, т.к. компонента на момент инициализации может не оказаться и подписка не произойдёт. Лучше объявлять entity, component и уже обращаться к эвенту внутри переменной-компонента). lifetime определяет время жизни элемента на сцене. Если не задано - значение по умолчанию 15 секунд. $Repeat Создает указанное число копий рендерера. (controller $Repeat renderer='MapMarkerItem' (bind count "collection.items.length" (event "collection.evAdded")) (args size="size" mapScale="mapScale" scaleRatio="scaleRatio") ) renderer, args, exprs, enabled, layout - поведение аналогично поведению в $Instance контроллере count задаёт число копий рендерера. Может быть любым expression'ом. В примере выше -- counter равен количеству элементов в коллекции collection. removeChildAt(index) - удаляет со сцены рендерер по index $index - целое число, номер ребенка по порядку от 0 до конечного элемента. У первого созданного элемента будет $index=0 и т.д. Автоматически находится в скоупе ребенка с момента создания. $Animation Анимирует родительский display object или значение переменной в скоупе. Доступные методы контроллера с примерами заполнения параметров: play - запуск одной анимации если (keystate == Key.DOWN), то изменяет значение longTapArc с 0 до 360 за 0.5сек если переменная tacticalMap меняет значение - отыгрывает появление, если tacticalMap меняет значение на первоначальное - отыгрывается исчезновение. bindcall указывает, что запустить анимацию следует в соответствии с условиями, указанными в bind enabled, bind trigger или event. duration указывает длительность анимации в секундах. delay указывает задержку перед проигрыванием анимации. from стартовые значения анимации. Если не указать - анимация начнется с тех значений, которые находятся в скоупе. to финальные значения анимации. Обязательное поле. reverse условия отыгрывания анимации в обратную сторону, to → from (при условии наличия обоих полей). trigger условия срабатывания анимации, когда значение условия меняется. Отличие от enabled в том, что enabled срабатвает только когда выражение == toBoolean(true). ВАЖНО! На момент запуска delay -- контроллер уже принял в себя значения всех переменных на всех позициях. Если на момент окончания задержки значения переменных изменились - контроллер об этом не узнает. killAll - свойство, при старте анимации уничтожает все активные анимации у объекта Доступные изинги: https://easings.net/ параметр easing принимает следующие значения: Примеры: Пример запуска анимации по клику на кнопку и отображение в текстовом блоке изменяющихся значений. Анимация переменной в scope : Пример анимации свойств стилей Trigger vs Enabled (controller $Animation (bindcall play duration = "HEALTH_ANI_MIN" enabled="isEnabled" ..... ) (controller $Animation (bindcall play duration = "HEALTH_ANI_MIN" trigger="isTarget == 'ally'" ..... ) trigger - условие срабатывания анимации, когда значение условия меняется на противоположное. Отличие от enabled в том, что enabled срабатывает только когда выражение true. Внимание! Особенность работы контроллера с параметром delay. Значения анимируемых переменных в параметре to вычитываются контроллером без учета delay. Поэтому если на момент окончания задержки значения переменных изменились контроллер об этом не узнает. $Sector Рисует сектор используя flash.display.Graphics target объекта $Tooltip В общем случае, тултип – это элемент, который показывается надо всей остальной вёрсткой. Примеры: всплывающая подсказка: появляется при наведении мыши на некоторый блок, пропадает, когда мышь уходит. контекстное меню: появляется по клику на блоке, пропадает, если кликнуть на экране за пределами меню. Например, Элемент и аргументы Как реализуется: в блок включаем controller $Tooltip, задаём ему название элемента и аргументы для всплывающей подсказки: Положение Задаётся тип точки привязки ("position"): тултип прилипает к краю блока, и в дальнейшем следит за положением блока, тултип прилипает к краю блока и так и стоит в этой точке (даже если блок уехал) тултип едет за мышью, тултип появляется в той позиции, где была мышь на момент его появления, и потом там стоит. Потом – выравнивание ("align") и сдвиг ("offset") относительно этой точки, и минимальное расстояние до границы экрана ("screenBoundsOffset"). Если тултип подъезжает к границе экрана (с учетом "screenBoundsOffset"), то он упрётся в эту границу и не будет смещаться... при условии, если он не перекроет точку приязки. То есть, если тултип имеет выравнивание "outerLeft|bottom" (слева и снизу от точки привязки) – то при приближении к нижней границе экрана он может в неё упереться – и не перекрыть точку. А вот при выравнивании "innerLeft|outerBottom" (под точкой привязки, у левого её края) тултип не может просто упереться в нижний край: точка привязки будет перекрыта. Поэтому он "перепрыгивает" на противоположную сторону от точки привязки, т.е. меняет выравнивание на "innerRight|outerBottom". Пины тултипа (см. ниже) при этом тоже поменяются. Примеры "упирания" и "перепрыгивания" см. Sandbox/Unbound2/TooltipSamples. Пины Также тултип может иметь пины (стрелочки от края тултипа к точке привязки); нужный пин (левый, правый, верхний или нижний) выбирается автоматически. Правда, с пинами есть сложности, на них не работают отступы (маржины и паддинги). Если нужен отступ – то приходится добавлять в пин фон нужного размера с прозрачной заливкой (например, цветом 0x00000001). А отрицательный отступ (т.е. наложение стрелочки на тело тултипа) и вовсе можно задать только с помощью параметра pinOffset. Другой способ сделать "пины" – это подписать элемент тултипа на событие evPinPositionChanged, и переключать подложку в зависимости от того, какую стрелочку нужно показать. Это работает надёжнее и даёт больше контроля, чем задание стрелочек в отдельных элементах. Появление/пропадание и анимация Здесь указываем, по каким событиям и с какой анимацией тултип появляется и пропадает. Анмация настраивается так же, как в controller $Animation. События Контроллер тултипа бросает события при появлении, исчезновении, или клике за пределами тултипа. Те же самые события могут направляться не только контроллеру тултипа, но и его элементу (renderer'у). Для этого события с таким же именами нужно вручную определить в скоупе рендерера; контроллер их там найдёт (так же, как прописывается событие evPinPositionChanged – см. выше). scroll_bar Элементы полосы прокрутки Полоса прокрутки состоит из 4 элементов: "трэка", по которому перемещается "тумб", и кнопок слева и справа от "трэка": (scroll_bar ... (btn_decr = 'имя элемента') (track = 'имя элемента') (thumb = 'имя элемента') (btn_incr = 'имя элемента') ... ) "Тумб" можно подцеплять мышкой и тащить, кнопки можно нажимать (сдвиг на одну "строчку" влево или вправо), на "трэк" тоже можно нажимать ("тумб" приедет в ту точку, на которую нажали). Каждый из 4 элементов в простейшем случае может быть просто закрашенным блоком с заданной высотой и шириной (но трэк и тумб автоматически растянутся под размер и диапазон области прокрутки). Можно прописать автоматическое изменение стиля элемента при наведении мыши и при нажатии. Для этого прописываем четыре стиля: собираем их в dict, (def constant SB_LEFT_BTN { up : 'SBLeftBtnUpStyle', over : 'SBLeftBtnHoverStyle', down : 'SBLeftBtnPressStyle', disabled : 'SBLeftBtnDisabledStyle' } ) и подписываем элемент на событие stateChanged: (def element SBLeftBtn() layout=true (style (width = 12px) (height = 13px) ) (bind class "SB_LEFT_BTN[$event.state]" init=false on='stateChanged') ) а потом подсовываем этот элемент в scroll_bar: (scroll_bar (btn_decr = 'SBLeftBtn') ... Имейте в виду, что какой-то элемент должен ловить события мыши – то он должен быть залит каким-то цветом или изображением (а вот альфу ему можно поставить в 0). Т.е., если нужно сделать прозрачный трэк – то ему всё равно надо указывать непрозрачную заливку, а потом писать (alpha=0). Параметры и события полосы прокрутки Когда scroll_bar работает в составе scrollArea, задавать надо только orientation, прочие параметры устанавливаются автоматически (и на события scrollArea тоже сама подписывается). Кстати, если поставить параметр alignThumbToBorders в false и не задавать btn_decr и btn_incr (задать только трэк и тумб) – то получится слайдер. scrollArea Область, которая умеет показывать контент бОльшего размера, и прокручивать его. Область прокрутки можно двигать колёсиком мыши (если зажать шифт – то по горизонтали); но scroll_bar для этого всё равно должен быть задан, т.к. именно он отвечает за параметры прокрутки и скорость анимации. Тени и анимация области прокрутки Можно задать четыре тени, и настроить анимацию при появлении/пропадании теней и при наведении мыши на область прокрутки: Методы для прокрутки Динамическая прокрутка Если в content поместить controller $Repeat, то контроллер может создавать свои элементы динамически, по мере того, как scrollArea прокручивает до них. Для этого контроллеру надо указать, какие размеры имеют его элементы:
  4. Конструкции языка разметки Constant Константы имеют такое же назначение, как и в других языках, и служат для хранения неизменяемых значений. В unbound можно использовать 2 типа constant: Глобальные констатнты Для объявления глобальной константы используется функция (def. В поле аргумента передается содержимое, которое может принимать переменная при объявлении. # объявление (def constant C_ALLY 0xFF80c0ff) ... # использование (style (width = "32px") (height = "32px") (backgroundColor = "C_ALLY") ) Локальные константыЭти константы объявляются в scope element и могут быть использованы только в element'е.
  5. Декларативный язык разметки и S-выражения Верстка состоит из S-выражений. Существует 4 вида s-выражения, каждый из которых предназначен для конкретного действия: Call method (<method name> <positional argument value>* <named argument>* <nested s-expression>+ ) <named argument> := <argument name> = <argument value> (bind isEnabled "$event.enabled" init=false (event "isEnableChanged") ) bind - <method name> isEnabled, "$event.enabled" - <positional argument value>* init=false - <named argument>* (event "isEnableChanged") - <nested s-expression>+ Add definition (def <definition type> <difinition name> (<declaration argument>*) <named argument>* <nested s-expression>+ ) <declaration argument> := <argument name> : <argument type> [ = <default value> ] <named argument> := <argument name> = <argument value> По сути является частным случаем s-выражения-метода и введен только ради особого синтаксиса декларации параметров. (def element TestView(name:str = '', count:number) layout=true (block ) ) задать значение свойства (<property name> = <property value>) (style (width = 100px) ) (tf (text = 'Hello world!') ) взять значение свойства (.<property name> <nested s-expression>+ ) (.graphics (lineStyle 1 0xffffdc84 1) (beginFill "0xff414141" "0") (drawRect 0 0 450 64) (endFill) ) На этих 4 типах выражений и строится вся разметка. Макросы Макрос - именованный параметризированный фрагмент верстки, который подставляется в место вызова на этапе парсинга. Макросы реализованы на уровне AST (Abstract syntax tree). Определение макроса: (def macro <macro name> (<declaration argument>*) <nested s-expression>+ ) <declaration argument> := <argument name> : <argument type> [ = <default value> ] (def macro StatusesVehicleTypes(width:number=100%, height:number=100%, renderer:str='VehicleTypeItem', name:str='statusesVehicleTypes') (element List "name" "renderer" "width" "height" (scope (containerFlow = "Flow.HORIZONTAL") (listVscrollPolicy = 'off') (listHscrollPolicy = 'off') ) ) ) Использовать макрос можно с помощью ключевого слова macro. (macro <macro name> <positional argument value>* <named argument>*) (macro StatusesVehicleTypes 160 height=32) Несмотря на то что это выглядит как обычный вызов метода, это не так. Подстановка макроса происходит на этапе парсинга. В определении макроса можно использовать макросы, определенные ранее. Подстановка происходит рекурсивно. (def macro ComponentStateBase (statesDict:expression) (macro ComponentStateBaseScope "statesDict") (macro ComponentStateBaseContent) ) Исполнение верстки Движок, исполняющий верстку, максимально абстрагирован от каких-либо конкретных функциональностей. В нем нет знания о спрайтах, скоупах и т д. Здесь есть такое понятие, как таргет-объект. Это текущий объект, над которым выполняются действия, описанные s-выражениями. S-выражения различаются по типам (метод, сеттер, геттер) и не более (даже definition на этом уровне будет просто методом). Первое исполнение верстки происходит после загрузки текста файла в фреймворк. После парсинга файла - мы имеем список s-выражений, которые содержатся в файле (как правило, это дефенишины, задания глобальных констант). Для исполнения этого списка s-выражений создается фейковый объект (хотя по факту этим методам он не нужен). Другим частым случаем запуска движка на исполнение списка s-выражений является построение дефинишина, здесь создается соответствующий дефинишину объект и s-выражения, которые содержатся в теле дефинишина, исполняются над ним. По ходу исполнения s-выражений таргет-объект меняется. Это происходит при исполнении вложенных s-выражений, для них таргет-объектом будет объект, который вернуло родительское s-выражение. Если s-выражение ничего не вернуло или вернуло не объект, то вложенные s-выражения исполняться не будут. Возвращать значения (в том числе объекты) могут методы и геттеры. На примере подробно расписано, как меняется таргет-объект: Типы данных В верстке введена строгая типизация (параметры definitions, свойства скоупа), проверка типов происходит на этапе исполнения (кроме макросов, для них на этапе подстановки, т е на этапе парсинга) Введение типизации позволяет лучше контролировать ошибки. тип описание синтаксис комментарии number number 12.34 для типа number можно уточнить единицы percent 12.34% pixels 12px bool boolean expression true / false str string 'text123' single quotes dict dictionary {a : 1, b: 2} array array [1, 2, 3] expression вычиляемое выражение "a ? 1 : 2" в двойных кавычках константа не может быть определена внутри выражения gfx указатель на любой GFx::Value нет константа не может быть определена в верстке и в выражениях cpp сложный объект, такой как коллекции или сущность нет Примечание: Важной особенностью при работе со строковыми литералами и переменными является то, что одинарные кавычки можно не использовать, т.к. парсер при разборе интерпретирует значения как строку. Поэтому существует двойственность при объявлении строковых переменных. Эта особенность проявляется и при использовании bindings конструкций (bind, bindcall, sync, dispatch), например: # Dispatch события evBtnUpEvent (dispatch evBtnUpEvent on=mouseUp) Первым аргументом toplevel функция dispatch ожидает строку, но явно обозначать, что это строка, не требуется. Enums В выражениях можно использовать перечисления, которые заданы в core c++ части Unbound. enum name свойства описание пример комментарии Flow HORIZONTAL VERTICAL - значение по умолчанию TILE_HORIZONTAL TILE_VERTICAL REVERSE_HORIZONTAL REVERSE_VERTICAL Свойства определяют то, как будут выстраиваться вложенные display objects. (block (style (flow = "Flow.HORISONTAL") ) ) # Эквивалент записи выше (hblock ) Для block с выставленным в стиле свойством flow существуют алиасы: block - вертикальный блок hblock - горизонтальный блок vtile - вертикальный tile блок htile - горизонтальный tile блок reverse - вертикальный блок с обратным порядком элементов в блоке hreverse - горизонтальный блок с обратным порядком элементов в блоке У block параметр flow = Flow.VERTICAL Easing line elastic_in elastic_out bounce_in bounce_out back_in back_out cubic_in cubic_out quint_in quint_out expo_in expo_out expo_in_out sine_in sine_out sine_in_out Types of easing for animation. (controller $Animation (play duration=0.3 to={alpha:0} easing="Easing.cubic_out") )
  6. Базовая функциональность Базовая функциональность определяет базовые возможности фреймворка: формирование сцены (создание и добавление sprites, textfields, symbols, blocks) scope, bindings system построение definitions - element, css, animation, macro, constant. holders глобальных данных (enums, глобальные константы, глобальные указатели на объекты, глобальные методы) Build stage Дисплей обджект (DO) - это общее наименование всех экранных объектов. Они отоборажаются по списку (дисплей лист) в порядке вызова, в координатах [х:0;у:0]. Наполнение и отображение, а так же набор свойств у разных диспл.обдж разный. Основной возможностью языка разметки unbound является создание, конфигурация и добавление instance of display objects (DO) в соответствующий target-объект в display list'е . Target-объектом является родительский DO для текущего фрагмента верстки Все DOs разделяются на 2 группы по наличию/отсутствию layout system. Layout system отвечает за позиционирование DO на сцене. (block (tf ) ) где нода block является target-объектом для DO tf. Display objects list методы верхнего уровня описание sprite Создание экземпляра Sprite symbol Создание экземпляра Symbol (MovieClip or Sprite) по имени из библиотеки tf Создание экземпляра текстового блока TextField element Создание экземпляра элемента описанного в верстке block Создает дочерний DO Для всех отображаемых объектов доступны некоторые свойства, такие как: Название свойства Описание Формат height высота объекта в px или % :number width ширина объекта в px или % :number x позиция по оси X в px или % :number y позиция по оси Y в px или % :number scaleX горизонтальный множитель :number scaleY вертикальный множитель :number alpha прозрачность объекта от 0 до 1 :number rotation поворот в градусах :number Пример создания Sprite размером 500x500px с координатами [x=100; y=200] и прозрачностью 50% (sprite (width = 500) (height = 500) (x = 100px) (y = 200px) (scaleX = 2) (alpha = 0.5) (rotation = 45) ) Определение элемента Верхнеуровневым DO верстки является element. Element – именованный параметризированный фрагмент верстки на базе спрайта. Element может иметь Scope, который содержит данные, доступные в теле element. Работа с элементом разделяется на 2 стадии: definition и create instance. Для определения элемента используется метод def. (def element CommanderPersonalInfo() layout=true ) Создание экземпляра: (element CommanderPersonalInfo) Scope Scope - это хранилище данных и событий, доступных в теле определения элемента. Scope может иметь только Element, остальные DO могут работать только со scope родительского Element. В scope должны быть объявлены все переменные и события, которые используются в теле element. Попытка обращения к несуществующему свойству или событию вызывает ошибку: access of undefined scope event 'nameEvent' методы верхнего уровня описание scope Метод возвращает scope элемента для дальнейшей работы. (scope (var lvlVal:str = '') (var title:str = '') (var cost:str = '') (var text:str = '') (var lvlTextColor:number = 0xffcac8c1) (var imageUrl:str = '') ) Байндинги Общее описание Байндинги отвечают за простую синхронизацию данных (свойство, вызов метода, диспатч события). Существует три элемента синхронизации свойство вызов метода событие Для своей работы байндинги делают снимок данных исполнения и используют этот снимок при вычислении выражений, чтобы в этих выражениях были доступны все данные, которые были доступны на момент инициализации байндинга. методы верхнего уровня описание scope -> object bind запись значения в свойство объекта bindcall вызов метода у объекта object -> scope sync значение переменной в scope-е синхронизируется с значением свойства объекта dispatch событие в scope-е синхронизируется с событием у объекта (диспатчится событие в scope-е по событию от объекта) Все байндинги имеют общие свойства: watch - следить ли за изменением значения свойств scope-а, которые используются в выражениях init - производить ли действие (соответствующее типу байндинга) при инициализации байндинга on - событие target-объекта, по которому будет срабатывать байндинг enabled - можно использовать для включения и выключения срабатывания, может принимать выражения типа (enabled = "$event.buttonIdx == 1") и общие методы: event - добавляет произвольное событие в качестве триггера к байндингу Bind Синтаксис: (bind scopeVar|property "scopeVar|$target|$event.field" [init=false|true] [watch=false|true] [on='scopeEventName|flashEventName|cppEventName']|[(event "scopeEventName")] [(enabled "expression")]), по-умолчанию init=true watch=true Синхронизировать можно как переменную из scope, так и свойство target-объекта. Для синхронизирования переменной из scope, bind нужно поместить в scope. (scope (var count:number = 30) (var total:number = 100) (var percent:number = 0) (bind percent "count / total") ) Для синхронизации свойства target-объекта, bind должен вызываться в target-объекте, свойство которого мы синхронизируем. (scope (var vehicleType:str = 'vehicleHeavy') ) (tf (bind text "vehicleType") ) В обоих случаях изменение любой переменной из выражения приводит к его вычислению, а результат записывается в синхронизируемую переменную или свойство. Управлять этим поведением можно через параметр watch=true|false. Второй способ вызвать синхронизирование выражения - подписаться на событие. Поддерживается 2 способа для подписки на событие Передать в аргумент on имя ивента как строку. Используется для подписки на флешовые события или события, которые распространяются из core c++. Если в этом ивенте есть аргументы, к ним можно получить доступ через объект $event. На момент выполнения выражения в bind все переменные должны уже быть известны. Но в $event аргументы попадут, если распространится событие. Так как события никакого еще не было, но на старте $event не определен, для этого у всех типов биндингов существует параметр init=true|false, которое позволяет настроить выполнение выражения при инициализации. (tf (class GrandTitleTextStyle) (text = 'default text') (bind text "$event.localX" init=false on='click') ) Передавать из scope объект event (scope (event onCustomEvent) ) (tf (bind text "$event.localY" (event "onCustomEvent")) (dispatch onCustomEvent on='click') ) Примечание: Подписаться на событие конкретного экземпляра элемента можно в его скоупе. Тогда передавать event нужно с использованием аргумента on. Пример: (element ButtonPrimary (scope (bind label "$event.localX+ $event.localY" init=false on='evBtnLeftClickEvent') ) ) Управлять исполнением синхронизации можно через вложенную конструкцию enabled, которая принимает выражение, результатом которого должно быть булевское значение. В свою очередь, если требуется подписать изменение enabled на event или выражение, нужно использовать bind. Инкрементальный счетчик по событию Параметры watch= и init= блока bind : watch - подписывать или нет на событие изменения переменных в выражении init - производить ли рассчет выражения при создании переменной (def element TestElement() layout=true (scope (var counter:number = 100) (bind counter "counter-10" watch=false init=false (event "evMouseClick")) #при watch=false возможно вычисление по событию ) (style (backgroundColor = 0xFF00FF00) (width = 200) (height = 100) ) (macro trace "counter") ) Bindcall Синтаксис: (bindcall functionName "scopeVar|$target"* [init=false|true] [watch=false|true] [on='scopeEventName|flashEventName|cppEventName']|[(event "scopeEventName")] [(enabled "expression")]), по умолчанию init=false watch=true Используется для вызова метода у target-объекта по условиям (событие, изменение аргумента). Пример использования при подписке вызов метода у DO: (mc 'CloseBtnCrossAnim' (bindcall gotoAndPlay "stateFrame") ) Таким образом, при изменении переменной stateFrame будет вызван метод gotoAndPlay. Другой пример - вызов методов у контроллеров: (controller $Animation (bindcall play duration=0.2 from={alpha:0} to={alpha:0.5} (event "evBtnOverEvent") (bind enabled "_isPressed")) ) Поведение параметров event, enabled такое же, как у конструкции bind. Dispatch Синтаксис: (dispatch scopeEventName delay=0.1 on='flashEventName|scopeEventName|cppEventName'|[(event "scopeEventName")] [args="{key1: value1, ...}"] [dir=0|1|2] [(enabled "expression")]), по умолчанию dir=0 Рассылка события по событию, которое генерируется scaleform или core c++ unbound. Перед тем как рассылать событие, его нужно объявить в scope. (scope (event onClick) ) (dispatch onClick on='click') Передача аргументов При рассылке события можно передавать аргументы. Аргументы передаются как dict. По умолчанию если не задан параметр args, то все свойства исходного event'a (тот ивент, который выступает тригером) передаются в рассылаемый event. (scope (event onClick) ) (element ButtonPrimary (dispatch onClick on='click') ) (trace "$event" init=false (event "onClick")) Результат в ub_player_errors.log: ======================================================================== ------------------------------------------- UBTRACE: {altKey:false,bubbles:true,buttonDown:false,buttonIdx:0,cancelable:false,clickCount:0,commandKey:false,controlKey:false,ctrlKey:false,currentTarget:°FЧ',delta:0,eventPhase:2,localX:41,localY:18,mouseIdx:0,nestingIdx:0,relatedObject:[null],shiftKey:false,stageX:41,stageY:18,target:°FЧ',type:click} Если же передать аргументы, то передача свойств исходного ивента не происходит. Задержка рассылки события Для решения вопросов отложенной рассылки события необходимо добавить параметр delay (scope (event onClick) (var argument:number = 100) ) (element ButtonPrimary (dispatch onClick delay=0.15 args="{param: argument}" on='click') ) (macro eventChecker "onClick") (trace "$event" init=false (event "onClick")) Результат в ub_player_errors.log: ======================================================================== ------------------------------------------- UBTRACE: {param:100} Направление распространения события Направлением распространения event можно управлять параметром dir. Поддерживаются 3 значения: 0 - event распространяется внутри element. По умолчанию dir=0. 1 - event распространяется от ребенка к родителю. Примечание: Важно помнить о том, что прежде чем использовать event, он должен быть объявлен в scope. Даже несмотря на то, что в scope определении element ChildElement event уже объявлен, его нужно также объявить и в TestView. 2 - event распространяется от родителя к ребенку. Разделение событий В приведенных примерах вложенный элемент распространяет событие и на сцене в родителе был только один экземпляр. Но часто бывают случаи, когда несколько одинаковых элементов лежат на одном уровне вложенности. Тогда отличить, от кого именно пришло событие, будет сложно. Рассмотрим пример: на сцене 4 экземпляра ChildElement, и каждый из них распространяет событие onClick. Текстовый блок будет ловить события от каждого элемента. Конечно, можно проверять id кнопки в выражении bind. Но также для этого можно передиспатчивать события из scope вложенного элемента в уникальное событие родителя. Т.е. событие onClickChild1 синхронизируется с событием onClick только у кнопки с id=0, поэтому поле text у текстового блока будет обновляться только при клике на эту кнопку. Dispatch при enabled=true Не срабатывает событие при переключении enabled в true, но продолжает срабатывать при переключении trigger в true. Dispatch property change event Побочным результатом изменений в dispatch стал контроль за событием изменения выражения (dispatch evUpdateMouse (bind enabled "isActive") (bind trigger "isActive")) При таком порядке биндингов сначала пересчитается enabled и событие сработает только при isActive=true. Контроллеры Сontroller - это атомарная функциональность над target-объектом. Позволяет расширить функционал за счет выполнения кастомной логики над объектом. Controller реализуется на С++. методы верхнего уровня описание controller Метод возвращает style текущего DO для дальнейшей работы (controller $Animation (play duration=0.2 to="{ alpha:(isMouseOver ? 1.0 : 0.0), visible:(isMouseOver ? true : false) }") ) Стилизация display object. Elements и blocks имеют Style, что позволяет настраиваить их визуальное представление, например, изменять размеры, накладывать фильтры и т.д. top-level methods style Метод возвращает style текущего DO для дальнейшей работы У каждого блока свой набор пропертей style. Так, например, блоку tf можно задавать font, size и color. (tf (style (fontFamily = $TitleFont) (fontSize = 36) (textColor = 0xf5eed5) ) ) Также через изменение свойств style: paddings, margins, position, flow и т.п, - можно управлять позиционированием блока. (block (style (position = "absolute") (bottom = 18px) (paddingLeft = 24px) (paddingRight = 24px) ) ) Style обладают только объекты с layout-system, а именно element с параметром layout=true и различного рода блоки, унаследованные от BaseBlock в c++. Обращение к свойством style у DO без layout system приводит к ошибке: access of undefined method 'style' through a reference with type element
  7. Модификация – файл или совокупность файлов, относящихся к проекту WOWS, взаимодействующие прямо или опосредованно с клиентом игры (файлами клиента), и/или каким-либо образом изменяющие его поведение. Правила публикации модификаций: Все публикации и содержание модификаций должны соответствовать основным правилам форума и правилам раздела модификаций. Публикации проверяются администрацией раздела в срок от одного до трех дней. Если по истечении трех дней публикация не была одобрена и не были предъявлены замечания для устранения, автору публикации необходимо связаться с администрацией раздела в ЛС форума. Модификация должна относится к проекту WOWS. Модификация должна соответствовать описанию. Опубликованная модификация должна соответствовать текущей версии клиента игры. Публикации, имеющие спорные или пограничные моменты, разрешаются по усмотрению администрацией форума. Если замечания к публикации не будут устранены в течение 7 дней, то такая публикация будет перемещена в раздел архива модификаций. В названии публикации необходимо указывать версию совместимости с клиентом и название модификации (например: [0.8.0.0] My SuperMod), если модификация не зависит от версии клиента игры, то указывается [ALL]. Публикация модификации другого автора может быть только по согласованию с самим автором модификации. В этом случае автор модификации должен сообщить со своего основного аккаунта в ЛС администратору раздела (MatroseFuchs) о своем согласии. Содержание публикации: Обязательно: Описание модификации. Ссылка для скачивания на файловое хранилище (Google Drive, Yandex.Disk, Cloud.Mail, Dropbox и т.д.). Инструкция по установке в описании публикации или в архиве модификации. При публикации модификации другого автора, в описании указывается автор такой модификации. Интерфейсные и графические модификации в описании должны содержать скриншоты (не более трех) отражающие суть модификации. При наличии особенностей и любой другой важной информации при использовании модификации, информация об этом должна быть добавлена в описание и выделена. По желанию автора публикации: Дополнительные изображения и видеозаписи добавляемые для описания модификации должны быть скрыты в спойлерах. Автор модификации может в своей теме указать свои веб-кошельки/счета для того, чтобы пользователи могли добровольно поддержать автора любой доступной для них суммой. Рекомендуется в теме публиковать скриншот результата проверки с VirusTotal Модификация должна распространяться бесплатно, продажа модификаций запрещена. Модификация публикуется в соответствующем ей разделе (см. ниже). С выходом очередного обновления клиента игры, модификация, при необходимости, должна быть обновлена до текущей версии игры в течение трех дней с момента выхода обновления клиента, в противном случае модификация будет перемещена в раздел архива модификаций до момента обновления её до актуальной версии клиента. После обновления модификации, в заголовке публикации должна быть изменена версия клиента на актуальную. После того как модификация, находящаяся в разделе архива модификаций, была обновлена до актуальной версии игры, автору публикации необходимо написать администрации раздела модификаций (MatroseFuchs) для проверки. Администрация проекта придерживается политики невмешательства во взаимоотношения мододелов, однако при необходимости Администрация может принять окончательное решение в спорной ситуации, рассмотрев соответствующие аргументы каждой из сторон. Представитель Администрации проекта по решению спорных ситуаций - MedvedevTD. Запрещено публиковать, а также добавлять или изменять в существующих публикациях: Программы и модификации, которые помогают целиться способами, не предусмотренными в игре, например отображают маркеры упреждения. Программы (боты или скрипты), которые берут управление каким-либо аспектом игры на себя. Программы и модификации, которые как-либо работают с файлом клиента игры scripts.zip или заменяют его. Материалы содержащие изображения или видеозаписи обнаженных натур, эротического или порнографического характера. Материалы, содержащие немецкую нацистскую (фашистскую) символику. Ссылки на сторонние ресурсы, за исключением ссылки на файловое хранилище для скачивания модификации и фан-сайты, в соответствии с основными правилами форума, в данном подразделе и на форуме запрещены. Ссылки на сайты, которые не вошли в список фан-сайтов, будут удаляться. Администрация форума оставляет за собой право не одобрять (запрещать) публикации по своему усмотрению.
  8. Цвета Ограниченная палитра специальных цветов используется в игре для текстов и иконографики: В общем случае, цвета можно выбирать из палитры так называемых безопасных Web-цветов:
  9. MatroseFuchs

    💬 Обсуждение ModAPI

    На основном предварительно 0.8.1 или 0.8.2, насчет ПТ не обещаю.
  10. MatroseFuchs

    💬 Обсуждение ModAPI

    пополним в одном из обновлений
  11. MatroseFuchs

    [ModAPI] Документация

    FlashAPI - StageModule Методы "StageModule" предоставляют возможность работать со сценой "Stage". Доступные методы: gameAPI.stage gameAPI.stage.addChild(child:displayObject) gameAPI.stage.addChildAt(child:displayObject, index:int) gameAPI.stage.removeChild(child:displayObject) gameAPI.stage.removeChildAt(index:int) gameAPI.stage.width() gameAPI.stage.height() gameAPI.stage.addChild(child:displayObject) Работает аналогично методу "addChild", добавляет экземпляр "displayObject" на сцену "Stage" для визуализации объекта. Входной аргумент "child" - создаваемый графический объект Flash-а. gameAPI.stage.addChildAt(child:displayObject, index:int) Аналогично методу "addChildAt", добавляет DispalyObject на определенный слой Stage'a. Входные аргументы: "child" - создаваемый графический объект Flash-а; index - порядковый номер слоя, на который должен быть добавлен DisplayObject. gameAPI.stage.removeChild(child:displayObject) Метод удаляет DispalyObject со Stage. Входной аргумент "child" - DisplayObject, который должен быть удален со Stage. gameAPI.stage.removeChildAt(index:int) Метод удаляет выбранный слой со Stage. Входной аргумент "index" - порядковый номер слоя, с которого должен быть удален DisplayObject. gameAPI.stage.width() Метод возвращает ширину сцены Stage. Возвращаемое значение имеет тип данных "Number". gameAPI.stage.height() Метод возвращает высоту Stage Возвращаемое значение имеет тип данных "Number".
  12. Типографика Шрифт Основной шрифт, используемый в игре, это Warhelios Condensed. Он бывает в двух начертаниях — обычном (WarheliosCondC) и жирном (WarheliosCondCBold). Правила использования Следует избегать использование своих стилей текста, и вместо этого использовать готовые стилевые классы: Класс Для чего используется $TextDefault13NM второстепенный (вспомогательный) текст $TextDefault15NM основной класс, используйте его в большинстве случаев $TextDefault17NM заголовки 4 уровня $TextDefault19NM заголовки 3 уровня $TextDefault21NM заголовки 2 уровня $TextDefault23NM заголовки 1 уровня $TextDefaultBoldNM имя корабля и его уровень, шапки таблиц, заголовки разворачиваемых списков, заголовки групп характеристик $TextDefaultBold17NM заголовки параграфов $TextDefaultBold19NM заголовки 3 уровня повышенной значимости $TextDefaultBold21NM заголовки 2 уровня повышенной значимости $TextDefaultBold23NM заголовки 1 уровня повышенной значимости, заголовки окон Пример стилизации текста Исходный текст: <block type="text""> <bind name="text" value="'Hello, world!'"/> # этот текст будет чёрного текста и в гарнитуре Arial </block> Теперь добавим стандартный стилевой класс, использующий белый цвет по умолчанию: <block type="text""> <styleClass value="$TextDefaultNM/> # теперь текст стал белым, с кеглем 15px, в гарнитуре Warhelios Condensed <bind name="text" value="'Hello, world!'"/> </block> Теперь поменяем текст, переопределив текст из класса своим, добавив атрибут (textColor) в блок (style): <block type="text""> <styleClass value="$TextDefaultNM/> <style> <textColor value="0xFFCC66"/> # золотистый цвет премиумных кораблей </style> <bind name="text" value="'Hello, world!'"/> </block>
  13. Стили Облик элемента задаётся набором атомарных стилевых свойств, таких как высота, ширина, цвет, расположение и так далее. Отдельные стилевые свойства можно объединять в стилевые классы class — стилевой класс; style — выражение, задающее стиль элемента в конкретно этом блоке (так называемый inline-стиль) через перечисление стилевых свойств. атомарные стилевые свойства, По аналогии с HTML, применяется то стилевое свойство, которое применено к элементу последним:
  14. Блоки Элемент — это независимый корневой блок самого верхнего уровня, внутри которого задаются остальные дочерние блоки. Пример описания корневого блока в XML файле: <block className="SomeClassName"> Объявление элемента нужно в двух случаях: Когда мы хотим создать новое окно; Когда мы хотим создать новый элемент, который будет использоваться в любом существующем окне. При этом, элемент может создаваться как динамически (на основе выполнения логических условий), так и статически. Пример динамического появления блока — кнопка «Забрать награду» в календаре: Дочерние блоки бывают следующих типов: block — спрайтовый блок; <block> ... </block> tf — текстоый блок; <block type="text"> mc — блок типа Movie Clip, определённый в каком-либо флэшовом *.fla-файле и экспортированный в ActionScript; <block className="some_class_name" type="native"> Если выполнить код выше, то на экране мы ничего не увидим, потому что по умолчанию блоки создаются без цветовой заливки, с нулевой высотой и шириной. Для управления их обликом как раз и используются стили, о них речь ниже.
  15. Список поддерживаемых событий (events) для мыши Unbound поддерживает лишь часть мышиных событий из ActionScript 3.0. Пример: (bind dispatch "'click'; 'eventName'; {}") событие описание click Щелчок левой кнопкой мыши mouseDown Срабатывает в момент нажатия левой кнопки мыши mouseUp Срабатывает в момент отпускания левой кнопки мыши mouseWheel Прокрутка колёсика мыши в любом направлении mouseOver Наведение указателя на элемент mouseOut Срабатывает в момент ухода указателя мыши с элемента mouseMove Срабатывает в момент движения указателя над элементом rollOver Аналогично mouseOver, но не сработает над дочерними элементами rollOut Аналогично mouseOut, но не сработает над дочерними элементами Примечание В ActionScript есть разница между mouseOver/rollOver и mouseOut/rollOut, в Unbound она сохраняется. Это значит, что событие mouseOver сработает как над родителем, так и над детьми, в отличие от rollOver, который сработает один раз над родителем и не сработает над детьми.
  16. Список байндингов DataHub 2.0 DHCollectionRepeatBinding DHCollectionGeneratorBinding DHCollectionBinding DHEntityBinding DHHandleEventBinding DHWatchBinding DHDataRefBinding
  17. Список доступных байндингов UbChildBinding UbInstanceBinding UbEventBinding UbSyncBinding UbRepeatBinding UbGeneratorBinding UbDraggableBinding UbClikListBinding UbStyleBinding UbStyleClassBinding UbAppearBinding UbTransitionBinding UbTooltipBinding UbSequenceBinding UbPropertyBinding UBVariablesBinding UbCatchEventBinding UbDispatchBinding UbDispatchDelayResetBinding UbChangeDispatchBinding UbCountdownBinding UbClockBinding UbContainsBinding UbFileBinding UbEventSequenceBinding UbTimeFormatBinding UbRestrictFeedbackBinding UbIndexOfBinding UBAccountLevelBinding SFMRequestBinding и SFMActionBinding FocusBinding InputMappingBinding UbSubstituteBinding UbSubstituteBinding DesignerCollectionBinding ConcatBinding ClipboardBinding ColorTransformBinding SliceBinding ResourceBinding entityDH firstEntityDH primaryEntityDH DHCollectionGeneratorBinding GSTimelineBinding WowsResizeBinding UbPluralTextBinding UbContextMenuBinding UbWatchBinding ActionIsDisplayBinding UbRepeatWithScopeHoldBinding UBServerTimeBinding UbFeatureCheckBinding UbGeneratorBinding UbInOutActionBinding UbIMEEnableBinding UbFadeBinding UbBlurLayerBinding, UbBlurMapBinding UbStageSizeBinding UBClickSplitBinding UbLinearChartBinding
  18. Всем привет! От лица нашей команды, выражаем благодарность мододелам проекта, за участие в разработке модификаций для игры World of Warships. На сегодняшний день мододелы - это уже сложившееся отдельное сообщество активных и инициативных людей, которые постоянно разрабатывают новые и совершенствуют существующие модификации, стремясь сделать игровой процесс более удобным и интересным. Сообщество постоянно растет и развивается, появляются новые идеи для модификаций, и мы в свою очередь стараемся развивать и совершенствовать инструментарий для реализации Ваших идей. В качестве благодарности мы подготовили для мододелов специальные нашивки и эмблемы: Поздравляем с этим замечательным событием, желаем новых оригинальных идей и надеемся на дальнейшее плодотворное сотрудничество! С уважением
  19. MatroseFuchs

    💬 Обсуждение ModAPI

    Спасибо что обратили внимание, ссылку добавил в документацию, на всякий случай дублирую еще тут https://drive.google.com/drive/folders/14VCPM7mOQGCq1MrvSVdv6r2wZoOP8Kfp. Свежая библиотека будет добавлена туда позже.
  20. MatroseFuchs

    💬 Обсуждение ModAPI

    Приветствую, уважаемые мододелы! В связи с необходимостью доработки, доступ к игровым константам был перенесен на версию 7.12. Доступ реализован в небольшом меню разработчика, которое будет вызываться сочетанием клавиш. Меню имеет две кнопки для показа констант и перезагрузки мода. Полное описание будет добавлено в документацию ModAPI с выходом обновления.
  21. MatroseFuchs

    💬 Обсуждение ModAPI

    Приветствую, уважаемые! Документация по ModAPI была обновлена, добавлены описания, новые методы и разделы, так же обновлена инструкция по созданию модов. Аналогичные темы на Европейском, Американском и Азиатском форумах будут обновлены немного позднее.
  22. Взаимодействие Python и Flash Возьмем наш мод "Hello World!" и посмотрим как взаимодействуют Python и Flash части мода: Дадим некоторые пояснения: Наш мод состоит из двух файлов - Main.py и Main.swf (скомпилированный файл из нашего проекта ".as"). Т.к. наш мод уже имеет и Flash часть, то и второй файл (Main.swf) мы так же добавим в папку с модом(!), где уже лежит Main.py. В Main.py создадим обработчик событий "events.onFlashReady", который сообщит нам что загрузился Flash файл и в него можно передать информацию. Теперь передадим строку "Hello World!" в Flash методом "flash.call". В это время Flash принимает наши данные методом "gameAPI.data.addCallBack" и передает в функцию-обработчик, которая была подписана на этот коллбэк. Далее функция-обработчик выводит сообщение на сцену, и вызывает методом "gameAPI.data.call" уже функцию в Python файле, но при этом никаких данных мы не передаем. Python файл получает вызов из Flash методом "flash.addExternalCallback", вызывает функцию-обработчик. И наконец функция-обработчик выводит сообщение об успешной работе в лог файл. Battle Mod Немного усложним задачу. Давайте попробуем изменить отображение какого-нибудь игрового эффекта, например изменим отображение получаемого нами урона от снарядов противника. Попробуем отобразить получаемый урон в другом месте, зададим другой цвет, размер шрифта и посмотрим что из этого получится. Комментарии к разработке: С помощью метода "battle.getPlayersInfo" получим ID нашего корабля. Метод "events.onReceiveShellInfo" сообщит нам о событии получения нашим кораблем урона и передаст информацию в функцию-обработчик. Далее функция-обработчик известным способом передаст информацию в Flash. И наконец Flash отобразит полученный урон так, как мы этого хотим. Как результат, мы получили мод, который отображает получаемый урон в заданном нами месте, имеет цвет и размер шрифта такой, какой мы хотим. В моде мы задали расположение сообщения выше центра, ярко-красным и оно отображается в течение трех секунд, если его не сменит другое сообщение. PS Данный мод является лишь идеей а не окончательным вариантом. Вы можете взять эту идею за основу для создания своего собственного мода и возможно именно Ваш мод войдет в официальный модпак. Удачи!
  23. Мод "HelloWorld" на FlashAPI Теперь создадим простой Flash мод. Откроем наш проект в редакторе (см. документацию) и немного доработаем скрипт: Скомпилируем файл проекта, и полученный файл "Main.swf" положим в папку с нашим модом. Запустим клиент игры и убедимся что наш мод работает.
  24. MatroseFuchs

    [ModAPI] Документация

    FlashAPI - DataBridgeModule Методы "Data Bridge Module" позволяют моду передавать или получать данные в/из Python части мода. Доступные методы: gameAPI.data gameAPI.data.call(methodName:String, params:Array):void gameAPI.data.addCallBack(methodName:String, func:Function):void gameAPI.data.removeCallBack(methodName:String = null, callBack:Function = null):void gameAPI.data.call(methodName:String, params:Array) Метод позволяет передать информацию в Python часть мода. Входные параметры: "methodName" - имя, ключ коллбэка, на который подписана функция в Python (в Python - falsh.addExternalCallback(name, func), где "name" соответствует "methodName") "params" - список (Array) передаваемых параметров. gameAPI.data.addCallBack(methodName:String, func:Function) Метод добавляет коллбэк для получения информации из Python'a (в Python - flash.call(name, args)), на который подписана функция во Flash. Входные параметры: "methodName" - имя, ключ коллбэка, на который подписана функция во Flash части мода (Main.swf-файл) "func" - функция-обработчик коллбэка gameAPI.data.removeCallBack(methodName:String = null, callBack:Function = null) Метод удаляет коллбэк, на который подписана функция во Flash. Входные параметры: "methodName" - имя, ключ коллбэка, на который подписана функция во Flash части мода (Main.swf-файл) "callBack" - функция-обработчик коллбэка
  25. MatroseFuchs

    [ModAPI] Документация

    FlashAPI Для создания Flash части мода нам потребуется редактор под ActionScript 3, подойдут такие как "FlashDevelop", "Adobe Flash Professional", "Adobe Flash Builder" и др. Создадим новый AS3 проект, главный файл назавем "Main", он будет иметь расширение "*.as", и в зависимости от выбранной IDE (редактора) добавим к проекту внешнюю SWC-библиотеку, актуальную версию которой можно будет взять из наших ресурсов. (пример добавления в Flash Builder) Далее в созданном проекте в файле "Main.as" доработаем скрипт для заготовки под наш мод. Теперь мы можем создать Flash часть мода. Как мы видим, наш главный класс имеет базовый класс "ModBase", который содержится в добавленной библиотеке, без этого класса наш Flash файл мода работать не будет.
×