Как скопировать MovieClip в AS3, который содержится во внешнем SWF-файле, загруженном из эфирного приложения iOS?
У меня есть приложение для iOS для каталога, которое загружает ресурсы (без ActionScript) с удаленного сервера, поэтому редакторы каталога могут обновлять эти активы (каталог), чтобы каждый месяц создавать новые выпуски каталога.
Air для iOS позволяет загружать SWF-файлы без кода ActionScript. Поэтому я загружаю свои ресурсы из внешних SWF-файлов и успешно тестирую, компилируя в режимах Ad Hoc или App Store.
Некоторые из этих ресурсов представляют собой анимированные мувиклипы (с целочисленными мувиклипами, несколькими кадрами и анимацией движения), которые необходимо создать несколько раз (произвольное число раз) в приложении для интерактивной функции.
НЕКОТОРЫЙ ФОН:
- Стандартный способ создания повторяемых элементов - это присвоение им имени класса связывания в Flash IDE, которое отлично работает для настольных приложений, но, похоже, это интерпретируется как код iOS, поэтому оно не импортируется при загрузке ресурсов, поэтому элемент не может быть создан из приложения.
- Есть несколько попыток скопировать старую функцию as2 duplicateMovieClip, но они не дублируют внутренние фрагменты ролика, движения и внутренние фрагменты ролика. Это пример.
- В этом вопросе они говорят, что это невозможно, и предлагают решение, в котором мувиклип должен быть включен в основное приложение, но таким образом редакторы не смогут обновлять графику и анимацию после утверждения приложения. в магазине. Весь смысл в том, чтобы редактор мог обновлять каталог товаров.
- Вот дополнительная дискуссия по теме.
ВОЗМОЖНЫЕ РЕШЕНИЯ ДЛЯ ИЗУЧЕНИЯ:
- Я думаю о реализации некоторой рекурсивной итерации, создающей каждый DisplayObject с нуля, но я все еще не могу найти последовательный способ дублировать форму, созданную редактором в пользовательском интерфейсе Flash. Фактически, они говорят, что это также невозможно, все, что можно сделать, это создать "растровые" копии, которые, вероятно, будут слишком тяжелыми при обработке, особенно если создать слишком много копий.
- Я предполагаю, что, вероятно, единственный способ - это найти какой-нибудь хак компиляции, чтобы позволить внешнему SWF определить новый класс, чтобы экземпляр мог быть создан в основном приложении. На данный момент редактор не сможет изменять дублирующиеся объекты.
- Существует также возможность иметь дублируемый элемент в отдельном SWF-файле и загружать его несколько раз, но я не знаю, сработает ли это, хотя это немного утомительно для дизайнера.
- Я также попытался сериализовать сериализованный несериализованный весь мувиклип, но я также не смог найти последовательный метод для этого.
Примечание для разработчиков Adobe Flash: реализация ARM/iOS класса AS3 Loader должна быть изменена, чтобы включить связанные классы в контекст выполнения, поскольку разработчик ожидает, что он сможет создавать экземпляры мувиклипов со связанным классом, даже если они содержится во внешнем SWF-файле, загруженном из приложения iOS air. В настоящее время инстанцирование не выполняется в iOS-air, но оно отлично работает в десктопе. Я понимаю, что Apple не позволяет выполнять код, загруженный из внешнего SWF-файла, но это не выполнение кода, это просто связь класса, которую можно использовать для создания нескольких экземпляров фрагмента ролика из фактического кода приложения.
Кто-нибудь может помочь?
1 ответ
У меня была такая же проблема, и я в итоге использовал дублированный символ на сцене внешнего SWF. Я дублировал символ около 30 раз на сцене
Я назвал экземпляры последовательно, например, card0, card1, card2 и т. Д.
Затем в коде у меня есть цикл for, который получает ссылку на эти объекты внутри загруженного SWF-файла, помещает их в пул (массив) и затем удаляет их как дочерние элементы из внешнего SWF-файла.
Сборщик мусора не удаляет объекты, так как на них все еще ссылается массив
Затем у меня есть код, который управляет распределением элементов из пула, а не их созданием.
Это делает внешний SWF немного больше, но не намного для 30 элементов в моем пуле, так как они являются только ссылками на символ в библиотеке
Вы можете написать JSFL-скрипт для дублирования и именования в FLA, чтобы автоматизировать процесс.
КСТАТИ.
Я попробовал несколько других (более чистых) методов, но ни один из них не работал на iOS
На ПК я смог получить определение класса из символа во внешнем SWF-файле, если пометил его как "Экспорт для ActionScript", а затем создал экземпляр класса. например
applicationDomain.getDefinition("Card") as Class;
Заметка. Я устанавливаю контекст загрузчика
var ldrContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain );
чтобы загруженный SWF-файл совпадал с текущим доменом приложения, в противном случае iOS вообще не сможет загружать и использовать SWF-файл.
Однако это работало только на ПК и странным образом не на Mac (OSX).
Моя следующая попытка была поставить одну копию символа на сцену и использовать, например,
_cardSWFClass = Object(_contentSWF.card).constructor;
где contentSWF - это объект MC загруженного извне swf, а "card" - это имя экземпляра на стадии объекта, подлежащего клонированию.
Этот метод работает как на ПК, так и на Mac, но не на iOS
Однако у меня есть ощущение, что это работает только на ПК и Максе, потому что у меня могло быть то же имя класса в FLA, который загружал внешний SWF, что и внешний SWF, так как я скопировал символ из Приложение к внешнему контенту.
Это также заставляет меня задуматься, не стоило ли пытаться, чтобы внешний MC использовал то же имя пакета, что и код приложения, а не внешний SWF, который был загружен в моем случае, не определил класс или имя пакета для SWF
т.е. определить пустые классы в FLA / коде приложения и во внешнем SWF-файле ссылаться на те же имена классов в том же пакете, что и FLA-приложение.
Эти классы, вероятно, должны быть пустыми (возможно, вообще без файла AS), поскольку iOS не должна загружать внешние SWF-файлы, которые содержат код. Однако на практике кажется, что iOS будет загружать внешние SWF-файлы, которые содержат код временной шкалы, но код удаляется загрузчиком.
Дальнейшими путями исследования может быть метод, который доступен для создания кода для внешних загруженных SWF-файлов внутри основного кода приложения, и который каким-то образом связан во время выполнения.
Побочный продукт этого может позволить создание экземпляров внешних символов (на самом деле я думаю, что это определенно нужно, иначе это кажется бессмысленным)
то есть как в этом обзоре http://blogs.adobe.com/airodynamics/2012/11/09/packaging-and-loading-multiple-swfs-in-air-apps-on-ios/
Однако нехватка времени помешала мне продолжить изучение этого вопроса.
Редактировать. Игнорировать ссылку. Я думаю, что это красная сельдь.
Изменить 2.
У меня есть частичное решение, которое может работать для некоторых людей.
Мои предположения об использовании одних и тех же имен пакетов и имен классов как в классе, который загружает SWF, так и в самом внешнем SWF, кажутся правильными.
Однако он работает только с использованием этого метода, когда на этапе внешнего содержимого есть экземпляр символа, который можно использовать для доступа к конструктору для внешнего символа. Кажется, он не работает с использованием метода getDefinition.
например, этот код получает класс экземпляра с именем "card" в _contentSWF
_cardSWFClass = Object(_contentSWF.card).constructor;
Также обратите внимание, что на ПК (хотя не на Mac и, возможно, не на iOS) для рассматриваемого класса было необходимо определить все его именованные подобъекты, т. Е. Как если бы вы не объявляли экземпляры автоматически в рабочей области.
В моем случае мой символ "карточка" имел TextField с именем txt и некоторые другие атрибуты, которые мне нужны для хранения данных, поэтому мне пришлось добавить их в класс, например
package DragAndDrop
{
import flash.display.MovieClip;
import flash.text.TextField;
/**
* ...
* @author Roger Clark
*/
public class Drag extends MovieClip
{
public var txt:TextField;
public var originalX:Number;
public var originalY:Number;
public var itemData:XML;
public function Drag()
{
}
}
}
Одна запись.
Созданный экземпляр класса не является DragAndDrop.Drag (или просто Drag), т.е. хотя и ПК, и Mac сообщают об этой трассировке (_cardSWFClass); это [класс Drag] на Mac, это завершается с ошибкой во время выполнения и выдает ошибку #1034 (сбой приведения типа), поскольку тип времени выполнения сообщается как DragAndDrop.Drag@9a40e51 на моем Mac
Поэтому необходимо объявить тип объекта как:MovieClip, который создается. Кажется, что невозможно привести его к Drag (только к MovieClip)
Только одна оговорка. Я не проводил всестороннего тестирования, чтобы увидеть, есть ли какие-либо другие ограничения к этому, но это, кажется, работает для меня, используя AIR 4 и iOS6.
Редактировать 3.
Я только что заметил еще одну вещь. Необязательно, чтобы исходный файл класса был доступен для внешнего FLA, когда SWF-файл "опубликован". Я понял, что случайно ошибся в путях, и что мой внешний FLA не имел доступа к файлу класса AS, и создавал собственное пустое определение класса на лету.
Я перепроверил это, с правильными путями, и это, казалось, не имело никакого значения, то есть это все еще работало на ПК, Mac и iOS
Кроме того, я попытался удалить свойства из внешнего файла определения класса для элементов, которые не были определены во внешнем FLA, например, originalX и originalY, но без них я получаю ошибки времени выполнения на ПК.
Я нахожу эти ошибки во время выполнения довольно странными, так как я объявляю класс, который создается как MovieClip, а MovieClip - класс dymanic. Так что, как будто Flash считает, что его экземпляр является каким-то особым типом нединамического MovieClip
Редактировать 4.
Я наткнулся на еще одну оговорку к этой работе вокруг. Представляется, что при некоторых обстоятельствах символы, которые необходимы для дублирования (путем доступа к их конструктору), должны присутствовать в кадре 1 внешнего SWF и, возможно, во всех других кадрах во внешнем MC.
Если вы попытаетесь получить конструктор этих экземпляров, а их нет в кадре 1, класс, который возвращает Flash, - это просто MovieClip, а не класс, определенный для символа (определенный в библиотеке). Заметка. Символы помечены для экспорта в кадре 1, так что это не причина.
На данный момент я не совсем уверен в точных обстоятельствах, когда это происходит, так как это может быть связано с путем загрузки внешнего SWF-файла или может быть вызвано тем, что приложение AIR загружает внешний SWF-файл.
то есть он работает нормально, когда я загружаю SWF-файл непосредственно в другой SWF-файл (на ПК), но не работает (на ПК), когда внешний SWF-файл загружается из SWC-файла, скомпилированного как часть приложения AIR.
Я опубликую больше информации, если когда-нибудь узнаю точную причину этих расхождений.
Изменить 5.
Это что-то вроде продолжающейся саги.
Я нашел одну проблему с использованием этого подхода. В iOS вам нужно загрузить SWF-файл в текущий домен приложения, иначе SWF-файл вообще нельзя использовать. Однако, если вы загружаете разные SWF с символами в них с одинаковым именем класса, Flash кэширует первый экземпляр (символ), который создается с использованием этого метода.
Обычный обходной путь для этого - создать новый домен приложения для каждого загруженного SWF-файла и впоследствии освободить домен. См. ApplicationDomain уточнение необходимо
Однако это не работает на iOS, так как вам, кажется, всегда нужно загружаться в домен ApplicationDomain.current.
См проблемы с загрузкой встроенных SWF-файлов в приложение Air
Таким образом, хотя мой обходной путь работает, он будет бесполезен, если вы хотите загрузить несколько внешних SWF-файлов, каждый из которых содержит символы с одинаковым именем класса, но разным графическим содержимым.