Flash Ripper RSS Readers


+

Архивы сайта Флэш Потрошитель за Август 2004


26.Август.2004,

Flex Builder

Долго ждали, и дождались: Macromedia выпустила Flex Builder, среду разработки для Flex. Кроме того, произошло много других обновлений и добавлений, связанных с технологией Flex.

Приятной вам работы! Мы уехали погулять недели две, отдохнуть от информационных технологий, так сказать. И вы отдыхать не забывайте ;-)

Писал Rost, 10:25 PM Отзывов: 6

 

19.Август.2004, Classes

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.

Писал Rost, 08:43 PM Отзывов: 6

 

12.Август.2004, Articles

Программирование классов в AS2. Снегопад

Джордж Форест доступно, по-русски написал статью о программировании классов в ActionScript 2. Надеемся, эта статья пригодится всем, кто изучает (или только начинает изучать) этот замечательный язык. Тем более, что темой статьи является такой распространенный и востребованный предмет, как создание систем частиц (в данном случае -- снегопада). Статья компактна, но при этом содержит в себе не только описание и исходные коды готовых классов, но и рекомендации по их расширению. Читать здесь: "Программирование классов в AS2. Снегопад."

Писал Rost, 03:23 PM Отзывов: 7

 

09.Август.2004, Coding

Выполнение функции в заданной области видимости с помощью класса mx.utils.Delegate (или: Передача событий от любого объекта к любому объекту)

Хорошая новость, а точнее, даже несколько. В последнее обновление для среды разработки Flash MX 2004 вошел новый класс mx.utils.Delegate. Его назначение -- избавить разработчиков от еще одной старой головной боли, связанной с обработкой событий. Это была старая проблема с областью видимости: вызывая функцию-обработчик события компонента (или, например, XML-объекта, или мувиклипа), мы автоматически попадаем в область видимости этого компонента (XML-объекта, мувиклипа и т.д.), а это означает, что ключевое слово this внутри такой функции будет указывать на вызвавший событие компонент (XML-объект, мувиклип..), а не на класс или мувиклип, которому принадлежит функция-обработчик. Но чаще всего внутри функции-обработчика нам нужна как раз область видимости содержащего ее класса или мувиклипа, а не вызвавшего событие компонента (XML-объекта, мувиклипа и т.д.)!

Как раз для решения это проблемы и предназначен класс mx.utils.Delegate. Изначально, класс Delegate был выпущен компанией Macromedia с целью прямой передачи событий компонентов в использующие их классы (раньше это приходилось делать с помощью всевозможных ухищрений по передаче событий.) Но, как мы сейчас увидим, этот полезный класс можно с успехом использовать и для обработки любых других, самых обычных событий.

Итак, первичная задача класса Delegate -- передать событие от компонента к использующему его объекту; вот синтаксис, изначально предлагаемый Macromedia (случай с компонентом):

import mx.utils.Delegate;
имяЭкземпляра.addEventListener("названиеСобытия", Delegate.create(областьВидимости, функция));

(См.: Оригинальная статья на LiveDocs по делегированию событий компонентов.)

Прекрасная возможность! Но, оказывается, с помощью класса Delegate можно делегировать не только события компонентов, но и любые, самые привычные и простые события, например, такие, как события кнопок или объекта XML. В качестве практического примера рассмотрим распространенную ситуацию: мы загружаем некий XML и хотим, что по окончании его загрузки была вызвана функция-обработчик, из которой мы могли бы получить прямой доступ к классу или мувиклипу, содержащему эту функцию.

В этом случае мы можем использовать следующий, еще более простой синтаксис:

import mx.utils.Delegate;
xmlData.onLoad=Delegate.create(this, processXML);

где this указывает на целевую область видимости (это может быть конкретный экземпляр класса или мувиклип, именно на него будет указывать ключевое слово this в вызываемом методе или функции-обработчике, processXML -- это метод-обработчик данного класса (или функция на таймлайне мувиклипа), который(ая) будет вызван(а) по окончании загрузки. Вот полный пример исходного кода:

// Это некоторый класс, использующий загружаемый XML, код содержитя в файле "SomeClassThatUsesLoadedXML.as":

import mx.utils.Delegate;

class SomeClassThatUsesLoadedXML{ // with Delegate class

private var inited:Boolean=false;
private var xmlData:XML;

function SomeClassThatUsesLoadedXML(){
if(!inited){
init();
}
}
private function init(){
xmlData=new XML();
xmlData.onLoad=Delegate.create(this,processXML);
inited=true;
}
private function processXML():Void{
trace("Событие onLoad вызвано на объекте: "+this + "\nXML данные: "+ xmlData);
}
public function loadXML(urlPath:String):Void{
xmlData.load(urlPath);
}
public function toString(){
return "[SomeClassThatUsesLoadedXML]";
}
}

//Пример использования, код в fla-файле:
var experimental:SomeClassThatUsesLoadedXML=new SomeClassThatUsesLoadedXML();
experimental.loadXML("content/xml/data.xml");

// Вывод в окне Output:
Событие onLoad вызвано на объекте: [SomeClassThatUsesLoadedXML]
XML данные:
Item 1

Разве это не хорошо? Спасибо ребятам из Macromedia!
//Обратите внимание: класс mx.utils.Delegate можно использовать как в AS1, так и в AS2, в любом предпочитаемом вами стиле кодирования.

Писал Rost, 08:12 PM Отзывов: 25

 

03.Август.2004, Good Job!

Ди-джейский пульт от Антона Волкова

Новая работа от Антона Волкова: ди-джейский пульт (770Kb).


Слова Автора:

О пульте

"Идея не нова -- имитация рабочего стола DJ'я. Основной упор делался на "фотореалистичность" и детали. В качестве визуала использовалась аппаратура Technics (кто знает, тот поймёт).

Из особенностей отмечу:

  • перетаскиваемость винила по столу;

  • скрэтч по клику на виниле;

  • обработка поворота винила, если он на вертушке или скрэтчится;

  • псевдо-правильный, но ведущий себя хорошо индикатор уровня звука;

  • цветные кнопки по середине - сэмплер (в мире такого не существует);

  • имитация движения винила.

О технологии создания


В процессе работы выяснил, что самое сложное - точная работа со звуком. Пара рекомендаций, кто с этим будет сталкиваться.

Момент №1

Flash-плеер не может одновременно проигрывать больше 8 сэмплов, поэтому надо правильно распределять звуковые потоки и всегда "затыкать" не используемые звуки (например с нулевой громкостью).

Момент №2

Когда необходимо сделать точную синхронизацию лупов (зацикленных сэмплов), сталкиваемся с очередной недокументированной особенностью Flash-плеера.

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

Кажется, не смертельно, но когда вы запускаете/выключаете лупы несколько раз, накапливается большая ошибка и начинается десинхронизация лупов (ударные сами по себе, а бас сам по себе).

Единственным правильным решением остаётся все лупы делать длиной кратной 46.43 мс, и осуществлять запуск в кратные 46.43 мс точки тайм-лайна.

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

sync.tick.start(0, 1); // первоначальный запуск сихро-звука
sync.tick.onSoundComplete = function() {
// делаем засечку
this.start(0, 1); // опять запускаем синхро-звук
};


Схематично выглядеть это будет так:

 первый start
|
0 -------------- 46.43 ------------ 92.86 ------>
|
onSoundComplete
|
засечка
|
start ------------>|
|
onSoundComplete
|
засечка
|
start ------------>|

Остаётся только запускать лупы по засечкам и синхронизация будет безупречной.

Спасибо franky за статью "Flash MX Sound Synch".

[Конец цитаты]

Писал Rost, 07:02 PM Отзывов: 4

 

Примечания: Статус документа: в процессе
++


Этот сайт окупается за счет саперов. Они говорят:
+++




++++



© 2002-2008 Производство: Рост Прибыли · О проекте · Подписка на новости (RSS)