Миграция на Flex mxmlc из ActionScript 2 mtasc

Несколько лет назад я создал крошечный, простой SWF-файл для воспроизведения MP3-файлов в различных браузерах. Я выставил интерфейсы и вызвал их из JavaScript. Все было маленьким и простым; вы можете увидеть весь Guise.as исходный код.

Я скомпилировал основной класс, используя mtasc, что позволяет указать основную функцию для кода инициализации:

/**Main entry point.*/
static function main(mc)
{

Это работало очень хорошо, пока я не хотел добавить поддержку WAV. Flash изначально не поддерживает WAV, поэтому я попытался добавить его в библиотеку. Но библиотека требует Flash 10 и не будет компилироваться mtasc я скачал Flex 4.6 и попробовал использовать mxmlc, Мальчик, моя боль была только началом.

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

  • Если я правильно понимаю, mxmlc не имеет понятия "основная точка входа", но Flash просто создаст экземпляр "основного класса", что бы это ни было. Но как мне указать основной класс? Если я ссылаюсь на мой класс с mxmlc в командной строке этот класс автоматически станет основным или абсолютно необходимо, чтобы мой класс был в корневом (то есть, нет) пакете? У него должно быть специальное имя?
  • После того, как я успешно назначил основной класс, могу ли я просто переместить код моей точки входа в конструктор моего основного класса?
  • В моем исходном классе я добавил глобальную функцию для преобразования объекта в массив, используя Array.from=function(object:Object), Это дало мне ошибку, когда я был в строгом режиме - очевидно, потому что мне не нравится добавлять статические методы в Array объект класса. Будет ли это работать в нестрогом режиме? В чем проблема? Если я преобразую это в обычный метод в моем классе, это будет работать?
  • Поскольку я привык делать в "реальном" JavaScript, я добавил Function.prototype.bind=function() функционировать так, что, когда у меня есть обратные вызовы, this будет установлен правильно. Это все еще будет работать? Могу ли я добавить методы в прототип Function?
  • Мне даже нужно больше связывать контекст? Если я позвоню что-то вроде positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000) без bind(this) Будет ли Flash проходить правильно this на мой метод обратного вызова?
  • Компилятор Flex пожаловался, что изменилось несколько методов API, поэтому, возможно, изменение моих вызовов изменило что-то, и я не понимаю новый API. Есть ли способ отладки этого SWF? Написать в консоль браузера? Звуковой сигнал? Что-нибудь? Не покупая какую-то большую IDE от Adobe или что-то еще?

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

2 ответа

Решение

Не думаю, что смогу ответить на все ваши вопросы, но постараюсь дать несколько ответов:

ActionScript 3 является существенным изменением по сравнению с ActionScript 2. Это полная перестройка архитектуры, а не просто незначительное обновление и несовместимость с предыдущими версиями, поэтому, если не считать перезаписи, обычно довольно сложно настроить нетривиальный as2 для компиляции в as3. Это очень похоже на совершенно новый язык. Поэтому может быть лучше сделать шаг назад и посмотреть, что изменилось в языке, потому что это очень много.

Самая большая вещь - это формализованное наследование классов, а не наследование прототипов.

  • "Flash просто создаст экземпляр" основного класса "", что бы это ни было ".

Итак, когда вы компилируете из командной строки, вы даете ему путь к "главному классу":

mxmlc.exe "c:\dev\project\SomeClass.as"

с SomeClass.as выглядит так:

package {
    import flash.display.Sprite;
    public class SomeClass extends Sprite {}
}

После инициализации flash создаст экземпляр этого класса и прикрепит его к сцене. Это будет похоже на концепцию AS2 _root, -src Переключатель передан mxmlc.exe устанавливает путь к остальным классам / пакетам, которые поддерживают этот основной класс.

Таким образом, ваш основной класс, как бы вы это ни называли, должен наследовать от Sprite,

  • После того, как я успешно назначил основной класс, могу ли я просто переместить код моей точки входа в конструктор моего основного класса?

Да. Конструктор для вашего "основного класса" будет точкой входа для вашего SWF.

  • "Поскольку я привык делать в" реальном " JavaScript, я добавил функцию Function.prototype.bind=function(), чтобы, когда у меня были обратные вызовы, это было установлено правильно. Это все еще будет работать? Могу ли я добавить методы прототипу функции?"

Методы класса ActionScript 3 являются автоматически связанными методами, что является небольшим отличием от JavaScript. На самом деле, невозможно вызвать метод класса в каком-либо ином контексте, кроме того экземпляра, из которого он был создан (даже если вы используете .call() или же .apply() попытаться форсировать изменение контекста). Например, с этим простым классом

public class SomeClass {
    public function Worker() {
        alert(this);
    }
}

а потом

var cls:SomeClass = new SomeClass();

cls.Worker();
var func:Function = cls.Worker;
func();
func.call(this);
func.apply(undefined);

Эти четыре вызова функций дадут одинаковый результат, потому что Worker() всегда привязан к функции, из которой он пришел.

Обратите внимание, это относится только к методам класса и не применяется к анонимным функциям / замыканиям. Так...

var func:Function = function():void { alert(this); }
func();
func.call(cls);
func.call(undefined);

... все разные

  • "Нужно ли мне больше связывать контекст? Если я вызову что-то вроде positionTimeoutID=setTimeout(fireSoundPosition.bind(this), 1000), без bind (this), Flash передаст правильное this в мой метод обратного вызова?"

Это зависит от того, если это метод класса, то он всегда будет связан (см. Последний раздел). Если закрытие / анонимная функция, то да, ее все равно нужно будет связать, чтобы указать this,

  • Компилятор Flex пожаловался, что изменилось несколько методов API, поэтому, возможно, изменение моих вызовов изменило что-то, и я не понимаю новый API. Есть ли способ отладки этого SWF? Написать в консоль браузера? Звуковой сигнал? Что-нибудь? Не покупая какую-то большую IDE от Adobe или что-то еще?

Возможно, вы захотите получить проигрыватель флэш-отладки. И компилятор должен был прийти с fdb флэш-отладчик командной строки. Идея состоит в том, что когда вы размещаете / запускаете приложение в проигрывателе отладки, вы можете прикрепить fdb к примеру и trace(), а также установить точки останова и просмотреть исключения.

  • В моем исходном классе я добавил глобальную функцию для преобразования объекта в массив, используя Array.from=function(object:Object). Это дало мне ошибку, когда я был в строгом режиме - очевидно, потому что мне не нравится добавлять статические методы к объекту класса Array. Будет ли это работать в нестрогом режиме? В чем проблема? Если я преобразую это в обычный метод в моем классе, это будет работать?

Мне нужно разобраться с этим, хотя я мог бы представить, что "правильное" решение AS3 будет состоять в создании статического метода из другого класса для выполнения этого действия, а не в попытке расширить Array непосредственно. Что-то вроде:

package {

    public class ArrayHelpers {
        public static From(object:Object):Array {
            /* do work */
        }
    }

}

А затем назовите это как: ArrayHelpers.From(whatever);

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

Прежде всего, чтобы получить основной класс, вы просто указываете этот класс на mxmlc командная строка. Класс не должен быть в корневом пакете. Поместите материал запуска в конструктор класса. О, и с других веб-сайтов, кажется, может потребоваться расширить класс Sprite или клип.

Как указывает 32bitkit, ничего из связующего не требуется. Но будьте осторожны - большая часть API изменилась со времен Flash 9. Например, ExternalInterface.call() теперь принимает только два аргумента, потому что вам не нужно передавать контекст (например, this) больше. И Sound API полностью изменился.

Попытка определить Array.from() наверное не сработает. (Мне не нужно было после того, как выкинул Function.prototype.bind() что мне больше не нужно.) Попытка расширить существующие классы, такие как добавление String.prototype.endsWith() похоже, тоже не работает.

Но, пожалуй, самое важное, что я нашел в отладке SWF, который наконец-то позволил мне выяснить проблемы, очень важно: скачайте отладочный Flash-проигрыватель ActiveX и установите его для IE. (Я только рекомендую версию IE, потому что весь смысл этого упражнения в том, что я пытаюсь заставить файлы WAV воспроизводиться на IE- единственном крупном браузере, который не поддерживает файлы WAV. Grumble grumble.) Серьезно Отладочный Flash Player неоценим. Автономный проигрыватель отладки не поддерживает ExternalInterface,

О, а простой способ помочь с отладкой? Просто перезвоните в логи браузера, как это:

ExternalInterface.call("console.info", "Hello, world!");

Отлично работает! Да, и еще одна вещь: включите это немедленно в начале вашего кода, и когда вы вызываете свой SWF из JavaScript, исключения возвращаются и отображаются в отладчике вашего браузера (и наоборот)!

ExternalInterface.marshallExceptions = true;

Весь день я был вынужден перейти на ActionScript3, Flash 10, Flex и т. Д., Когда думал, что мне нужно изменить только пару строк кода. Теперь, когда у меня, по крайней мере, есть что-то связанное, во многом благодаря обратной связи здесь, завтра я вернусь назад и попытаюсь выяснить, почему я не могу воспроизвести файлы WAV- в этом весь смысл упражнение для начала.

Другие вопросы по тегам