Flex и RIA блоги



2007-03-29

08:17:09, Junik
Плагин XMLBuddy для Eclipse

Вчера открыла для себя плагин для Eclipse XMLBuddy, который помогает работе с XML. Позволяет настроить подсветку XML и DTD, генерит DTD для имеющегося XML и еще много всего. Есть бесплатная версия XMLBuddy и платная XMLBuddy Pro. Про все это подробнее на сайте http://www.xmlbuddy.com.
Устанавливается простым копированием в папку plugins.
Кстати, поделитесь, кто чем пользуется для работы с XML в Eclipse.


2007-03-28

18:40:51, Agahov's blog
Решение проблемы наследования от Point.

Проблема:
Допустим, сделал я интерфейс IVector:

  1. interface IVector{
  2. function get x () : Number;
  3.  …
  4. }

Есть у меня класс утилита, который работает с этим интерфейсом:

  1. class VectorMath{
  2.   public function calc(v:IVector):IVector
  3.   {
  4.   …
  5.   }
  6. }

Кульминация - нужно сделать реализацию IVector:

  1. class Vector  implements IVector
  2. {
  3.   private var _x  : Number;
  4.   public function get x () : Number
  5.   {
  6.         return _x;
  7.   }
  8. }

Если присмотреться к классу Vector, становиться понятно, что он очень похож на Point.
Что же делать, ведь в данной реализации наследовать Vector от Point нельзя. Включать Point в Vector тоже нехорошо, потому как мы потеряем поведение Point. И для всех системных утилит принимающих Point, придется делать преобразование.

Решение:
Перепишем интерфейс IVector:

  1. interface IVector
  2. {
  3.   function get i () : Number;
  4.  
  5. }

И реализация IVector будет иметь следующий вид:

  1. class Vector  extends   Point implements IVector
  2. {
  3.   public function get i () : Number
  4.   {
  5.         //это не опечатка :)
  6.         return super.x;
  7.   }
  8. }

Вот такая радость:). Сегодня придумал. Если вы увидели недостатки данного решения, очень прошу поделиться.


2007-03-27

09:18:07, Junik
Новый Flex Community Site

Farata Systems анонсировали сайт http://www.myflex.org. Пока это только alpha версия. Интересно то, что сделан сайт на flex. Пока еще не очень удобно им пользоваться, но надеемся на лучшее. Обещают, что там будут появляться компоненты для flex и плагины для flex builder, в том числе и бесплатные.


2007-03-26

14:57:30, Junik
Легкая локализация во Flex. А будет ли runtime локализация?

Если вы разрабатываете flex приложение, то локализация не должна отнять много времени, про что есть статьи и на русском языке (например, эта). Несколько минут и ваше приложение “заговорит” на разных языках, а если забудете что-то важное, то exception обеспечен.
Adobe предлагает использовать [ResourceBundle] metadata в ActionScript и @Resource директиву в MXML. Лично я отдаю все-таки предпочтение использованию метатега ResourceBundle с последующим общением с объектом типа ResourceBundle, хотя бы потому что Flex не поддерживает runtime локализацию и при необходимости придется ее добавлять. И проще будет вместо ResourceBundle подсунуть класс с таким же интерфейсом, чем исправлять строки типа “@Resource(key=’keyname’, bundle=’ResourceBundleName’)” во всех mxml файлах.
Кстати, судя по первому комменту этого поста стоит ожидать поддержки runtime локализации в первой половине 2007 года, так что ждать осталось совсем немного. :) Хочется верить, что для этого не прийдется создавать swf файл для каждого языка с последующей их подгрузкой, как сейчас предлагается создавать swf-оболочку для css.


14:27:10, Graann's blog
Подгрузка css на стадии компиляции

В процессе работы над очередным проектом у нас с Junik возникла потребность в использовании каскадных стилей. Подробнее о стилях и вариантах их использования написано тут, методика подгрузки css в рантайме тут, здесь же речь пойдет о тех проблемах с которыми мы столкнулись в процессе подгрузки файла css на стадии компиляции.
В окне свойств каждого проекта есть вкладка именуемая Flex Compiler, где в строке additional compiller arguments можно задавать опции для компиляции приложения. В перечне присутствует такая незаменимая в нашем случае опция как defaults-css-url. Собственно эту, как и все остальные, опцию можно вынести и в специальный конфигурационный xml. Хотя сейчас не об этом. Сейчас о том, что где бы вы ни задали ваш css вовсе не факт что он у вас заработает. Нам как раз посчастливилось столкнуться с этой проблемой. Изначально наш css подгружался в mxml-ине посредством тега Style и все прекрасно работало. После того как мы вынесли css в конфигурационный файл приложение работать напрочь отказывалось и постоянно генерило ошибки в рантайме.
В хелпе ничего внятного мы не нашли. Нечто отдаленное покоится тут Активное прогугливание ответов на вопрос “что за фиг?!” тоже нам не доло. Кроме криков о помощи еще кучки товарищей различных национальностей гугл ничем не порадовал.
Пришлось думать самим. Суть проблемы на поверку оказалась в следующем:
Как вы вероятно знаете, по умолчанию флекс пользуется услугами default.css. (у меня c:\Program Files\Adobe\Flex Builder 2\Flex SDK 2\frameworks\defaults.css) в котором аккуратно прописывает все стили компонент. Когда вы подгружаете css в теге Style приложение первоначально грузит вышеупомянутый defaults.css и только после этого применяет к приложению правила из вашего css. В случает же когда вы прописываете defaults-css-url defaults.css замещается вашим файлом и приложению просто не хватает стилей для отображения.


2007-03-24

08:06:54, Korax Flash
Вышел первый HotFix для Flex SDK 2.0.1

От разработчиков Flex SDK появился первый HotFix, лечащий многие баги в DataGrid. К сожалению другие баги (неправильные скроллбары, ошибка на вторичной загрузке модулей, дублирование иконок в Menu), пока не исправлены. Но будем надеятся, что скоро выйдут соответствующие исправления.

Немного недоумения вызвало, что все файлы в архиве отдатированы 06-фев-2007, а фикс вышел только два назад. Ну да ладно…, как умеют, так и работают … :)


2007-03-23

06:13:03, Korax Flash
Встречайте Apollo!

Apollo – кросс платформенная среда, позволяющая создавать многофункциональные приложения с использованием большого количества современных технологий; таких, как HTML, Flash, JavaScript, AJAX, Flex и проч. для операционных систем Windows и MacOS, а в перспективе – и Linux.

Уже сегодня можно посмотреть и потрогать Apollo-технологию, скачав дистрибутивы с сайта Adobe Labs. Выход финальной версии Apollo запланирован на конец этого года, так-что массовое создание Apollo-приложений вероятно переносится на 2008 год.

Уже в альфа-версии можно:

  • работать с окнами операционной системы
  • работать с файловой системой
  • работать с новым HTML-рендером

И всего этого программисты из Adobe, добились всего-лишь за год напряженной работы.

Порадуемся вместе с программистами из Adobe долгожданному выходу Альфа-продукта и с нетерпением ждём новых фич и функционала в этом и последующих годах.


2007-03-20

21:30:39, Korax Flash
«Убийца» Java и .NET: Apollo

Тут CNews порадовала своим заголовком, вслед за информативными сообщениями от Роста и Константинера:

http://flash-ripper.com/archives/001691.php

http://riapriority.com/blogs/constantiner.php…

Post Update:

Сорри пост зачищен, отныне про Adobe Flex, либо хорошо, либо ничего…


2007-03-18

08:10:14, Action Script 3
Как теперь работать с клипами ?

Что-то давно я ничего не писал , блог зафлудили спамеры, тем не менее посещаемость растёт. Последнее обстоятельство заставило меня пристыдиться и написать что-нибудь.

Разницы между AS1 и AS2 невелика, некоторые фичи API плеера (например битмап фильтры и ExternalInterface) и эмуляция ООП среды на стадии компилляции. Это именно эмуляция, компиллятор собирает из исходников AS2 код AS1. Посмотрите на параметры публикации, выберите Flash Player 6 и убедитесь что среда предалагает публикацию на двух языках AS1 и AS2.

Многие флешеры говорят что они “кодят на AS2″, но большинство из них не понимают что такое ООП. Они имеют какие-то представления об этом, но пишут программы приемущественно в кадрах клипов и считают “классы” лишним наворотом большого смысла в котором видят. ООП идеология – ключевой момент, отличающий AS1 от AS2.
Если пишите программы приемущественно в кадрах, значит кодите на AS1.

Если AS1 — ваш первый язык программирования. То перейти на ActionScript 3 вам будет сложнее. Т.К. в вашем мозге (как и ранее в моём) есть вредные извилины абстрактной модели MovieClip’ов.
Если вы работали на ActionScript 2 то всё немного проще, из-за принципов ООП, которым можно научиться в ActionScript 2.
Всех флешеров AS1, смутит новая модель работы с клипами.

Раньше приаттачить клип из библиотеки можно было так:

clip.attachMovie('linkageId', 'clipName', depth)

1. cоздали новую копию символа linkageId

2. создали новую переменную clipName в клипе clip.
Процесс довольно не привычный для программиста. Двумя строковыми литералами мы создаём переменную непонятного типа в объекте clip.

В Actions Script 3 логика больше соответсвует стандартам.
Что бы создать какой-то графический элемент и разместить его на сцене нужно:

1. Создать новый сомвол в библиотеке и нарисовать что-то в этом символе.
2. Ассоциировать созданный символ с классом:
Просто щёлкните правой кнопкой на символе в билиотеке, выберите Linkage. В открывшемся окне поставьте галочку Export for ActionScript.
В подсветившемся поле “Class” введите название класса.
3. Создать инстанцию класса и приаттачить куда нужно методом addChild().

Допустим вы создали в библиотеке символ и ассоциировали его с классом Square.

package
{
	import flash.display.Sprite;
	public class Board extends Sprite
	{
		public function Board()
		{
			var aSquare:Square = new Square()
			this.addChild(aSquare);
		}
	}
}

  • 1 — объявляем пакет.
  • 3 — импортируем класс Sprite из базового пакета flash.display.
  • 4 — объявляем новый класс Board наследующий Sprite.
  • 8-9 — объявляем переменную типа Square и записываем в неё ссылку на только что созданный объект типа Square.

В строке 9 “аттачим” “клип” aSquare к инстации Document Class, которая служит “рутом”.
Обратите внимание ,что для вызова конструктора Square() – не нужно ничего импортировать ( как это нужно было для создания Board наследника Sprite) потому, что все классы созданные в билиотеке являются Top Level и общедоступны для всего приложения. Так же в любом месте программы нам не нужно импортировать класс Board, так как он находится в “верхнем” TopLevel пакете.

Усложняем пример, создаём в библиотеке новый символ, например кружок поменьше квадратика, и ассоциируем его с классом Round.
Создём в одном фолдере вместе с .fla файлом, файл Board.as:

package
{	
	import flash.display.Sprite;
	import flash.utils.setTimeout;

	public class Board extends Sprite
	{
		var aSquare:Square;
		var aRound:Round;
		function Board()
		{
			this.aSquare = new Square();
			this.aRound = new Round();
			trace(this.aSquare.parent);				//	null
			trace(this.aRound.parent);				//	null
			flash.utils.setTimeout(this.addToBoard, 1000);
			flash.utils.setTimeout(this.addToSquare, 2500);
		}
		function addToBoard():void
		{
			this.aSquare.x = this.aSquare.y = 100;
			this.addChild(this.aSquare);
			this.addChild(this.aRound);
			trace(this.aSquare.parent);		//	[object Board]
			trace(this.aRound.parent);		//	[object Board]
		}
		function addToSquare():void
		{
			this.removeChild(this.aRound);		
			trace(this.aRound);		//	null
			this.aSquare.addChild(this.aRound);
			trace(this.aSquare.parent);		//	[object Board]
			trace(this.aRound.parent);		//	[object Square]
		}
	}
}

    • 4 — импортируем функцию setTimeout из пакета flash.utils. В пакете можно объявлять не только классы но и функции, константы и т.д. Подробнее эта тема обсуждалась здесь.
    • 8-9 — объявляем пустые ссылки на будущие экземпляры классов Square и Round.
    • 12-13 — создаём объекты aRound и aSquare.
    • 14-15 — у только что созданных объектов нет родителей, и на сцене они не отображены.
    • 16-17 — функция setTimeout позволяет вызвать другую функцию через определённый промежуток времени. Вызоваем функцию addToBoard через одну секунду, а функцию addToSquare через две с половиной секунды.
    • 21 — задаём квадрату координаты 100, 100. Круг остаётся на месте (0,0).
    • 22-23 — строки – добавляем квадрат и круг на сцену. После этого они появятся на сцене. Круг в начале координат, а квадрат в точке 100, 100.
    • 24-25 — строки – родителем обоих объектов стал объект Board.

Ещё через 1,5 секунды будет вызвана функция addToSquare:

  • 29 — удаляем со сцены (Board) круг;
  • 30 — смотрим что у круга нет родителя;
  • 31 — аттачим круг в квадрат, вызывая метод addChild в объекте aSquare. Теперь круг сохранит свои координаты 0,0 внутри квадрата.
  • 32-33 — смотрим на родителей клипов aSquare и aRound.

Важный момент: мы отказались и полностью игнорируем имёна клипов. Нет необходимости отслеживать путь к объекту и юзать извращения targetPath и eval, стиль требует передавать ссылки на объекты. Например в объекте aSquare создать поле round ссылающееся на aRound.
Вообще-то если вы настоящиий AS2 программист , вы уже должны так делать =)

В AS1/2 конструктор мувиклипов приватный, это значит что вызвать его мы можем только из другого клипа. Новый клип создаётся и сразу присоединяется к родителю на указанный уровень.
Таким образом в AS1/2 мы НЕ можем создать клип без родителя. И не можем поменять родителя у уже созданного клипа.

Итог:
В AS3 “клипы” можно создавать где угодно, аттачить куда угодно и когда угодно.
Конструкции типа this['aSquare']['aRound'].targetPath() и eval(‘aSquare.aRound’) уходят в прошлое, юзаем ссылки.


02:16:02, Action Script 3
Как теперь работать с клипами ?

Что-то давно я ничего не писал , блог зафлудили спамеры, тем не менее посещаемость растёт. Последнее обстоятельство заставило меня пристыдиться и написать что-нибудь.

Разницы между AS1 и AS2 невелика, некоторые фичи API плеера (например битмап фильтры и ExternalInterface) и эмуляция ООП среды на стадии компилляции. Это именно эмуляция, компиллятор собирает из исходников AS2 код AS1. Посмотрите на параметры публикации, выберите Flash Player 6 и убедитесь что среда предалагает публикацию на двух языках AS1 и AS2.

Многие флешеры говорят что они "кодят на AS2", но большинство из них не понимают что такое ООП. Они имеют какие-то представления об этом, но пишут программы приемущественно в кадрах клипов и считают "классы" лишним наворотом большого смысла в котором видят. ООП идеология - ключевой момент, отличающий AS1 от AS2.
Если пишите программы приемущественно в кадрах, значит кодите на AS1.

Если AS1 — ваш первый язык программирования. То перейти на ActionScript 3 вам будет сложнее. Т.К. в вашем мозге (как и ранее в моём) есть вредные извилины абстрактной модели MovieClip'ов.
Если вы работали на ActionScript 2 то всё немного проще, из-за принципов ООП, которым можно научиться в ActionScript 2.
Всех флешеров AS1, смутит новая модель работы с клипами.

Раньше приаттачить клип из библиотеки можно было так:

1. cоздали новую копию символа linkageId
2. создали новую переменную clipName в клипе clip.
Процесс довольно не привычный для программиста. Двумя строковыми литералами мы создаём переменную непонятного типа в объекте clip.

В Actions Script 3 логика больше соответсвует стандартам.
Что бы создать какой-то графический элемент и разместить его на сцене нужно:

1. Создать новый сомвол в библиотеке и нарисовать что-то в этом символе.
2. Ассоциировать созданный символ с классом:
Просто щёлкните правой кнопкой на символе в билиотеке, выберите Linkage. В открывшемся окне поставьте галочку Export for ActionScript.
В подсветившемся поле "Class" введите название класса.
3. Создать инстанцию класса и приаттачить куда нужно методом addChild().

Допустим вы создали в библиотеке символ и ассоциировали его с классом Square.

  • 1 — объявляем пакет.
  • 3 — импортируем класс Sprite из базового пакета flash.display.
  • 4 — объявляем новый класс Board наследующий Sprite.
  • 8-9 — объявляем переменную типа Square и записываем в неё ссылку на только что созданный объект типа Square.

В строке 9 "аттачим" "клип" aSquare к инстации Document Class, которая служит "рутом".
Обратите внимание ,что для вызова конструктора Square() - не нужно ничего импортировать ( как это нужно было для создания Board наследника Sprite) потому, что все классы созданные в билиотеке являются Top Level и общедоступны для всего приложения. Так же в любом месте программы нам не нужно импортировать класс Board, так как он находится в "верхнем" TopLevel пакете.

Усложняем пример, создаём в библиотеке новый символ, например кружок поменьше квадратика, и ассоциируем его с классом Round.
Создём в одном фолдере вместе с .fla файлом, файл Board.as:

  • 4 — импортируем функцию setTimeout из пакета flash.utils. В пакете можно объявлять не только классы но и функции, константы и т.д. Подробнее эта тема обсуждалась здесь.
  • 8-9 — объявляем пустые ссылки на будущие экземпляры классов Square и Round.
  • 12-13 — создаём объекты aRound и aSquare.
  • 14-15 — у только что созданных объектов нет родителей, и на сцене они не отображены.
  • 16-17 — функция setTimeout позволяет вызвать другую функцию через определённый промежуток времени. Вызоваем функцию addToBoard через одну секунду, а функцию addToSquare через две с половиной секунды.
  • 21 — задаём квадрату координаты 100, 100. Круг остаётся на месте (0,0).
  • 22-23 — строки - добавляем квадрат и круг на сцену. После этого они появятся на сцене. Круг в начале координат, а квадрат в точке 100, 100.
  • 24-25 — строки - родителем обоих объектов стал объект Board.
  • Ещё через 1,5 секунды будет вызвана функция addToSquare:

  • 29 — удаляем со сцены (Board) круг;
  • 30 — смотрим что у круга нет родителя;
  • 31 — аттачим круг в квадрат, вызывая метод addChild в объекте aSquare. Теперь круг сохранит свои координаты 0,0 внутри квадрата.
  • 32-33 — смотрим на родителей клипов aSquare и aRound.

Важный момент: мы отказались и полностью игнорируем имёна клипов. Нет необходимости отслеживать путь к объекту и юзать извращения targetPath и eval, стиль требует передавать ссылки на объекты. Например в объекте aSquare создать поле round ссылающееся на aRound.
Вообще-то если вы настоящиий AS2 программист , вы уже должны так делать =)

В AS1/2 конструктор мувиклипов приватный, это значит что вызвать его мы можем только из другого клипа. Новый клип создаётся и сразу присоединяется к родителю на указанный уровень.
Таким образом в AS1/2 мы НЕ можем создать клип без родителя. И не можем поменять родителя у уже созданного клипа.

Итог:
В AS3 "клипы" можно создавать где угодно, аттачить куда угодно и когда угодно.
Конструкции типа this['aSquare']['aRound'].targetPath() и eval('aSquare.aRound') уходят в прошлое, юзаем ссылки.


2007-03-16

12:14:10, Junik
Изменение цвета прелоадера flex приложения

Недавно наткнулась на проблему изменения цвета прелоадера flex приложения. Это, тот прелоадер, который flex автоматически показывает во время инициализации приложения. Сама не смогла догадаться, как это сделать, решение нашла тут. Для тех, кому лень переводить, вкратце перескажу.
Цвет фона прелоадера приложения задается в HTML в теге object embed в атрибуте bgcolor.
Предлагаются два варианта:

  1. Отредактировать свойства компиляции проекта в Flex Builder
  2. Прописать атрибут прямо в свой HTML файл

Чтобы задать цвет в Flex Builder необходимо выбрать свойства проекта и там на вкладке Flex Compiler дописать строку “-default-background-color #336699″ в Additional compiler arguments.


04:08:30, Korax Flash
Готов A3 JTable

Ребята из aswing.org выпустили на всеобщее обозрение A3 JTable

Этот год сулит новое “программистское щастье”:

  • Flex Builder => IDEA
  • MXML => ASML
  • MX Компоненты => AsWing (Open Source Flash ActionScript GUI framework and library)

До кучи осталось забрать производство Flash Player Runtime из нерасторопных рук Адобовских программистов и заодно повысить скорость исполнения апликух в 50-100 раз и наконец сделать мультиязычный инсталлятор.


2007-03-03

07:34:48, Agahov's blog
Публичные переменные в классе flash.geom.Point

Дополнение к посту «Публичные переменные это зло… »
Постараюсь более подробно раскрыть проблему реализации системного класса flash.geom.Point.

Изучим структуру flash.geom.Point:

  1. var myTestPoint : Point = new Point(9,9);
  2. trace(describeType(myTestPoint));

в данные момент меня интересуют две строчки, которые говорят что свойства x, y класса flash.geom.Point, описаны как публичные переменные


variable name="x” type="Number”

variable name="y” type="Number”

какие проблемы это вызывает?

Отсутствует возможность переопределить данные свойства в классе потомке.

Пример 1:

  1. Point;
  2.  
  3.         public class MyPoint extends Point
  4.         {
  5.                
  6.                 public function set x (v:Number)
  7.                 {
  8.                         x = v;
  9.                 }
  10.         }
  11. }

error: 1024: Overriding a function that is not marked for override.

Пример 2:

  1. package
  2. {
  3.         import flash.geom.Point;
  4.  
  5.         public class MyPoint extends Point
  6.         {
  7.                
  8.                 public override function set x (v:Number)
  9.                 {
  10.                         x = v;
  11.                 }
  12.         }
  13. }

error: 1023: Incompatible override.

Следовательно для реализации, например, интерфейса IPoint

  1. package
  2. {
  3.         public class IPoint
  4.         {
  5.                
  6.                 function set x (v : Number) : void;
  7.                 function get x () : Number;
  8.                
  9.                 function set y (v : Number) : void;
  10.                 function get y () : Number;
  11.                
  12.         }
  13. }

нельзя использовать использовать наследование

  1. public class MyPoint extends Point implements IPoint

придется использовать делегацию:

  1. package
  2. {
  3.         import flash.geom.Point;
  4.  
  5.         public class MyPoint implements IPoint
  6.         {
  7.                
  8.                 private var _point : Point;
  9.                
  10.                 public function MyPoint ()
  11.                 {
  12.                         _point = new Point();
  13.                 }
  14.                
  15.                 public function set x (v:Number):void
  16.                 {
  17.                         _point.x = v;
  18.                 }
  19.                 public function get x ():Number
  20.                 {
  21.                         return _point.x;
  22.                 }
  23.                
  24.                
  25.                 public function set y (v:Number):void
  26.                 {
  27.                         _point.y = v;
  28.                 }
  29.                 public function get y ():Number
  30.                 {
  31.                         return _point.y;
  32.                 }
  33.                
  34.         }
  35. }

Делегация в данном случае не оправдана, так как класс MyPoint нельзя будет использовать в методах работающих с Point. Вокруг стандартных методов придётся писать обёртки или использовать преобразование.

Пример преобразования:

  1. var Rect:Rectangle = new Rectangle(0,0, 100, 100);
  2. Rect.offsetPoint( new Point(myPoint.x, myPoint.y) );

Пример обертки:

  1. package
  2. {
  3.         import flash.geom.Rectangle;
  4.         import flash.geom.Point;
  5.  
  6.         public class MyRectangle extends Rectangle
  7.         {
  8.                
  9.                 public function offsetIPoint ( point : IPoint)
  10.                 {
  11.                         offsetPoint (new Point ( point.x, point.y ));
  12.                 }
  13.                
  14.         }
  15. }

06:02:14, Agahov's blog
flex-coding-guidelines

Fabio Terracini опубликовал в рассылке FlexCoders рекомендации по оформлению кода для Flex (AS3, MXML, CSS).
ссылка на pdf файл.

Данный документ основан на соглашениях используемых в Adobe Flex libararies, Java
и работе Fabio в DClick.


2007-02-23

00:40:25, Korax Flash
Исследование AVM и Garbage Collector

По ссылке http://flash.korax.ru/demo/ethereal/ethereal.html
я выгрузил свои тесты GC, с использованием таймера с ослабленными связями (Week Reference Timer). Такой таймер позволяет проследить за удаленными объектами (другого способа пока не знаю). Это актуально в крупных приложениях, когда крупные объекты очень часто создаются и удаляются (типа пользовательского многооконного приложения). Основное правило таких приложений - это продолжительная и стабильная работа. Естественно, что утечки по памяти в приложении приводят к дестабилизации работы системы.

Несколько выводов, которые мне удалось сделать из тестов:

  1. Объекты не содержащие кроссвязей удаляются моментально, при пересоздании объекта (re new).
  2. Очень странно, но зануление ссылки, приводит к временной задержке окончательного освобождения памяти занимаемой объектом (вне завиcимости от кроссвязей). Это стало причиной моих ошибочных умозаключений о неубиваемости объекта. Причина, по которой VM так работает - мне не ясна!
  3. Объекты содержащие кроссвязи, при зачистке ссылки, живут непредсказуемое кол-во времени, но как правило удаляюся из памяти единомоментно.
  4. Работающий в объекте StrongReference-таймер оставляет объект “вечно живым”. В принципе так и должно быть. Но если StrongReference-таймер инициализирован, и листенеры установлены, но таймер не запущен или остановлен, тогда в отсутствии ссылок объект будет удалён.

Всё-таки, как мне кажется, если в приложении есть “тяжёлые”, многократно пересоздаваемые объекты, лучше доводить счетчик ссылок (Reference Counter) до единицы перед зачисткой “главной” ссылки объекта.

Все мои попытки создать чрезвычайно сложный неубиваемый пул объектов (с Reference Counter поднятым от 100 до 200) со множествственными связями (кольцевыми, иеархаическими, в массивах, полях) не увенчался успехом. Мощный однако анализатор кроссвязей у VM!

Может кому-нибудь другому удастся :)


2007-02-12

09:29:35, Graann's blog
Юбилей :)

сабж


2007-02-07

14:51:41, Graann's blog
Формат даты в DateTimeAxis

При работе с чартингом, одной из осей которого является DateTimeAxis, часто возникает потребность в изменении формата отображения меток. Как я поняла в ходе общения с кодом DateTimeAxis, сам флекс не меняет формат даты в зависимости от локали. По умолчания дата отображается в формате m/d/yy. Для российского глаза такое отображение несколько непривычно. Хелп предоставляет два пути решения этой проблемы.
1. labelFunction:Function [read-write]
Called to format axis values for display as labels. A labelFunction has the following signature:

  1. function labelFunction(labelValue:Object, previousValue:Object, axis:IAxis):String


If you know the types of the data your function will be formatting, you can specify an explicit type for the labelValue and previousValue parameters.

Казалось бы вот оно счастье, однако поспешность в выборе может послужить для вас причиной дополнительного геморроя. Качественная замена функции дело довольно муторное. Ведь интервал между метками может составлять как секунды так и годы. Куча кода. Рекомендую с негодованием отвергнуть эту веселую перспективу и обратить свой взор к пункту 2.

2. В хелпе есть такое понятие как Protected Methods. Для человека пришедшего из AS2 и не озаботившегося ознакомлением с матчастью AS3 такое буквосочетание может показаться слабо информативным, однако белые люди сжевавшие в процессе общения с флексом уже не одну pdf-ную страницу в курсе что Protected Methods - методы класса которые можно переопределять в наследниках. Часто большинство этих методов скрыто в недрах хелпа в аккордеоне с надписью “Show Inherited Protected Methods", однако это не наш случай. Интересующие нас сейчас методы DateTimeAxis на виду:

  1. formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
  2. formatMilliseconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  3. formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
  4. formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
  5. formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  6. formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String

Разумеется прежде чем переопределять их в соответствии с вашими пожеланиями следует ознакомиться с исходным кодом DateTimeAxis. Там за вас уже все придумали и написали:

  1. protected function formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String
  2. {
  3.         var fy:Number = d[fullYearP];
  4.         return fy.toString();
  5. }
  6. protected function formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
  7. {
  8.         var fy:Number = d[fullYearP];
  9.         return (d[monthP] + 1) + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
  10. }
  11. protected function formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
  12. {
  13.         var fy:Number = d[fullYearP];
  14.         return (d[monthP] + 1) + "/" + d[dateP] + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
  15. }
  16. protected function formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
  17. {
  18.         return d[hoursP] + ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]);
  19. }
  20. protected function formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  21. {
  22.         return d[hoursP]+ ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]) + ":" + (d[secondsP] < 10 ? "0" + d[secondsP] : d[secondsP]);
  23. }

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

Кстати. Если вдруг получившиеся в ходе переопределения методов метки будут натыкаться друг на друга и делать подписи абсолютно нечитаемыми следует воспользоваться методом reduceLabels(intervalStart:AxisLabel, intervalEnd:AxisLabel):AxisLabelSet, а никак не свойством interval : Number, как это может захотеться с первого взгляда. Но это уже совсем другая история…


2007-02-03

15:49:14, Agahov's blog
Пример неудачного, использования CairngormEventDispatcher

Краткое описание действующих лиц.

Паттерны программирования
http://en.wikipedia.org/wiki/Design_pattern_(computer_science)
http://zeus.sai.msu.ru:7000/SE/project/pattern/index.shtml
http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/singleton.htm
http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/patterns/

J2EE (Java 2 Enterprise Eddition)
http://ru.sun.com/java/j2ee/index.html
http://www.codenet.ru/webmast/java/j2ee.php

J2EE Patterns
http://java.sun.com/blueprints/patterns/catalog.html
http://www.patterndepot.com/put/8/JavaPatterns.htm

Cairngorm Микро архитектурный фреймворк, основанный на J2EE паттернах, адаптированных для flex /flash (ria). Т.е. это реализация нескольких паттернов для flex и общая рекомендация о связке между ними.

CairngormEventDispatcher – Централизованный диспетчер событий, Singleton.
Позволяет послать событие из любой точки программы.

CairngormEvent – пользовательское событие, его можно переопределить для отсылки данных вместе с событием.
MyEvents.MY_EVENT – имя пользовательского события, которое ассоциируется с командой.

отсылаем событие:

  1. var theMyEvent : CairngormEvent = new CairngormEvent( MyEvents.MY_EVENT );
  2. CairngormEventDispatcher.getInstance().dispatchEvent ( theMyEvent );

Архитектура Cairngorm подразумевает, что обработка этих событий будет реализована через FrontController, который определяет соответствие событий и команд(ICommand). Другими словами, обработка реакции на события происходит централизованно.

Но существует возможность подписаться на это событие в любом месте приложения. Без использования команд и FrontController.

подписываемся на событие без использования комманд:

  1. CairngormEventDispatcher.getInstance().addEventListener ( MyEvents.MY_EVENT, MySuperHandler );

На первый взгляд данная возможность впечатляет: кто угодно может обратиться к кому угодно из любой точки приложения.

Но если Вы напишите достаточно много таких вызовов, то потеряете контроль над своим приложением. Особенно, если работаете в команде над общим кодом.
Первая проблема, которую я вижу, это циклический вызов. Остальные предоставлю вам найти самостоятельно, если всё же решите использовать данную конструкцию.


2007-01-13

08:57:31, Action Script 3
Своя TopLevel функция.

В некоторых встроенных пакетах flash, например в пакете flash.utils, есть свои функции. Импортируя пакет с функцией мы можем её вызвать без указания класса.
Просто наугад попробовал объявить функцию вне класса. Сработало ! :) . Странно что нигде не встречал подобных примеров:

Оператор
callTopLevel(); - сработает в любом месте программы.

Аналогично можно объявить функцию в пакете и импортировав пакет , получить к ней доступ

Можно разместить или в любом файле с используемом классом, или создать файл с карширением .as, одноимённый с функцией:

Этот момент не принципиален, но приятен :)
Можно создать удобные функции для форматирования строк, чисел или функции для ведения каких-то журналов, свой трейс например. Можно перенаправлять трейс. Т.е. вместо trace() к примерую зать out(). А в теле out можно делегировать аргуметы функции trace() и в нужный момент, заменяя пару строк, скомпиллировать для ведения своего отчёта.


08:08:15, Action Script 3
Своя TopLevel функция.

В некоторых встроенных пакетах flash, например в пакете flash.utils, есть свои функции. Импортируя пакет с функцией мы можем её вызвать без указания класса.
Просто наугад попробовал объявить функцию вне класса. Сработало ! :) . Странно что нигде не встречал подобных примеров:

package
{
      import flash.display.Sprite;

      public class TopLevelTest extends Sprite
      {
             callTopLevel();
      }

      public function callTopLevel():void
      {
          trace("i am TopLevel function");
      }
}

Оператор

callTopLevel(); – сработает в любом месте программы.

Аналогично можно объявить функцию в пакете и импортировав пакет , получить к ней доступ

package
{
      import functions.callFnc;
      import flash.display.Sprite;

      public class FncTest extends Sprite
      {
             callFnc();
      }
}

Можно разместить или в любом файле с используемом классом, или создать файл с карширением .as, одноимённый с функцией:

package functions
{
      public function callFnc():void
     {
            trace('calling Fnc');
     }
}

Этот момент не принципиален, но приятен :)
Можно создать удобные функции для форматирования строк, чисел или функции для ведения каких-то журналов, свой трейс например. Можно перенаправлять трейс. Т.е. вместо trace() к примерую зать out(). А в теле out можно делегировать аргуметы функции trace() и в нужный момент, заменяя пару строк, скомпиллировать для ведения своего отчёта.


2006-12-29

19:13:51, Action Script 3
Обзор Flash alpha 9. Document class.

Пожалуй начнём с Flash IDE, уверен что более 80% процентов читающих статью и понятия не имеют о других IDE (а может и вовсе не знают что такое IDE ). Поэтому нее буду вас распугивать флексом и FDT :) .
Я считаю, имеет смысл сначала познакомиться с AS3 хоть чуть-чуть, а потом пробовать Flex.

Итак, у вас уже установлена Flash 9 alpha ( если нет, скачайте её здесь
). В принципе, это та же восьмёрка, только теперь мы можем творить в ней AS3 (при желании, в параметрах публикации можно изменить версию AS, только помните что AS1/2 и AS3 не совместимы).
Ну вот вы открыли IDE и хотите что-то сделать, нарисовать что-то , пару строк кода написать.... Не всё так просто.
Лучше забудьте о панели Actions, вообще. Теперь всё держится на классах, а писать код в кадрах клипов просто опасно....
Т.к. он иногда неправильно компиллируется. Представьте себе, вы написали несколько функций в кадре, например у вас 300 строк. Но в один прекрасный момент всё перестало работать, вы даже можете найти строчку при изменении которой происходит сбой. Какая-нибудь совсем безобидная строка типа:

Короче, забыли писать код в кадрах, договорились ? :)

Ну и где писать код ?

Давайте созданим новый флэш документ, сохраним его в какой-нибудь фолдер. А теперь посмотрим, что нового у нас появилось на панели properties:
Синяя рамка - фокус на поле Document class
Добавилось одно новое поле Document class (выделено синим). Это имя класса, который будет у нас "рутом" (вобще-то в AS3 понятие root приобрело несколько иной смысл).
И что это значит ?
Значит это то , что мы должны создать где-то класс и записать его полное имя здесь.
Если из предыдущего и дальнейших предложений нифига не понятно, ничего страшного. Не ЗАКРЫВАЙТЕ страничку и не вздыхайте "Ну вот блин, опять классы.... Куда уж мне". Просто копипастите код и интуитивно всё будет понятно :) .
В ближайшее время опишу или дам линки на хорошее описание классов, объектов и прочих умных слов.

Попробуем создать такой класс, что бы у нас заработал хоть какой-то код.
Для этого:
1. Создаём где-нибудь файл .as с классом.
2. Вносим полное имя класса в поле Document class.
3. Тестируем.

Проще всего заставить работать функцию trace();

Создадим в фолдере с нашим .fla файл Tracer.as. В котором запишем

Теперь идём в окошко нашего .fla и тестируем.


08:03:15, Action Script 3
Обзор Flash alpha 9. Document class.

Пожалуй начнём с Flash IDE, уверен что более 80% процентов читающих статью и понятия не имеют о других IDE (а может и вовсе не знают что такое IDE ). Поэтому не буду вас распугивать флексом и FDT :) .
Я считаю, имеет смысл сначала познакомиться с AS3 хоть чуть-чуть, а потом пробовать Flex.

Итак, у вас уже установлена Flash 9 alpha (если нет, скачайте её здесь). В принципе, это та же восьмёрка, только теперь мы можем творить в ней AS3 (при желании, в параметрах публикации можно изменить версию AS, только помните что AS1/2 и AS3 не совместимы).
Ну вот вы открыли IDE и хотите что-то сделать, нарисовать что-то , пару строк кода написать…. Не всё так просто.
Лучше забудьте о панели Actions, вообще. Теперь всё держится на классах, а писать код в кадрах клипов просто опасно….
Т.к. он иногда неправильно компиллируется. Представьте себе, вы написали несколько функций в кадре, например у вас 300 строк. Но в один прекрасный момент всё перестало работать, вы даже можете найти строчку при изменении которой происходит сбой. Какая-нибудь совсем безобидная строка типа:

var a:Number = b;

Короче, забыли писать код в кадрах, договорились ? :)

Ну и где писать код ?

Давайте созданим новый флэш документ, сохраним его в какой-нибудь фолдер. А теперь посмотрим, что нового у нас появилось на панели properties:

DocumentClass2

 

Добавилось одно новое поле Document class (выделено синим). Это имя класса, который будет у нас “рутом” (вобще-то в AS3 понятие root приобрело несколько иной смысл).
И что это значит ?
Значит это то , что мы должны создать где-то класс и записать его полное имя здесь.
Если из предыдущего и дальнейших предложений нифига не понятно, ничего страшного. Не ЗАКРЫВАЙТЕ страничку и не вздыхайте “Ну вот блин, опять классы…. Куда уж мне”. Просто копипастите код и интуитивно всё будет понятно :).
В ближайшее время опишу или дам линки на хорошее описание классов, объектов и прочих умных слов.

Попробуем создать такой класс, что бы у нас заработал хоть какой-то код.
Для этого:
1. Создаём где-нибудь файл .as с классом.
2. Вносим полное имя класса в поле Document class.
3. Тестируем.

Проще всего заставить работать функцию trace();

Создадим в фолдере с нашим .fla файл Tracer.as. В котором запишем

package
{
import flash.display.Sprite;
public class Tracer extends Sprite
{
public function Tracer()
{
trace('Я Tracer. Я буду здесь рутом :)');
}
}
}

Теперь идём в окошко нашего .fla и тестируем.


2006-12-28

17:49:04, Action Script 3
Нетипизированный массив, как с этим бороться ? Часть - 1

Для начала привожу цитату Nirth'а:

Дело в том, что в таких забавных и пушистых языках, как например Java или C++, массивы являются инвалидами по сравнению с их братьями в ActionScript, например массив может хранить себе только экземпляры одного типа( только числа, только строки, только текстовые поля), и его размер задается в начале, и его нельзя увеличить. Спасением несчастным программистам были КОЛЛЕКЦИИ, которые позволяли хранить экземпляры разных типов (если надо было), размер их был динамическим, их можно было фильтровать и сортировать, и вообще работать с ними было в радость.

Действительно, радость. Разработчики подарили нам один тип - Array, который делает всё и сразу, благодаря чему флешерам приходится меньше думать....
А теперь о плохом.

Сила AS 3 кроется в типизации, потому, что плеер не тратит время на определение типов. Обращение к полям ссылки с дифинированным типом, происходит намного быстрее. Однако с динамическими объектами всё осталось по-прежнему. Объявив динамически переменную , мы не можем задать ей тип.
Отсюда низкая скорость обработки элементов массива.
Иногда нужно обработать оромное количество элементов, здесь "умный" массив нас конкретно обламывает.
Возьмём такой вот класс:

Допустим, у нас есть огромный массив объектов этого типа. Нам нужно в каждом объекте нужно найти сумму a+b+c и записать в переменную sum.
Решим это несколькими способами

Плеер тратит кучу времени на поиск типа, но мы можем ему помочь сделать это побыстрее :)

Т.е. явно преобразуя тип и убрав сравнение с длиной массива, мы сократили время в 40 (!) раз.
Обратите внимание, если написать вместо var n:Number , просто n = 0,(если мы инициализируем не типизированную переменную) проиграем в несколько раз самому первому опыту.

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

var m1:My;
var m2:My;
...

А вот куда:

Добавим в класс My переменную next.


Как видите у этого способа есть существенный недостаток - мы не можем выбрать произвольный элемент в цепочке. Есть мысли обойти этот недостаток, ноя не готов ещё их опубликовать
В конечном итоге мы ускорили выполение скрипта в 1755/25 = 70,2 раза.

Следует отметить, что на AS2 самый оптимизированный вариант, с в 10 раз меньшим количеством элементов (у меня 1 000 000 повисает и никогда не досчитывается) , занимает более 950 милисекунд. Т.е. здесь AS3 быстрее AS2 более чем в 380 раз.


07:59:22, Action Script 3
Нетипизированный массив, как с этим бороться ? Часть &#8211; 1

Для начала привожу цитату Nirth’а:

Дело в том, что в таких забавных и пушистых языках, как например Java или C++, массивы являются инвалидами по сравнению с их братьями в ActionScript, например массив может хранить себе только экземпляры одного типа( только числа, только строки, только текстовые поля), и его размер задается в начале, и его нельзя увеличить. Спасением несчастным программистам были КОЛЛЕКЦИИ, которые позволяли хранить экземпляры разных типов (если надо было), размер их был динамическим, их можно было фильтровать и сортировать, и вообще работать с ними было в радость.

Действительно, радость. Разработчики подарили нам один тип – Array, который делает всё и сразу, благодаря чему флешерам приходится меньше думать….
А теперь о плохом.

Сила AS 3 кроется в типизации, потому, что плеер не тратит время на определение типов. Обращение к полям ссылки с дифинированным типом, происходит намного быстрее. Однако с динамическими объектами всё осталось по-прежнему. Объявив динамически переменную , мы не можем задать ей тип.

Отсюда низкая скорость обработки элементов массива.
Иногда нужно обработать оромное количество элементов, здесь “умный” массив нас конкретно обламывает.
Возьмём такой вот класс:

package
{
	public class My
	{
		public var a:Number = 0;
		public var b:Number = 0;
		public var c:Number = 0;
		public var sum:Number = 0;
	}
}

Допустим, у нас есть огромный массив объектов этого типа. Нам нужно в каждом объекте нужно найти сумму a+b+c и записать в переменную sum.
Решим это несколькими способами

//задаём массив :
 var ar:Array = []; var i:int = 0;
 while( i < 1000000){
	 ar[i] = new My();
	 ar[i].a = Math.random()*100;
	 ar[i].b = Math.random()*100;
	 ar[i].c = Math.random()*100;
	 i+=1;
 }

// пробегае по массиву, подсчитывая то, что нужно
 var t:int = getTimer();   i = 0;
 while( i < ar.length){
	ar[i].sum = ar[i].a + ar[i].b + ar[i].c;
	i+=1;
 }
 trace(getTimer()-t);  // 1755

Плеер тратит кучу времени на поиск типа, но мы можем ему помочь сделать это побыстрее :)

var ar:Array = []; 
 var i:int = 0;
 var m:My = new My();
 while( i < 1000000){
	 m = new My();
	 m.a = Math.random()*100;
	 m.b = Math.random()*100;
	 m.c = Math.random()*100;
	 ar.push(m);
	 i+=1;
 }

// пробегае по массиву, подсчитывая то, что нужно
 var t:int = getTimer();   i = 0; var l:int = ar.length;
 while( i < l){
        m = ar[i];
	m.sum = m.a + m.b + m.c;
	i+=1;
 }
 trace(getTimer()-t);   // 45

Т.е. явно преобразуя тип и убрав сравнение с длиной массива, мы сократили время в 40 (!) раз.
Обратите внимание, если написать вместо var n:Number , просто n = 0,(если мы инициализируем не типизированную переменную) проиграем в несколько раз самому первому опыту.

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

var m1:My;
var m2:My;

А вот куда:

Добавим в класс My переменную next.

package
{
	public class My
	{
		public var next:My = null;
		public var a:Number = 0;
		public var b:Number = 0;
		public var c:Number = 0;
		public var sum:Number = 0;
	}
}

// создаём объекты ссылающиеся друг на друга поцепочке. 
var m:My = new My();
var i:int = 0;
var prevElement:My;
while( i <= 1000000){	
	m = new My();
	m.a = Math.random()*100;
	m.b = Math.random()*100;
	m.c = Math.random()*100;
 	if(i != 0) prevElement.next = m;
	else firstElement = m;
	prevElement = m;
	i+=1;
}

// переходим в начало цепи и работаем с каждым элементом последовательно
var t:int = getTimer(); i = 0;
m = firstElement;
// мы викинули счётчик и сравнение
while(m != null){
	m.sum = m.a + m.b + m.c;
        // и избавились от конвертации и проверки типов
	m = m.next;
}
trace(getTimer()-t);   // 25

Как видите у этого способа есть существенный недостаток – мы не можем выбрать произвольный элемент в цепочке. Есть мысли обойти этот недостаток, ноя не готов ещё их опубликовать
В конечном итоге мы ускорили выполение скрипта в 1755/25 = 70,2 раза.

Следует отметить, что на AS2 самый оптимизированный вариант, с в 10 раз меньшим количеством элементов (у меня 1 000 000 повисает и никогда не досчитывается) , занимает более 950 милисекунд. Т.е. здесь AS3 быстрее AS2 более чем в 380 раз.

 

 


2006-12-25

12:09:33, Agahov's blog
Публичные переменные...это зло

Вместо публичных переменных, нужно использовать свойства (get/set).
Как миниму, свойства позволяют контролировать доступ к внешним переменным класса.
Отход от этой практики приводит к нескольким проблемам. Особенно заметных в публичных библиотеках.

Примером НЕ использования свойств может служить стандартный класс as3 flash.geom.Point, в котором атрибуты x и y определены как публичные переменные.

Что из этого следует ?
Теперь нельзя переопределить поведение атрибутов x и y в классе наследнике.
Нельзя сделать интерфейс IPoint, c нормальными свойствами, для класса наследника Point, следовательно нельзя организовать множественное наследование от Point.

Как с этим жить?
1) Сделать свой класс который не наследуется, от Point, а включает его, этот вариант решает проблемы для работы с новыми классами принимающими IPoint но,
с методами которые принимают Point работать будет тяжело.
В дополнение придётся прописать у CustomPoint свойство get point,
возвращающее Point для передачи и set point для применения значения. О передаче значения по ссылке придётся забыть.

2)Ещё как вариант сделать обёртки над классами принимающими Point, поменять их на IPoint, но это сразу видно работа не благодарная…

так, что без кровного решения проблемы я пока не нашел….


2006-12-21

11:32:53, Action Script 3
Плавная кнопка

Итак, у вас есть клип кнопки, вы красиво нарисовали все переходы. На тайм лайне вы рассчитали как кнопка красиво переливаясь принимает положения up, over, down....
Этот класс поможет создать плавно меняющуюся кнопку.

Для начал вам нужен тайм лайн с клипом. В этом клипе должны быть кадры с метками up, over, down. На этих кадрах и будут фиксированные положения кнопки. Между кадрами может быть MotionTween. Пример можете скачать здесь.

Класс:

SoftButton(button:MovieClip, toggle:boolean)
Что бы создать кнопку, передайте конструктору клип с кнопкой ( не забудьте расставить метки up, over, down на нужных кадрах) -

Что бы создать кнопку с залипанием (toggle) - передайте конструктору значение true вторым параметром

Свойства
data:Object [read-write]
Можете добавить любые данные к кнопке. Так удобнее работать, особенно когда у вас несколько кнопок.

selected:Boolean [read-write]
Кнопка выбрана/не выбрана. Selected может принять значение true, только если свойство toggle равно true. Иначе присвоение selected = true - игнорируется без генерации ошибки.
Когда selected принимает true, клип с кнопкой начинает идти к кадру "down".

toggle:Boolean [read-write]
Залипание. Можно менять после создания кнопки. После присвоения значения false, свойство selected так же принимает значение false.

Создание radioButton группы

Для работы с примером скачайте архив с классами кнопок


07:27:34, Action Script 3
Отрезки, точки, измерение углов

Выложу несколько классов для работы с геометрией, которые я часто использую.
Прежде чем проверять примеры, создайте фолдер со всеми классами из этой статьи (APoint, Angle и Edge).Для начала маленький класс для угла.

Всё что он делает - скрывает реализацию конвертации углов в радианы и наоборот и перенаправляет методы класса Math - sin(), cos(), tan(). Мне кажется более логичным обращаться к синусу угла так

чем

Вот класс, ничего сложного, в описании не нуждается. Один момент - класс автоматически округляет значения углов в радианах до пятого знака (можно поменять точность) при сравнении.

Используется тривиально. Лишнего описания не требуется

Класс точки:

distance(p:APoint):Number
Методы distance и to - дублируют метод Point.distance(p1, p2). Мне кажется более логичным делегировать статический метод класса объекту, хотя это ваше дело.

angle(p1:APoint, p2:APoint, [p3:APoint]):Object
Метод angle - возвращает угол образованный тремя точками. Вершиной угла в функции выступает инстанция точки, в которой вызвали метод.

опционально можно указать третий агрумент - точку, которая лежит внутри угла. Дело в том, что функция angle() - возвращает НЕ развернутый угол. Т.е. меньший , если конечно же три точки не лежат на одной прямой.
Иногда бывает нужно узнать развернутый угол. Например в невыпуклом многоугольнике. Для этого нужно указать третьим параметром точку лежащую внутри угла.

А вот класс отрезка или, как это называют в зарубежной литературе, - edge. Включает в себя 4 элемента - точку начала, конечную точку (если потребуется работать с отрезком как с вектором) и коэффициенты k, b. k- угловой коэффициент, b - смещение по оси Oy.

Edge(p1:APoint, p2APoint)
В конструкторе указываем две точки, которые будут служить началом и концом отрезка.

Методы

cross(e:Edge):Object
Методом cross можно определить пересекаются ли отрезки или нет, если пересекаются , то как. Этот метод принимает один аргумент - отрезок (инстанцию класса Edge). И рассматривает все возможные случаи пересечения.
Метод возвращает объект содержащий два поля:
cross(edge).type:String - тип пересечения. Все типы пересечений перечислены в классе энумерации EdgeCross.
cross(edge).p:APoint - точка пересечения. Если отрезки не параллельны, в не зависимости от того пересекаются ли отрезки или нет, возвращается точка содержащяя координаты пересечения прямых, содержащих эти отрезки. Что очень удобно, т.к мы можем использовать класс Edge для нахождения координат пересечения двух прямых заданных двумя точками.

Свойства

b:Number [read-only]
Коэффициент смещения прямой по оси oY содержащей отрезок.

k:Number [read-only]
Угловой коэффициент прямой содержащей отрезок.

p1:APoint
p2:APoint

Начальная и конечная точки отрезка - вектора.
Во время изменения точек отрезка , происходит перерасчёт коэффициентов k и b. Эти коэффициенты часто используются при математических расчётах.

length:Number [read-only]
возвращает длину отрезка.

Правда в этом классе есть один недостаток. Если пересечением двух отрезков являться другой отрезок , то функция возвращает null вместо точки p, однако однако следовало бы возвращать отрезок.


2006-11-24

00:35:11, Agahov's blog
Ассоциация классов с объектами библиотеки во Flash 9 alpha

Речь пойдет о свойстве linkage муви клипов библиотеки или скорее его отсутствии в Flash 9.

Объектная модель графических объектов в as3 сильно изменилась.

В частности исчез метод attachMovie.

Теперь используются:

  1. mc = new MyClass();
  2. addChild (mc)

Проблема заключается в том, что в as3 нельзя назначить один класс двум различным клипам библиотеки. Компилятор не сможет определит с каким клипом ассоциировать класс.

Выходы из положения заключается в:

1) создании нескольких одинаковых классов, с различными именами например от общего родителя;

2)Пожалуй единственный способ который не создает одинаковые классы это загрузка внешнего swf;

3)Также возможно включать внешний ресурс для класса:

  1. package
  2. {
  3.    import flash.display.Sprite;
  4.    
  5.    [Embed(source="assets/map1.swf")]
  6.    public class Map1 extends Sprite
  7.    {
  8.       public function Map1 ()
  9.       {
  10.       } 
  11.    }
  12. }

4) Использовать Embed, для свойства,
(swf должна быть сделана с помощью более раннего fhash IDE, я использовал flash 8).

  1. package
  2. {
  3.    import flash.display.Sprite;
  4.    import flash.display.DisplayObject;
  5.  
  6.    public class MyClass extends Sprite
  7.    {
  8.  
  9.  
  10.       [Embed(source="assets/animation.swf", symbol='libSymol' )]
  11.       public var Map1:Class;
  12.  
  13.  
  14.  
  15.       public function MyClass()
  16.       {
  17.          super();
  18.          var map:DisplayObject = new Map1 ();
  19.          addChild ( map );
  20.  
  21.       }
  22.    }
  23. }


Если вам известно более красивое решение, обязательно поделитесь.

Далее следует вопрос, как эти классы использовать?


Предыдущие 30 |