使用 TweenLite 在 AS3 中以恒定速度无限水平滚动
我需要在父级 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
觉得这应该很简单。 任何人都可以向我指出任何可能的教程或提出任何建议吗?
任何帮助表示赞赏。
I need to do an endless horizontal scroll of elements within a parent MovieClip.
No matter what ever method I try, an element of 'drift' occurs and eventually the elements start to overlap.
I've tried using relative recursive tweening for each element according
but this method seems prone to quite a bit of error after repeated starts and stops.
//CODE START
function doScroll():void {
TweenLite.to(this, .25, {x:"20", ease:Linear.easeNone,onUpdate:checkPos,onComplete:doScroll});
}
//CODE END
I've reverted to doing absolute tweens to a predefined position using a contant speed. This seems to be more accurate but still some 'drift' occurs.
//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
Thought this should be very simple.
Can anyone point me to any possible tutorials or make any suggestions?
Any help appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案/讨论位于 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 阈值,但当它这样做时,它将位于 x 位置983.333333。此时,由于条件逻辑,它会跳回到 -980,但请注意,它移动了额外的 3.333333 像素。您希望 Item1 和 item2 以与补间期间完全相同的速度行进,但是您的 onUpdate 逻辑在重新定位时使它们错位,最终,某些项的行进速度比其他项快,从而影响了它们的整体速度。
另一个问题与 Flash 将 DisplayObjects 的 x/y 坐标四舍五入到最接近的 0.05 这一事实有关。因此,当您进行手动重新定位(换行)时,会出现小的舍入误差。例如,假设 TweenLite 将精确的 x 值设置为 980.799。 Flash 实际上会将其四舍五入为 980.75。然后,当您像 this.x -= 980 那样重新定位它,然后对其进行补间时,该值将在该轮中丢失近 0.05 像素。多次执行此操作,总计可以达到半像素或整个像素(或更多)。您的所有项目都在稍微不同的点跨越阈值,因此舍入误差并不相同,因此您开始看到间距略有变化。再次强调,这不是补间引擎的问题。您将看到引擎本身正确设置了值,但在应用于 DisplayObject 时 Flash 会在内部对它们进行舍入。
解决方案已发布在 http://forums.greensock.com/viewtopic。 php?f=1&t=6800,其中包含 FLA 和支持文件。
正如其他人所建议的那样,我建议使用一个代码块来管理您正在对齐/滚动的所有项目。它会从一个参考点开始布局,以便每次都完美排列。您可以补间应用逻辑的 getter/setter。我一直使用这种技术并且效果很好。您可以在上面 URL 中附加的代码中看到一个较小规模的示例(ItemBase.as 中的scrollX getter/setter)
Solution/Discussion at http://forums.greensock.com/viewtopic.php?f=1&t=6800
(warning: this is gonna require a rather lengthy explanation...)
It's a logic problem in your code. In your onUpdate, you were running conditional logic such that if the x position is beyond 980, it kills the tween and moves x back to -980 and starts things over. You're doing that for each individual item, each of which begins at a different position. That initial position affects when it crosses that threshold, thus when they reposition, the offsets are different.
For example, let's say item1 starts at an x position of 0 and item2 starts at 490 and both start moving at 400 pixels per second and your frame rate is 60, thus they'll move 6.66666 pixels per frame. Item1 will take 147 frames to hit 980. However, item2 will take 74 frames (actually 73.5, but there's no such thing as a half-frame) to cross the 980 threshold, but when it does so it will be at an x position of 983.333333. At that point it jumps back to -980 due to your conditional logic, but notice that it traveled an EXTRA 3.333333 pixels. You intended Item1 and item2 to travel at the exact same velocities and they do during the tween, but your onUpdate logic is misaligning them on the reposition such that in the end, some are traveling more than others which affects their overall velocity.
Another issue has to do with the fact that Flash rounds x/y coordinates of DisplayObjects to the nearest 0.05. So when you do your manual reposition (wrap), small rounding errors creep in. For example, let's say TweenLite sets the exact x value to 980.799. Flash will actually round that to 980.75. Then when you reposition it like this.x -= 980 and then tween it, the value would have just lost almost 0.05 pixels on that round. Do that many times and it can add up to a half-pixel or whole pixel (or more). All your items are crossing the threshold at slightly different spots, thus the rounding errors aren't the same, thus you start seeing slight variances in the spacing. Again, this is NOT an issue with the tweening engine. You'll see that the engine itself sets the values correctly, but Flash rounds them internally when applied to DisplayObjects.
A solution was posted at http://forums.greensock.com/viewtopic.php?f=1&t=6800 that includes an FLA and support files.
As others have suggested, I'd recommend having a single chunk of code that manages ALL the items that you're aligning/scrolling. It would lay things out from a single reference point so that everything lines up perfectly every time. You could tween a getter/setter that applies the logic. I use that technique all the time and it works great. You can see a smaller-scale example in the code I attached in the above URL (the scrollX getter/setter in ItemBase.as)
如果您要在单个维度上以相同的速率无限期地补间所有背景元素 - 为什么不使用计时器并完全绕过补间库?
If you will be tweening all background elements at the same rate indefinitely on a single dimension - why not use a Timer and bypass tweening libraries entirely?