Oct 16, 2008

Sprite: Properly update properties

Simple: update the x property of a bunch of Sprites on the stage based on the Mouse's x position.

If you are on the right half of the stage, move objects to the left (scroll right/negative x). If you are on the left side of the stage, move objects to the right (left scroll/positive x). This also takes into account how close you are to the center; if you are closer to the edges, scroll faster.

This is accomplished using an ENTER_FRAME handler and other fancy Math is happening but essentially we have:

layer.x -= _curRatio * _speed[layer];

All this is doing is updating the x property of a particular 'layer' object. And the result of this is not satisfactory by any means. Why do the objects seem to not be updating properly? And what is the solution?

The theory here is that Flash cannot redraw the object while attempting to update the property which is changing it (x, y, alpha, rotation). To accommodate this quirk is a simple fix; simply set a variable on the Sprite, update that property and then update the x property based on said variable.

layer.xPos -= _curRatio * _speed[layer];
layer.x = layer.xPos;


Simple and effective.

I'm betting that many people incorrectly use this technique but really can't tell and this never notice. However when one has things scrolling at a particular rate (layers) where one can visibly see the discrepancy it all becomes apparent rather quickly.

Thanks to Daniel.

Share this Post


                           

Comments


Jessicaerymn     May 10, 2009
Great! Thank you very much! I always wanted to write in my blog something like that. Can I take part of your post to my site? Of course, I will add backlink? Regards

Alrick     Nov 06, 2008
Hey, I'm sort of a newbie.
I really don't understand whats going on. You guys started in the middle and some parts are missing for me.
Forgive me if I can't put 2 + 2 together.

Please explain a little further.

Thanks :)

Stephen Koch     Oct 17, 2008
@Keith

Thanks for the feedback/explanation. If I'd have actually searched for a problem/solution I probably would have come across that post.

Yes, fixed the typo.

Stephen Koch     Oct 17, 2008
@Steven Sacks:

Basically it comes down to a design decision.

In order for us to match what our designers have designed in terms of a panorama view/parallax movement we set up a huge timeline tween fro left to right with all the layers. This way we could show the client comps and they could see what it would eventually look like.

Given that the tween was set up over 1 minute we can figure out, from the starting position of a particular layer, exactly how many pixels that layer is moving in one frame. For example, the background layer has a max speed of 7.06 pixels per frame. The top most layer moves at a max speed of 11.11222222 pixels per frame.

formula: Absolute value of the starting x position / (60 seconds * 30 frames per second)

So, I've decided on ENTER_FRAME to keep things in line with what the design team has designed.

Steven Sacks     Oct 17, 2008
Why not use a TimerEvent.TIMER instead of an Event.ENTER_FRAME listener?

Keith Peters     Oct 17, 2008
your first line of code is:

layer.x = _curRatio * _speed[layer];

Did you mean this?

layer.x -= _curRatio * _speed[layer];


I don't think it's a matter of redrawing. That happens at the end of a frame after all the code has executed anyway. I think the problem is described here:

http://www.bit-101.com/blog/?p=669

Basically, display object x and y positions can only store so much precision. Up to 1/20 of a pixel. At least this was the case in Flash 8 and before. Assigning to an intermediate value allows for much more precision.



Speak






Submit »