пятница, ноября 30, 2007

gotoAndPlay каждый ENTER_FRAME - некорректная работа анимации. AS3

Столкнулся с проблемой:
Если каждый фрейм для MovieClip вызывать gotoAndPlay(label), перестает работать внутренняя анимация клипов типа MovieClip, расположенных в этом фрейме.
Переход осуществляется, но вложенные клипы не воспроизводятся.

четверг, ноября 29, 2007

Объект с глобальным доступом. Полезные свойства.

Работая с паттерном Singleton в применении к реализации объекта с глобальным доступом, неожиданно наткнулся на полезное его свойство - возможность легко передавать данные между совершенно несвязанными и далеко друг от друга располагающимися объектами.

* * *

И синхронизировать!

* * * UPDATE * * *
Изменение заголовка:
Старый - "Singleton как средство передачи данных между объектами"
Новый - "Объект с глобальным доступом. Полезные свойства."
Причина - неверное использование термина "Singleton"

воскресенье, ноября 25, 2007

Загружаемый растр. Как включить сглаживание при трансформациях. AS2

Я не нашел штатных средств Flash, которые бы позволили сделать сглаживание для загруженного (через MovieClipLoader) растрового изображения.
Решил обойти эту проблему, используя класс BitmapData. Код здесь.

После загрузки, на момент события onLoadComplete, клип не является полноценным. AS2

Загружаем клип при помощи MovieClipLoader.
По событию onLoadComplete мы получаем новый загруженный клип.
Но он еще неполноценный.
В момент действия onLoadComplete мы не можем получить его _width, _height. Не видим клипов или динамических текстовых полей, которые размещены в нем.
Всё это можно получить позже - на следующем фрейме.

Значит, просто ждем следующего фрейма. Пока других выходов не нашел: Здесь код.

* * *

Всё выше написанное не имеет смысла, так как у MovieClipLoader существует событие onLoadInit, решающее эту проблему.

Прозрачность BitmapData. AS2

Маленькие детские грабельки из песочницы. Чтобы BitampData была прозрачной, недостаточно просто установить в конструкторе параметр transparent в true. Надо обязательно следующий параметр fillColor установить в 0.
Только после этого BitmapData будет в себя рисовать прозрачные клипы и аттачиться в другие клипы прозрачно.
В хелпе про это сказано.

суббота, ноября 24, 2007

О динамическом добавлении методов. AS2

Некоторые объекты, типа AsBroadcaster и EventDispatcher, добавляют новые методы инициализируемым классам. Обычно я просто описывал класс как dynamic.
Но есть более правильный способ - определить присваиваемые методы.
Можно как свойства типа Function, можно как пустые методы.

пятница, ноября 23, 2007

Паттерн Singleton в языке ActionScript

Наконец решил использовать Singleton явно и в полную силу.
С удивлением обнаружил что раньше не вставил ссылку на эту статью в свой блог и теперь потратил время чтобы перерыть flash-ripper в поисках ссылки...
Итак, как резюме - здесь пример паттерна на AS3, хотя никто нам не мешает модифицировать и использовать этот код для AS2 (правда уже не получится реализовать такой же запрет на инстанцирование через конструктор).

* * *

Запрет на инстанцирование на AS2 делается еще проще чем на AS3, так как есть возможность объявить конструктор класса как private.

понедельник, ноября 19, 2007

Видео с камеры

var webcam:Camera = Camera.get();
cam_video.attachVideo(webcam);

где cam_video: компонент Video.

воскресенье, ноября 18, 2007

Нетипизированные переменные. AS2

В объекте this.__face назначаются некоторые свойства:
this.__face.url=parameters_array[0];
this.__face.x=parameters_array[1];
this.__face.y=parameters_array[2];

Далее, производя арифметические операции с этими свойствами, возникают ошибки.
Однако, стоит назначить свойствам тип:
this.__face.url=parameters_array[0];
this.__face.x=Number(parameters_array[1]);
this.__face.y=Number(parameters_array[2]);
И всё встает на свои места.

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

суббота, ноября 17, 2007

Об особенностях мониторинга загрузки, об экспорте для AS и об импорте классов. AS2

Важно знать:
  1. Если клип экспортируется для ActionScript посредством Linkage > Export for ActionScript, при отмеченном параметре Export in first frame, этот клип будет доступен для "attachMovie" с первого же фрейма, но будет помехой для правильного мониторинга загрузки SWF-файла, т.к. первый фрейм не будет выведен до тех пор, пока все его клипы не загрузятся. При этом, загрузка некоторого (довольно приличного) объема данных не будет отображена, что не есть хорошо.
    Для того, чтобы отложить загрузку такого клипа, необходимо снять параметр Export in first frame. Однако если явным образом такой клип не присутствует во временной шкале, он не будет экспортирован в SWF вообще. Поэтому, для экспорта таких клипов нужно отвести какой-нибудь фрейм, который никогда не будет показан при воспроизведении SWF.
  2. Классы из Publish settings > Flash > Settings > Classpath и классы из текущего каталога импортируются во фрейм, указанный там же, в Export frame for classes. Для идеального мониторинга загрузки, лучше указать не 1-й фрейм, а какой-либо другой, располагающийся после модуля мониторинга загрузки .
    Странно, но классы, импортируемые "вручную" также не могут быть использованы до этого фрейма.
  3. Если с клипом ассоциирован класс по средством параметра Linkage > Export for ActionScript, и для клипа и для класса всё происходит как в 1-м и 2-м пунктах.

Особенности мониторинга загрузки (preloader):

  1. Модуль мониторинга загрузки должен располагаться до фрейма, в который импортируются классы и экспортируются клипы.
  2. Мониторинг не может быть описан классом.
  3. Модуль мониторинга загрузки должен иметь минимальный объем.
  4. При подсчете процента загрузки SWF, необходимо учитывать объем уже загруженных на момент активации мониторинга данных:

    На момент инициализации мониторинга:
    this.skipped=_root.getBytesLoaded();
    this.total=_root.getBytesTotal()-this.skipped;

    В процессе подсчета загруженного объема:
    var progress:Number=(_root.getBytesLoaded()-skipped)*100)/this.total;

Код подключаемого кода здесь.

среда, ноября 14, 2007

Как сохранить из Flash изображение в формате JPG

Есть необходимость сохранять изображение из Flash в формат JPG.
А точнее - сделать скриншот.

Поиски привели к статье: Export JPEG with Flash/PHP - bitmap сканируется в строку base64 и передается на сервер, где ее ловит PHP-скритп и транслирует в формат JPG.
Способ применим начиная с 8й версии FlashPlayer.

Другая статья: PNG Encoder in AS3 - здесь bitmap конвертируется в байтовый массив содержащий изображение в формате PNG.
Рядом - класс-конвертер Bitmap в JPG: More fun with image formats in AS3. Код прилагается.

Как сохранить ByteArray на сервер в файл: Save ByteArray to file with PHP

Еще статейка с сохранением PNG и JPG для Flash 8: Saving JPEGs or PNGs with Flash 8 Revisited. С исходниками.

* * *

Использовал последнюю статью (Saving JPEGs or PNGs with Flash 8 Revisited) - работает ОТЛИЧНО! Превосходный интерфейс, документировано, отличная демка.

воскресенье, ноября 11, 2007

Delegate. Проблема доступа к вызывающему объекту

this.item.area.onRelease=Delegate.create(this,this.onItemRelease);

Объектов item может быть много. Необходимо в onItemRelease как-то добраться до area, которое вызвало событие.

Неполучилось.

Есть конечно способы модифицирующие класс Delegate, но хотелось бы без этого.

* * *

Обсудили этот вопрос. Наиболее изящным мне показался следующий метод:

Для Area определяем:

var onReleaseWithThis:Function;
function onRelease() {
onReleaseWithThis(this);
}

Теперь для главного класса:

this.item.area.onReleaseWithThis=Delegate.create(this,this.onItemRelease);
function onItemRelease(who) {
trace(who);
}

* * *

В итоге, склонился к методу перекрытия класса Delegate своим, с передачей параметров. Использовать удобно, подключать удобно. Разве что неудобно таскать из проекта в проект.

Заметил правда один хак, который сам непонимаю почему работает. При передаче дополнительных параметров при create, они находятся в области видимости create, но затем, почему-то легко доступны в самой вызываемой функции уже позже, при работе программы. А нет ли такой вероятности, что эти параметры удалятся тем же Garbage Collector ом? Тем не менее метод работает, и я его буду использовать. Благо в AS3 такой ерундой заниматься уже нет необходимости.

Использовать String не по назначению плохо. AS2/3

Еще раз убедился что String для идентификаторов состояний и тому подобного очень плохо, хотя и, казалось бы, удобно. Например, очень просто определить переменную state как String и устанавливать/проверять состояния типа "playing", "stopped" и т.п.
Теперь определяем state как Number и определяем константы ClassName.PLAYING и ClassName.STOPPED.
В случае, если состояние проверяется часто, например несколько раз в течение фрейма, выигрыш производительности составляет почти в 2 раза.

пятница, ноября 02, 2007

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

Как лучше определять свойства класса, предназначенные для потомков и внешнего пользования? Вопрос не быстродействия а логики.

  1. Определить как protected и в потомках использовать их напрямую, а для внешнего использования сделать public установщик.
  2. Определить как private, и для потомков и для внешнего использования сделать public установщик.
  3. Определить как public.

Первый способ дает неоднозначность - обращаться к свойству напрямую или через установщика. Однако, обращаясь напрямую, мы имеем дело с переменной, что улучшает производительность.

Второй способ лучше, т.к. сокращает количество путей доступа к свойству, что лучше сказывается на инкапсуляции объекта.

Последний способ применим только для простых конструкций.

* * *

Важно четко понимать, какой способ лучше применить:

  • Очевидное применение первого способа - для абстрактных классов,
  • Второй соответственно в реализациях
  • Третий - для простых конструкций, предназначенных для хранения данных.

четверг, ноября 01, 2007

Как загрузить библиотеку и затем аттачить из нее клипы

Встал вопрос, как это сделать. Нашел такой код. Надо пробовать.

* * *

Попробовал, работает превосходно. Обожаю AS3.

* * *

Трансформируя вышеприведенный код получаем очень простое решение:

Перед загрузкой указываем лоадеру контекст:
var context:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain);
this.loader.load(this.source_url, context);

Затем, уже после того как загрузится swf-ка, мы в любой момент можем сделать следующее:

var movie_class:Class = ApplicationDomain.currentDomain.getDefinition("MovieClass") as Class;
var movie_sprite:Sprite = new movie_class();
this.addChild(movie_sprite);

Как загрузить библиотеку и затем аттачить из нее клипы

Встал вопрос, как это сделать. Нашел такой код. Надо пробовать.

Версия подгружаемой SWF

Смотреть 4й байт. Код.