Доступ к символу MainTimeline с помощью встраивания на уровне класса - PullRequest
2 голосов
/ 18 января 2012

Вот сценарий:

У нас есть творческая команда, которая работает во Flash CS5.5 и создает ресурсы SWF, в которых есть как графические элементы, так и код ActionScript, а также инженерная группа, которая создает файлы .as истроит "кодовые SWF".SWF-файлы кода должны загружать или встраивать творческие ресурсы и взаимодействовать с кодом в нем, чтобы наши приложения работали.

Для разработки на мобильных устройствах под iOS есть другое соображение - невозможно загрузить исполняемый код в AIRпакеты приложений для iOS из-за Apple TOS (см. связанный вопрос ).Следовательно, невозможно использовать Loader для загрузки SWF-файлов в среде iOS и сохранения их кода.

Встраивание SWF-файла в файл ActionScript стандартным способом приводит к загрузчику, который загружает встроенный SWF-файл непосредственно в байтах.,Это приводит к доступу к основной временной шкале верхнего уровня следующим образом:

[Embed(source="embed_test.swf")]
  private var no_aot_support:Class;

public function main():void
{
  var no_ios:* = new no_aot_support();
  addChild(no_ios);
  no_ios.addEventListener(Event.COMPLETE, function():void {
    var timeline:MovieClip = no_ios.getChildAt(0).getChildAt(0);
    trace(timeline.foo); // foo variable exists, output is 'blah'
  });
}

Однако этот механизм встраивания не работает на устройствах iOS, поскольку код выполнения не разрешен в соответствии с TOS Apple - весь код долженбыть пропущенным через опережающий компилятор (AOTCompiler) во время компиляции, и встроенный таким образом SWF-файл не соответствует этому критерию.

Обращаясь, я обнаружил , что одинможет использовать встраивание на уровне класса, чтобы обойти это, так как встраивание на уровне класса проходит через компилятор и приведет к рабочему коду под iOS:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf", symbol="Symbol1")]
   public final dynamic class anim extends MovieClip { };
}

Это работает нормально, но я неЯ хочу сослаться на символ в SWF, я хочу весь SWF (он же ссылка на основную временную шкалу), но следующие результаты приводят к ошибке компилятора:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf")]
   public final dynamic class anim extends MovieClip { };
}

Я также декомпилировал SWF, нашелосновной символ временной шкалы, и попробовал это:

package
{
  import flash.display.MovieClip;

  [Embed(source="embed_test.swf", symbol="embed_test_fla.MainTimeline")]
   public final dynamic class anim extends MovieClip { };
}

Но компилятор настаивает на том, что этот символ не существует.

Поскольку у меня много, много ресурсов SWF, мне нужно решение, которое неэто связано сзлиться на весь мой рабочий процесс (т.е. входить в каждый FLA и вносить изменения).Это должно быть возможно, а если нет, то это проблема рабочего процесса, которую должен решить Adobe.

Так что я застрял - обычные встраивания получают MainTimeline, но не работают в iOS, встраивания на уровне класса работают в iOSи не может получить доступ к MainTimeline.

Не стесняйтесь скачайте мой пример проекта и поиграйте с ним.

Ответы [ 2 ]

5 голосов
/ 19 января 2012

Размещение объектов на главной временной шкале всегда создает сгенерированный код в SWF-файле: Flash IDE генерирует весь необходимый код для запуска приложения, то есть создает экземпляр класса документа длябыть помещенным на сцену во время выполнения.Это, однако, код, к которому нельзя получить доступ, если SWF не загружен через объект загрузчика - ни использование [Embed], ни генерация SWC не позволят этого.

Я пытался экспортировать SWC, потому что, как @ 32bitkid, я считал, что это способ обойти ограничения.И, как выясняется, вы можете создать экземпляр класса документа, даже если вы явно не объявляете его и имеете IDE, автоматически генерирующим его.Но, увы, все инсценировки исчезли.:( Вы также можете объявить пользовательский класс документа и поместить объекты библиотеки на сцену, используя addChild() - тогда все будет работать нормально. Но все, что вы будете делать на главной временной шкале в IDE, вы не сможете получить к нему доступ. Когда-либо.

Это также имеет смысл: объекты на самом деле находятся на стадии экземпляров , размещенных на главной временной шкале экземпляре . Но как только вы вызываете new MyDocumentClass(), вы создаетеновый экземпляр, в котором еще нет членов.

Странно то, что все это должно быть верно для любых объектов библиотеки, а также для размещения экземпляров объектов в пределах временной шкалы объекта библиотеки также требуется кодгенерация, не так ли? - но на самом деле это совсем не одно и то же: все, что вы поместили на сцену в своем объекте библиотеки , все равно будет существовать и будет доступно, когда вы вызовете new MyLibraryObject();.

Итак. Единственный способ, которым я вижу, чтобы ваш проект работал, это чтобы ваши дизайнеры создавали MovieClip (или Sprite) с уникальным названием Timeline в библиотеке каждого FLA a.и экспортируйте это для ActionScript.(Вы не всегда можете использовать «Временную шкалу», потому что тогда у вас будут конфликты имен при работе с более чем одним SWC). Затем эта «Временная шкала» используется для размещения любых необходимых объектов непосредственно на сцене, добавления кода кадра и т. Д.В рамках этого проектировщики могут работать точно так, как они привыкли, без каких-либо ограничений, кроме аппаратного обеспечения устройства и доступного API.Единственная реальная разница в том, что ничто не может существовать на основной временной шкале самого FLA.

Затем вы можете использовать подход SWC (который намного менее утомителен, чем ручное создание кода [Embed]) и создать экземпляр символа «Хронология» из основного приложения - все должно быть там, где вам нужно.

0 голосов
/ 03 сентября 2012

Я публикую свой собственный способ решения этой проблемы, на случай, если что-то случится по этому вопросу:

Здесь есть более подробный ответ: Можно ли вставлять или загружать SWF-файлы при создании iphoneapps (Это разрешено Apple)

Я создал инструмент для решения этой проблемы путем объединения встроенных SWF-файлов в основной SWF-файл.Таким образом, встраивания AOT-компилируются и преобразуются в код target-c, поэтому я получаю экземпляр моего актива (основной временной шкалы), и код актива правильно кросс-компилируется для работы на устройствах iOS.

Он работает с использованием встраивания следующим образом:

[Embed(source="GameLevel.swf")]
  private var GameLevel:Class;

public function main():void
{
  var my_level:* = new GameLevel();
  addChild(my_level);
}

В этом сценарии, если в коде gameLevel.swf есть код, он, как правило, не будет работать в iOS, потому что новый gameLevel () создастЗагрузчик и интерпретировать байт-код SWF.Но если вы сначала запустите вышеуказанный SWF-файл через мой инструмент SWFMerge, он возьмет встроенный SWF-файл и объединит его с корневым SWF-файлом.Затем ADT скомпилирует ваш основной SWF-файл (включая встроенный код) в target-C, он будет работать на iOS и обратите внимание: новый gameLevel () теперь приводит непосредственно к экземпляру вашего ресурса - НЕ к загрузчику.

Инструмент SWFMerge находится здесь:

http://www.onetacoshort.com/temp/SWFMerge_alpha.swf

Дайте мне знать в комментариях, если этот обходной путь работает для вас или у вас есть проблемы.

Я добавлю, чтоиспользование рабочего процесса SWC лучше и официально поддерживается, но этот обходной путь очень полезен, когда у вас либо нет исходного исходного файла FLA, либо вы просто хотите быстро использовать существующие ресурсы с кодом в них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...