Долго ждали, и дождались: Macromedia выпустила Flex Builder, среду разработки для Flex. Кроме того, произошло много других обновлений и добавлений, связанных с технологией Flex.
Приятной вам работы! Мы уехали погулять недели две, отдохнуть от информационных технологий, так сказать. И вы отдыхать не забывайте ;-)
Цитата:
"Свершилось!!!!! Я бился над этим больше чем пол года. Еще сырая версия, но работает вполне корректно. Скоро приведу в порядок и... эх.... заживем!
Главное, и единственное пока, что делает Path, -- это перевод расчета позиции объекта с кривой в прямую. Т.е. рассчитываем только один параметр: позиция объекта на длине пути. Затем с помощью getPointByPosition получаем координаты x, y. Таким образом задача сводится к вычислению только одного параметра: позиция объекта на длине пути. Чудить на базе этого можно уже сколько угодно. Например и скорость задавать с помощью Path и брать, например _y в качестве скорости."
Path
getPointByPosition
x
y
_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.
Джордж Форест доступно, по-русски написал статью о программировании классов в ActionScript 2. Надеемся, эта статья пригодится всем, кто изучает (или только начинает изучать) этот замечательный язык. Тем более, что темой статьи является такой распространенный и востребованный предмет, как создание систем частиц (в данном случае -- снегопада). Статья компактна, но при этом содержит в себе не только описание и исходные коды готовых классов, но и рекомендации по их расширению. Читать здесь: "Программирование классов в AS2. Снегопад."
Хорошая новость, а точнее, даже несколько. В последнее обновление для среды разработки Flash MX 2004 вошел новый класс mx.utils.Delegate. Его назначение -- избавить разработчиков от еще одной старой головной боли, связанной с обработкой событий. Это была старая проблема с областью видимости: вызывая функцию-обработчик события компонента (или, например, XML-объекта, или мувиклипа), мы автоматически попадаем в область видимости этого компонента (XML-объекта, мувиклипа и т.д.), а это означает, что ключевое слово this внутри такой функции будет указывать на вызвавший событие компонент (XML-объект, мувиклип..), а не на класс или мувиклип, которому принадлежит функция-обработчик. Но чаще всего внутри функции-обработчика нам нужна как раз область видимости содержащего ее класса или мувиклипа, а не вызвавшего событие компонента (XML-объекта, мувиклипа и т.д.)!
mx.utils.Delegate
this
Как раз для решения это проблемы и предназначен класс mx.utils.Delegate. Изначально, класс Delegate был выпущен компанией Macromedia с целью прямой передачи событий компонентов в использующие их классы (раньше это приходилось делать с помощью всевозможных ухищрений по передаче событий.) Но, как мы сейчас увидим, этот полезный класс можно с успехом использовать и для обработки любых других, самых обычных событий.
Delegate
Итак, первичная задача класса Delegate -- передать событие от компонента к использующему его объекту; вот синтаксис, изначально предлагаемый Macromedia (случай с компонентом):
import mx.utils.Delegate; имяЭкземпляра.addEventListener("названиеСобытия", Delegate.create(областьВидимости, функция));
(См.: Оригинальная статья на LiveDocs по делегированию событий компонентов.)
Прекрасная возможность! Но, оказывается, с помощью класса Delegate можно делегировать не только события компонентов, но и любые, самые привычные и простые события, например, такие, как события кнопок или объекта XML. В качестве практического примера рассмотрим распространенную ситуацию: мы загружаем некий XML и хотим, что по окончании его загрузки была вызвана функция-обработчик, из которой мы могли бы получить прямой доступ к классу или мувиклипу, содержащему эту функцию.
В этом случае мы можем использовать следующий, еще более простой синтаксис:
import mx.utils.Delegate; xmlData.onLoad=Delegate.create(this, processXML);
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");
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, в любом предпочитаемом вами стиле кодирования.
Новая работа от Антона Волкова: ди-джейский пульт (770Kb).
Слова Автора:
Из особенностей отмечу:
Дело в том, что звуковой тайм-лайн как бы разбит на фреймы по 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".
[Конец цитаты]
Совсем древнее: 17-20.09.2002, 23-30.09.2002, 01-04.10.2002, 07-11.10.2002, 14-19.10.2002, 20-26.10.2002, 27.10-02.11.2002, 04-08.11.2002, 11-16.11.2002, 18-23.11.2002 25-30.11.2002, 02-07.12.2002, 09-14.12.2002 Сайт заработал 17.09.2002