Flash Ripper RSS Readers

+

12.Июль.2007

Конвейер для ActionScript3 от Евгения Потапенко

Евгений Потапенко признался, что уже месяца два как выложил ActionScript3-версию своего класса Conveyor, ставшим для многих незаменимым помощником во флэш-программировании.

По ссылке - отличнейшая статья и исходники.

Posted by: Rost at 11:16 PM | Comments (21)

02.Июль.2007

Класс MapManager для управления просмотром карт

Сообщает Ив:

Сделал менеджер карт (с примером). Это такой клас, который позволяет легко и быстро прикрутить необходимый (зум, драг) функционал к карте или к любому изображению.

Никаких комментов там нет, сорри, но мне было-бы интересно услышать основные вопросы, которые возникают в процессе прикрутки.

Ответы можно писать сразу Иву в руФлэш (или сюда).

Posted by: Rost at 02:10 PM | Comments (3)

08.Май.2007

ImageProcessing Library от Joa Ebert

Joa Ebert написал библиотеку для работы с изображениями. Чтобы понять всю ее мега мощь листаем документацию. Примеры автора: пример 1 и пример 2

Документация особо прикольная таем, что содержит картинки-иллюстрации по применению конкретных классов.

Библиотека распростряняется по лицензии Creative Commons License.

А вот еще одна жирная вещь от него же: интерактивный гончарный круг (3D-шникам известен как модификатор Lathe). И один из исходящих линков с его сайта: oos.moxiecode.com.

Автор новости -- Илья Панин.

Posted by: Rost at 06:14 PM | Comments (3)

11.Февраль.2007

Класс UISprite: один из способов поженить AS3-класс Sprite с визульными компонентами Flex Framework

Когда мы попытаемся произвести такую простую операцию, как добавление экземпляра класса Sprite во Флекс-приложение, -- нечто вроде myCanvas.addChild(new Sprite()); -- флекс ругнется и скажет нам, что добавлять можно только классы, реализующие интерфейс IUIComponent.

Это потому, что все визуальные компоненты фрэймворка Fleх этот интерфейс реализуют и работают только с аналогичными реализаторами. Такая вот замкнутая система. Как же нам втиснуться со своим скромным спрайтом в эту громаду событийно-заскинованного великолепия? Ведь Sprite как класс не реализует интерфейс IUIComponent.

Значит, нам нужен тот, кто его реализует. Здесь открывается множество путей, один из которых -- создать класс, расширяющий класс Sprite и реализующий этот самый интерфейс IUIComponent -- этот путь называется Путь Великого Наследования, он долгий и утомительный, и мы туда сейчас не пойдем. Нам ведь совсем не хочется реализовывать все 86 методов интерфейса IUIComponent (я мог ошибиться, проверьте) в этот поздний час.

Ведь есть другой путь -- композиция. Это для нашего случая. Мы используем класс, который уже реализует интерфейс IUIComponent. Я выбрал класс, который называется -- о чудо -- UIComponent! Замечательно в нем то, что его метод addChild принимает в качестве аргумента столь нужный нам спрайт.

Значит мы теперь можем решить проблему женитьбы спрайта с компонентами Flex 2 Framework. Мы скормим свой спрайт экземпляру класса UIComponent c помощью его метода addChild, и сможем пользовться нашим спрайтом, завернутым в эту оболочку.

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

package
{
import mx.core.UIComponent;
import flash.display.Sprite;

/**
* UISprite class is a wrapper class
* for adding Sprites to Flex display list as childs.
*
* @author Rostislav Siryk
*
*/
public class UISprite extends UIComponent
{
/**
* Sprite to add to display list
*/
public var mySprite: Sprite;

public function UISprite()
{
// Empty constructor
}

/**
* Adds non-flex display object as child to this UIComponent instance
*
* @param assetToSet Object to add as child
*/
public function setAsset(assetToSet: Object): void
{
mySprite = (new assetToSet());
this.addChild(mySprite);
}

/**
* Optionally sets teh hane of this UIComponent
*
* @param assetName New name of UIComponent
*/
public function setName(assetName: String): void
{
name = assetName;
}

/**
* Overrides UIComponent class width getter
* @return Width of the UIComponent as width of this mySprite child
*
*/
override public function get width():Number
{
return mySprite.width;
}

/**
* Overrides UIComponent class width setter
* @param width New width of the UIComponent as width of this mySprite child
*
*/
override public function set width(width:Number):void
{
mySprite.width = width;
}

/**
* Overrides UIComponent class height getter
* @return Height of the UIComponent as height of this mySprite child
*
*/
override public function get height(): Number
{
return mySprite.height;
}

/**
* Overrides UIComponent class height setter
* @param height New height of the UIComponent as height of this mySprite child
*
*/
override public function set height(height: Number):void
{
mySprite.height = height;
}
}
}

Пример использования:

var myUISprite = new UISprite();
myUISprite.setSprite(someSprite);
myCanvas.addChild(myUISprite);

(можно было обойтись и одной строкой кода, передавая параметр someSprite через конструктор, но я решил поддерживать подход с пустым конструктором, используемый во Flex Framework)

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

Posted by: Rost at 11:44 PM | Comments (4)

02.Февраль.2006

Класс DelegateExt, используемый для передачи аргументов вызываемой функции (AS2)

Как известно, класс Delegate позволяет выполнять любую функцию в любой заданной области видимости. Таким образом можно передавать события от любого объекта к любому другому объекту. Но иногда возникает необходимость передать не только событие, но и некоторые аргументы вместе с ним. Стандартный класс Delegate этого не предусматривает, поэтому я написал для собственных нужд класс-расширение DelegateExt, позволяющий передавать параметры вызываемой функции. Если кому-то он пригодится, буду рад. Класс пока испытан только на одном рабочем проекте, так что в случае возникновения ошибок-неполадок -- пишите сюда.

/**
* @author Rostislav Siryk (rost - at - flash-ripper.com)
*/
class com.flashripper.utils.DelegateExt{
function DelegateExt(){
}
static function create(obj:Object, func:Function, params:Object):Function {
var fExt = function(){
arguments.push(arguments.callee.args);
return func.apply(arguments.callee.target, arguments);
};
fExt.args = params;
fExt.target = obj;
fExt.func = func;
return fExt;
}
}

Кстати, в языке ActionScript 3 ни класс Delegate, ни DelegateExt не пригодится, так как в AS3 есть встроенное делегирование событий -- вот вам еще один плюс AS3.

Posted by: Rost at 09:51 PM | Comments (2)

25.Ноябрь.2005

Флэш-дизайнерам: как сделать так, чтобы свойство Scale9Grid заработало в режиме Live Preview в среде разработки Flash 8 (обновлено)

Дизайнеры всего мира были значительно обрадованы новым и очень полезным свойством мувиклипов, Scale9Grid. Те, кто уже знает, что это такое, могут пропустить этот абзац и читать дальше начиная с заголовка "Решение задачи". Тем кто не знает: свойство Scale9Grid позволяет "разбить" мувиклип четырьмя направляющими на 9 условных зон:

1 | 2 | 3
-----------------
4 | 5 | 6
-----------------
7 | 8 | 9

Такое разбиение приводит к тому, что способ масштабирования мувиклипа изменяется: теперь этот мувиклип, вместо того, чтобы масштабироваться как обычно, позволяет растягиваться только определенным зонам (2 и 8 -- только по горизонтали, 4 и 6 -- только по вертикали, 5 -- во всех двух направлениях, а углам -- 1, 3, 7 и 9 зонам -- растягиваться вообще запрещено внутренним прокурором флэш-проигрывателя). Таким образом можно добиваться сохранения скруглений углов, масштаба теней, свечений и т.п. декоративных эффектов при масштабироании мувиклипа. Вот -- хороший и красочный туториал о том, как использовать свойство Scale9Grid -- исходник прилагается!.

Но во всем этом 9-зонном великолепии есть грустный факт для дизайнеров: Scale9Grid не работает в режиме LivePreview в среде разработки -- здесь по прежнему отображается уродливо деформированное нечто. Это снижает полезность данной фичи в разы -- чтобы увидеть готовый дизайн, нужно компилировать весь проект. А мы хотим видеть результат сразу же!

Решение задачи

  1. Копируем в каталог classes/com/flashripper/utils микрокласс Scale9Grid (243 байта);
  2. Создаем мувиклип со свойством Scale9Grid обычным образом и размещаем его на сцене; (добавлено:точка регистрации клипа должна находиться в верхнем левом углу);
  3. Задаем в свойствах нашего мувиклипа "Export to ActionScript", там же -- произвольное значение для "Linkage ID" и там же -- точное значение поля "AS 2.0 class", равное "com.flashripper.utils.Scale9Grid";
  4. Кликаем по нашему мувиклипу в библиотеке правым кликом и выбираем пункт "Convert to Compiled Clip", получая таким образом откомпилированную версию нашего клипа в среде разработки.
  5. Наслаждаемся 9-зонным масштабированием Scale9Grid в среде разработки Flash 8 в режиме LivePreview.

Класс com.flashripper.utils.Scale9Grid можно использовать для любых мувиклипов с заданным свойством "Scale9Grid" сколько угодно раз.

Posted by: Rost at 02:57 PM | Comments (14)

18.Ноябрь.2005

Объекты-признаки как более эффективная замена цепочек прототипов в ActionScript 3.0

В языке ActionScript 3.0 классы представляются внутри проигрывателя как объекты класса, определяющие не только свойства и методы класса, но также и прототип и так называемые "признаки" (traits) класса, являющиеся внутренними сущностями, недоступными для прямого использования. Как вы наверняка помните из ActionScript 1-2, прототип является объектом, содержащим свойства и методы непосредственного надкласса данного класса. А поскольку прототип содержит информацию только о непосредственном надклассе, то интерпретатор ActionScript в более ранних версиях ActionScript для поиска унаследованных свойств последовательно осматривал объекты-прототипы данного класса и всех его надклассов вплоть до Object.prototype включительно. Этот способ поиска унаследованных свойств был назван цепочкой прототипов (или цепочкой наследования). В ActionScript 3.0 прототипы по-прежнему используются для реализации иерархии наследования, но для поиска идентификатора цепочка прототипов больше не используется. Все унаследованные свойства и методы экземпляра теперь хранятся в новом объекте признаков ("traits"), который избавляет от необходимости обхода цепочки прототипов для поиска свойств и методов по имени и существенно повышает производительность кода.

Предыдущие версии ActionScript предоставляли прямой доступ к объектам-прототипам в цепочке прототипов, но этого больше нет ActionScript 3.0. Теперь, когда язык предоставляет более зрелую реализацию основанного на классах программного интерфейса, "хаки" с использованием цепочки прототипов больше не допускаются. И даже более того -- оптимизация внутреннего механизма наследования, например введение объектов-признаков, обеспечивющих намного большую производительность Flash Player, сделала прямой доступ к цепочке прототипов в высшей степени непрактичным.

// via "Programming ActionScript 3.0" Alpha 1 manual

Posted by: Rost at 03:28 PM | Comments (6)

17.Июнь.2005

SmartRestrict -- класс для контроля ввода пользователя

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

Пример использования:

import com.flashripper.utils.SmartRestrict;

function onTextResult(res){
trace("Success:" + res);
}

// создаем экземпляр класса SmartRestrict,
// в качестве параметров указывая текстовое поле,
// строку, которую необходимо заставить ввести пользователя,
// функцию-обработчик результата
// и максимально допустимое кол-во неудачных попыток,
// после совершения которых приложение само
// заполнит текcтовое поле нужным значением

sr=new SmartRestrict(txtLogin, "login", onTextResult,5);

Исходный код класса:

// SmartRestrict class v 0.5.0.1 by Rostislav Siryk
// Usage: new SmartRestrict(txtFieldToRestrict:TextField, strToBeEntered:String, fncOnResult:Function, numErrorsMaxCount:Number)

import mx.utils.Delegate;

class com.flashripper.utils.SmartRestrict {

static private var dc=Delegate.create;

private var txtField:TextField;
private var strToEnter:String=String("Unknown");
private var strInProgress:String=String("");
private var numCharIndex:Number=Number(0);
private var numAttempts:Number=Number(0);
private var numAttemptsMax:Number=Number(24);
private var fncOnResponse:Function;

public function SmartRestrict(txtFieldToRestrict:TextField, strToBeEntered:String, fncOnResult:Function, numErrorsMaxCount:Number)
{
strToEnter=strToBeEntered;
txtField=txtFieldToRestrict;
fncOnResponse=fncOnResult;
if(numErrorsMaxCount) numAttemptsMax=numErrorsMaxCount;
//txtField.restrict=strToEnter;
txtField.onChanged=dc(this,onRestricted);
Selection.setFocus(txtField);
}

private function onRestricted()
{
var numCharEntered=Key.getAscii();
var numCharNeeded=strToEnter.charCodeAt(numCharIndex);
trace(numCharEntered + "-" + numCharNeeded + "/"+numAttempts);
if(numCharEntered==numCharNeeded)
{
strInProgress+=strToEnter.charAt(numCharIndex);
numCharIndex++;
}else{
numAttempts++;
}
txtField.text=strInProgress;
if(numAttempts>numAttemptsMax || strToEnter==strInProgress)
{
doFinalize();
}
}

private function doFinalize()
{
txtField.text=strToEnter;
txtField.onChanged=null;
txtField.type="dynamic";
fncOnResponse(strToEnter==strInProgress);
delete this;
}
}

Posted by: Rost at 09:10 PM | Comments (12)

21.Сентябрь.2004

SuperFades, класс для цветовых трансформаций

Bob Donderwinkel создал класс SuperFades -- Actionscript 2 класс, позволяющий производить различные цветовые трансформации над любым мувиклипом.

Скачать Superfades v1.6 | смотреть демонстрацию.
// Via Denis Sheremetov

Posted by: Rost at 07:09 PM | Comments (0)

19.Август.2004

Path -- новый полезный объект от Ивана Дембицкого

Цитата:

"Свершилось!!!!! Я бился над этим больше чем пол года. Еще сырая версия, но работает вполне корректно. Скоро приведу в порядок и... эх.... заживем!

Главное, и единственное пока, что делает Path, -- это перевод расчета позиции объекта с кривой в прямую. Т.е. рассчитываем только один параметр: позиция объекта на длине пути. Затем с помощью getPointByPosition получаем координаты x, y. Таким образом задача сводится к вычислению только одного параметра: позиция объекта на длине пути. Чудить на базе этого можно уже сколько угодно. Например и скорость задавать с помощью Path и брать, например _y в качестве скорости."

Конец цитаты. Исходный код:

// author: Ivan Dembicki
Path = function () {
this.path_points=arguments.toString(), this.path_length=0;
var x_array = [], y_array = [], k = 0, i, len = arguments.length, x0 = arguments[0] || 0, y0 = arguments[1] || 0, x1, y1, x2, y2, ln, o, a1, a2, a3, a4, a, b, c, d, e, a2t, sa;
var s = Math.sqrt, l = Math.log, p = Math.pow;
for (i=2; i<len; i += 4) {
x1=arguments[i] || 0, y1=arguments[i+1] || 0, x2=arguments[i+2] || 0, y2=arguments[i+3] || 0, ln=this["ln"+k++]=[{_y:y0, _x:x0}, {_y:y1, _x:x1}, {_y:y2, _x:x2}];
// ASSetPropFlags(this, "ln"+(k-1), 7, 1)
o=ln[3]={}, a1=o.a1=x0-2*x1+x2, a2=o.a2=y0-2*y1+y2, a3=o.a3=x0-x1, a4=o.a4=y0-y1, a=o.a=4*(a1*a1+a2*a2), b=o.b=-8*(a1*a3+a2*a4), c=o.c=4*(a3*a3+a4*a4), e=o.e=Math.sqrt(c), d=s(c+b+a), sa=s(a), a2t=a*2, ln[4]=(2*sa*(d*(b+a2t)-e*b)+(b*b-4*a*c)*(l(2*e+b/sa)-l(2*d+(b+a2t)/sa)))/(8*p(a, (3/2)));
this.path_length += ln[4];
x0=x2, y0=y2;
}
this.segments = k--;
// comment it!
_root.lineStyle(0, 0, 30), _root.moveTo(this.ln0[0]._x, this.ln0[0]._y), _root.curveTo(this.ln0[1]._x, this.ln0[1]._y, this.ln0[2]._x, this.ln0[2]._y), _root.curveTo(this.ln1[1]._x, this.ln1[1]._y, this.ln1[2]._x, this.ln1[2]._y);
_root.curveTo(this.ln2[1]._x, this.ln2[1]._y, this.ln2[2]._x, this.ln2[2]._y);
// end comment it
};
tmp = Path.prototype={};
tmp.getPointByPosition = function(poz) {
if (poz<0 || poz>this.path_length) {
return {_x:this.ln0[0]._x, _y:this.ln0[0]._y};
}
if (this.segments<1) {
return false;
}
var i = 0, ln, len = 0, ff = 0;
for (i; i<=this.segments; i++) {
ln=this["ln"+i], len += ln[4];
if (len>poz) {
ff = (poz-(len-ln[4]))/ln[4];
break;
}
}
var s = Math.sqrt, l = Math.log, p = Math.pow, abs = Math.abs;
var fn = function (ff) {
var o = ln[3], a1 = o.a1, a2 = o.a2, a3 = o.a3, a4 = o.a4, a = o.a, b = o.b, c = o.c, e = o.e, i = 1, st = 1, f_l = ln[4], t_l = ff*f_l, max_i = 100, d, sa, a2i;
while (max_i--) {
d=s(c+i*(b+a*i)), sa=s(a), a2i=a*2*i, f_l=(2*sa*(d*(b+a2i)-e*b)+(b*b-4*a*c)*(l(2*e+b/sa)-l(2*d+(b+a2i)/sa)))/(8*p(a, (3/2)));
if (abs(f_l-t_l)<.000001) {
return i;
}
st /= 2, i += f_l<t_l ? st : f_l>t_l ? -st : 0;
}
return i;
};
var f = fn(ff), p0 = ln[0], p1 = ln[1], p2 = ln[2], e = 1-f, ee = e*e, ff = f*f, b = 2*f*e;
return {_x:p2._x*ff+p1._x*b+p0._x*ee, _y:p2._y*ff+p1._y*b+p0._y*ee};
};
delete tmp;

Как это использовать:


/// TEST
_root.createEmptyMovieClip("mc", 0);
_root.mc.lineStyle(5, 0xFF0000, 100);
_root.mc.lineTo(.2, 0);
_root.mc.tween_path = new Path(0, 0, 100, 0, 100, 100, 100, 200, 450, 380, 0, 300, 0, 0);
_root.mc.speed = _root.mc.path_position=0;
_root.mc.onEnterFrame = function() {
if (this.path_position>this.tween_path.path_length) {
this.path_position = 0;
}
this.path_position += this.speed += .01;
var poz = this.tween_path.getPointByPosition(this.path_position);
this._x=poz._x, this._y=poz._y;
};

Скачать класс Path: http://www.sharedfonts.com/Path.as.

Posted by: Rost at 08:43 PM | Comments (6)


++