Бесконечная горизонтальная прокрутка с постоянной скоростью в AS3 с использованием TweenLite - PullRequest
1 голос
/ 24 января 2012

Мне нужно сделать бесконечную горизонтальную прокрутку элементов в родительском MovieClip.

Независимо от того, какой метод я пробую, элемент «дрейф» возникает, и в конечном итоге элементы начинают перекрываться.

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

//CODE START
      function doScroll():void {
         TweenLite.to(this, .25, {x:"20", ease:Linear.easeNone,onUpdate:checkPos,onComplete:doScroll});
     }
//CODE END

Я вернулся к созданию абсолютных анимаций дляпредопределенная позиция с использованием постоянной скорости.Это кажется более точным, но все же происходит некоторый «дрейф».

//CODE START
//_dest is predefined 
var speed:Number = 500;
var dist:Number = this.x - _dest;
var distAbs:Number = dist < 0 ? -dist : dist;
//kludge to get constant velocity by recalculating time every frame
_time = distAbs / speed;
TweenLite.to(this, _time, {x:_dest, ease:Linear.easeNone,onComplete:reset});
//CODE END

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

Любая помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Решение / Обсуждение на http://forums.greensock.com/viewtopic.php?f=1&t=6800

(предупреждение: это потребует довольно длинного объяснения ...)

Это логическая проблема в вашем коде.В вашем onUpdate вы выполняли условную логику так, что если позиция x превышает 980, она убивает анимацию движения, возвращает x обратно к -980 и начинает все заново.Вы делаете это для каждого отдельного элемента, каждый из которых начинается с другой позиции.Эта начальная позиция влияет, когда она пересекает этот порог, поэтому, когда они перемещаются, смещения отличаются.

Например, предположим, что item1 начинается с позиции x в 0, а item2 начинается с 490, и оба начинают двигаться с 400пикселей в секунду и ваша частота кадров составляет 60, таким образом, они будут двигаться 6,66666 пикселей на кадр.Item1 потребуется 147 кадров, чтобы достичь 980. Тем не менее, Item2 потребуется 74 кадра (на самом деле 73,5, но нет такого понятия, как полукадр), чтобы пересечь порог 980, но когда это произойдет, он будет в положении x983,333333.В этот момент он возвращается к -980 из-за вашей условной логики, но обратите внимание, что он путешествовал ДОПОЛНИТЕЛЬНО 3.333333 пикселей.Вы хотели, чтобы Item1 и Item2 двигались с одинаковыми скоростями, и они делают это во время анимации движения, но ваша логика onUpdate смещает их во время репозиции, так что в итоге некоторые путешествуют больше, чем другие, что влияет на их общую скорость.

Другая проблема связана с тем, что Flash округляет координаты x / y объектов DisplayObjects до ближайших 0,05.Поэтому, когда вы выполняете ручную репозицию (перенос), появляются небольшие ошибки округления. Например, допустим, TweenLite устанавливает точное значение x равным 980,799.Вспышка фактически округлит это до 980.75.Затем, когда вы измените положение, например this.x - = 980, а затем измените его, значение в этом раунде потеряло бы почти 0,05 пикселя.Сделайте это много раз, и это может добавить до половины или целого пикселя (или больше).Все ваши товары пересекают порог в немного разных точках, поэтому ошибки округления не одинаковы, поэтому вы начинаете видеть небольшие отклонения в интервале.Опять же, это НЕ проблема с двигателем анимации.Вы увидите, что движок сам устанавливает значения правильно, но Flash округляет их внутренне, когда применяется к DisplayObjects.

Решение было размещено на http://forums.greensock.com/viewtopic.php?f=1&t=6800, которое включает FLA и файлы поддержки.

Как и другие предлагали, я бы порекомендовал иметь один кусок кода, который управляет ВСЕМИ элементами, которые вы выравниваете / прокручиваете.Это выложит вещи из единой точки отсчета, чтобы каждый раз все выстраивалось идеально.Вы можете использовать метод получения / установки, который применяет логику.Я использую эту технику все время, и она прекрасно работает.Вы можете видеть уменьшенный пример в коде, который я прикрепил в приведенном выше URL-адресе (getter / setter scrollX в ItemBase.as)

0 голосов
/ 26 января 2012

Если вы будете анимировать все элементы фона с одинаковой скоростью в течение неопределенного времени в одном измерении - почему бы не использовать Таймер и полностью обойти библиотеки анимации?

...