Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   глючит карусель в баннере (http://www.flasher.ru/forum/showthread.php?t=175160)

DimkaN 11.02.2012 08:36

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

Объекты двигаются по эллипсу, меняется угол, от pi/2 до pi (ну примерно до pi - в коде видно).
Когда угол предыдущего объекта становится равным pi - текущий объект перемещается в начало карусели т.е. угол равняется pi/2.

В общем, странное как - то ведет себя каруселька, при больших приращениях угла через пару оборотов расстояние между объектами становится разным, да и иногда объекты не хотят перемещаться в начало карусели. Не могу понять в чем дело.

Баннер вложил в архив.

Полный исходник класса:

Код AS3:

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];
                }
 
        }
}


olexandr 11.02.2012 14:34

Я не знаю, у кого как, но у меня нет никакого желания вникать в такой код.
Что это за e.target.ugol = Math.PI/2? Приведите e.target к чему то нормальному.
Зачем в коде столько чисел? Вынесите их в константы или используйте динамические, расчетные величины
например, tempItem.scaleX = 1 - (7-i)*0.125; Что за 7, откуда оно? А 0.125?
Извините, если резковато, но все же, если упорядочить код, то и искать проблемы станет проще!

DimkaN 11.02.2012 18:05

Ок, поправил код, удалил всё лишнее и прокомментировал всё, кажется теперь должно быть понятнее

"Что это за e.target.ugol = Math.PI/2? Приведите e.target к чему то нормальному."
что значит к нормальному, чем это не нормально? Что значит написал в комментариях к коду. Те же глюки что и были.

Код AS3:

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
 
                  }
 
                }

Да еще попутно вопрос, можно ли как-нить вынести реализацию методов в отдельный файл?

PainKiller 12.02.2012 01:09

выложите исходники если хотите чтобы вам помогли, я за вас это - new AmorSym(),new Vinograd(),new ChocolateSym(),new CoffeSym(),new Vishnya(),new Hugo(),new GreypFR(),new SunDance() рисовать не буду. А на пустышке я глюков не увидел.
Цитата:

Да еще попутно вопрос, можно ли как-нить вынести реализацию методов в отдельный файл?
А у вас класс, что не в отдельном файле что ли?

DimkaN 12.02.2012 06:56

Вот исходник http://www.onlinedisk.ru/file/823733/

Класс в файле, я имел ввиду реализацию его методов. Допустим в одном файле класс и прототипы методов,
В другом - реализация, можно ли так?

Gaen 12.02.2012 08:43

Лучше перепишите код так, чтобы у вас один слушатель ENTER_FRAME двигал все объекты. Сейчас каждый двигает сам себя, поглядывая на соседей, и тут черт ногу сломит, что происходит.

Расхождение по углу скорее всего возникает, когда объекты перепрыгивают angleEtalon и ставятся на начальный угол. Когда скорость большая, на момент проверки угол будет не angleEtalon, а скажем angleEtalon + 0.1. И после этого он ставится на Math.PI / 2, хотя должен быть на Math.PI / 2 + 0.1.

DimkaN 12.02.2012 09:20

Код AS3:

Math.PI/2 +(beforeObj.ugol - angleEtalon);

переписал

Глючит по прежнему, возможно из-за второго глюка - объекты иногда не перемещаются в начало.

Спасибо, перепишу на один слушатель, мож тогда все прояснится.

Есть еще идеи?

Gaen 12.02.2012 10:42

Есть.

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

Заводим некий baseAngle, относительно которого будут позиционироваться объекты, и в слушателе ENTER_FRAME делаем следующее:
1. Изменяем скорость (как сейчас)
2. Передвигаем baseAngle (как сейчас передвигаются объекты)
3. Вычисляем угол каждого объекта относительно baseAngle (например, item.ugol = baseAngle + i * 0.1)
4. Вычисляем координаты объектов, скейлим, сортируем

При таком подходе все объекты будут всегда жестко зафиксированы на угловом расстоянии 0.1 радиана друг от друга.

DimkaN 12.02.2012 19:52

Вложений: 1
Вообщем ребят вот что получилось, вроде глюков не видно, сделал по простому.

Хотел чтобы объект двигался в сторону, пока предыдущий объект не достиг ПИ, а потом перемещался в конец очереди, и при обратном вращении чтоб такая же обратная анимация была. Но что-то не могу понять как это сделать, точнее я че то сделал, но глючит ужасно.

DimkaN 13.02.2012 12:37

Вложений: 1
Если кому интересно сделал второй вариант, спасибо всем за помощь...


Часовой пояс GMT +4, время: 11:13.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.