![]() |
|
||||||||||
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
Ребят, всем привет, очень задолбался поэтому прошу помощи, я в AS3 новичок. Короче пытаюсь сделать я карусель.
Объекты двигаются по эллипсу, меняется угол, от pi/2 до pi (ну примерно до pi - в коде видно). Когда угол предыдущего объекта становится равным pi - текущий объект перемещается в начало карусели т.е. угол равняется pi/2. В общем, странное как - то ведет себя каруселька, при больших приращениях угла через пару оборотов расстояние между объектами становится разным, да и иногда объекты не хотят перемещаться в начало карусели. Не могу понять в чем дело. Баннер вложил в архив. Полный исходник класса: package { import flash.display.MovieClip; import flash.filters.GlowFilter; import flash.filters.BlurFilter; import flash.events.Event; public class MovieClipMotion extends MovieClip { public var soapObj:Array; /* array for classes names storage */ public var radiusX:int; public var radiusY:int; public var angleEtalon:Number; public var centerX:int; public var centerY:int; public var speed:Number; /*cunstructor*************************** *Creates array of classes instances for soap *adding to the scene ***************************************/ function MovieClipMotion():void { speed = 0.03; soapObj = new Array(new AmorSym(),new Vinograd(),new ChocolateSym(),new CoffeSym(),new Vishnya(),new Hugo(),new GreypFR(),new SunDance()); centerX = 1080; centerY = 170 radiusX = 900; radiusY = 320; angleEtalon = 7*( (Math.PI/2)/soapObj.length ) + Math.PI/2; for(var i:int = 0; i<soapObj.length; i++) { var tempItem:MovieClip = soapObj[i]; /*scaling*/ tempItem.scaleX = 1 - (7-i)*0.125; tempItem.scaleY = tempItem.scaleX; /*calculate angle*/ tempItem.ugol = i*( (Math.PI/2)/soapObj.length ) + Math.PI/2; tempItem.x = centerX + radiusX*Math.cos(tempItem.ugol); tempItem.y = centerY - radiusY*Math.sin(tempItem.ugol); tempItem.addEventListener(Event.ENTER_FRAME,motion); addChild(tempItem); } this.addEventListener(Event.ENTER_FRAME,changeSpeed); } function changeSpeed(e:Event):void { speed = (this.mouseX - 500)/3500; } function motion(e:Event):void { var beforeObj:Object; //sort for(var i:int = 4 ; i < 11; i++) if(this.getChildAt(i).scaleX > this.getChildAt(i+1).scaleX) this.swapChildrenAt(i,i+1); if ( angleEtalon > e.target.ugol ) { e.target.x = centerX + radiusX*Math.cos(e.target.ugol); e.target.y = centerY - radiusY*Math.sin(e.target.ugol); e.target.ugol += speed; e.target.scaleX = (e.target.y+radiusY) / (radiusY+centerY - radiusY*Math.sin(angleEtalon)); e.target.scaleY = e.target.scaleX; //this.blurInOut(e,e.target.scaleX); } else { beforeObj = e.target.parent.getChildAt(e.target.parent.getChildIndex(e.target)-1); if (beforeObj.ugol >= angleEtalon){ e.target.ugol = Math.PI/2; } //else e.target.x -= 30; } } function blurInOut(objForBlur:Event, step:Number) { var blurF:BlurFilter = null; blurF = new BlurFilter((1-step)*150,(1-step)*150,1); objForBlur.target.filters = [new GlowFilter(0xFFFFFF,1,20,20,1.5,1),blurF]; } } } |
|
|||||
|
Я не знаю, у кого как, но у меня нет никакого желания вникать в такой код.
Что это за e.target.ugol = Math.PI/2? Приведите e.target к чему то нормальному. Зачем в коде столько чисел? Вынесите их в константы или используйте динамические, расчетные величины например, tempItem.scaleX = 1 - (7-i)*0.125; Что за 7, откуда оно? А 0.125? Извините, если резковато, но все же, если упорядочить код, то и искать проблемы станет проще! |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
Ок, поправил код, удалил всё лишнее и прокомментировал всё, кажется теперь должно быть понятнее
"Что это за e.target.ugol = Math.PI/2? Приведите e.target к чему то нормальному." что значит к нормальному, чем это не нормально? Что значит написал в комментариях к коду. Те же глюки что и были. package { import flash.display.MovieClip; import flash.filters.GlowFilter; import flash.filters.BlurFilter; import flash.events.Event; public class MovieClipMotion extends MovieClip { public var soapObj:Array; /* array for classes objects */ public var radiusX:int; public var radiusY:int; public var angleEtalon:Number; public var centerX:int; public var centerY:int; public var speed:Number; /*cunstructor*************************** *Creates array of classes instances for soap *adding to the scene ***************************************/ function MovieClipMotion():void { /*инициализация переменных*/ soapObj = new Array(new AmorSym(),new Vinograd(),new ChocolateSym(),new CoffeSym(),new Vishnya(),new Hugo(),new GreypFR(),new SunDance()); centerX = 1080; centerY = 170 radiusX = 900; radiusY = 320; speed = 0.03 angleEtalon = Math.PI; //это угол при котором следует переместить элемент в конец карусели for(var i:int = 0; i<soapObj.length; i++) //создаем временную переменную для каждого объекта в карусели { var tempItem:MovieClip = soapObj[i]; /*calculate angle*/ tempItem.ugol = i*( (Math.PI/2)/soapObj.length ) + Math.PI/2; // задаем каждому объекту начальный угол в карусели( от pi/2 до pi) tempItem.addEventListener(Event.ENTER_FRAME,motion); //каждому элементу слушатель события. addChild(tempItem); // добавить элемент на сцену } this.addEventListener(Event.ENTER_FRAME,changeSpeed); // подключаем слушатель к //сцене чтобы менять скорость вращения от положения мыши } function changeSpeed(e:Event):void { speed = (this.mouseX - 500)/3500; // вычислить скорость - 3500 подобрано, 500 - половина ширины сцены } function motion(e:Event):void { var beforeObj:Object; //sort for(var i:int = 4 ; i < 11; i++) // сортировка объектов в зависимости от масштаба if(this.getChildAt(i).scaleX > this.getChildAt(i+1).scaleX) //если масштаб объекта больше то он должен быть на переднем плане this.swapChildrenAt(i,i+1); if ( angleEtalon > e.target.ugol ) //пока угол объекта не достигнет PI мы двигаем его вычисляя координату от угла { e.target.x = centerX + radiusX*Math.cos(e.target.ugol); e.target.y = centerY - radiusY*Math.sin(e.target.ugol); e.target.ugol += speed; e.target.scaleX = (e.target.y+radiusY) / (radiusY+centerY - radiusY*Math.sin(angleEtalon)); e.target.scaleY = e.target.scaleX; } else // если угол объекта достиг pi { beforeObj = e.target.parent.getChildAt(e.target.parent.getChildIndex(e.target)-1); //находим предыдущий объект по индексу if (beforeObj.ugol >= angleEtalon) //когда предыдущий объект достигает угла PI - текущий объект перемещается в начало карусели e.target.ugol = Math.PI/2; // начало карусели это угол Pi/2 } } Последний раз редактировалось DimkaN; 11.02.2012 в 19:10. |
|
|||||
|
выложите исходники если хотите чтобы вам помогли, я за вас это - new AmorSym(),new Vinograd(),new ChocolateSym(),new CoffeSym(),new Vishnya(),new Hugo(),new GreypFR(),new SunDance() рисовать не буду. А на пустышке я глюков не увидел.
Цитата:
|
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
Вот исходник http://www.onlinedisk.ru/file/823733/
Класс в файле, я имел ввиду реализацию его методов. Допустим в одном файле класс и прототипы методов, В другом - реализация, можно ли так? |
|
|||||
|
strange mood
|
Лучше перепишите код так, чтобы у вас один слушатель ENTER_FRAME двигал все объекты. Сейчас каждый двигает сам себя, поглядывая на соседей, и тут черт ногу сломит, что происходит.
Расхождение по углу скорее всего возникает, когда объекты перепрыгивают angleEtalon и ставятся на начальный угол. Когда скорость большая, на момент проверки угол будет не angleEtalon, а скажем angleEtalon + 0.1. И после этого он ставится на Math.PI / 2, хотя должен быть на Math.PI / 2 + 0.1.
__________________
тонкий тролль, осеянный благодатью |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
переписал
Глючит по прежнему, возможно из-за второго глюка - объекты иногда не перемещаются в начало. Спасибо, перепишу на один слушатель, мож тогда все прояснится. Есть еще идеи? |
|
|||||
|
strange mood
|
Есть.
Вместо того, чтобы двигать каждый объект отдельно, привязать всю пачку к одному углу, и менять только этот угол. Проще объяснить на примере. Заводим некий baseAngle, относительно которого будут позиционироваться объекты, и в слушателе ENTER_FRAME делаем следующее: 1. Изменяем скорость (как сейчас) 2. Передвигаем baseAngle (как сейчас передвигаются объекты) 3. Вычисляем угол каждого объекта относительно baseAngle (например, item.ugol = baseAngle + i * 0.1) 4. Вычисляем координаты объектов, скейлим, сортируем При таком подходе все объекты будут всегда жестко зафиксированы на угловом расстоянии 0.1 радиана друг от друга.
__________________
тонкий тролль, осеянный благодатью |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
Вообщем ребят вот что получилось, вроде глюков не видно, сделал по простому.
Хотел чтобы объект двигался в сторону, пока предыдущий объект не достиг ПИ, а потом перемещался в конец очереди, и при обратном вращении чтоб такая же обратная анимация была. Но что-то не могу понять как это сделать, точнее я че то сделал, но глючит ужасно. |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 14
|
Если кому интересно сделал второй вариант, спасибо всем за помощь...
|
![]() |
![]() |
Часовой пояс GMT +4, время: 12:36. |
|
|
« Предыдущая тема | Следующая тема » |
|
|