Skip Navigation

Ramblings from the team at zinc Roe

Metal Fish Eggs

x and y precision in ActionScript 3

I ran into some strange behavior while programming zombies in ActionScript 3 this morning. The code was pretty straight-forward, setting the zombie sprite’s x and y in an enter frame loop to move it to some arbitrary point. As part of the loop, I was checking if the sprite’s rotation was equal to the angle between the sprite’s x and y coordinates and the target x and y coordinates:

// calculate the distance
delta = new Point(
    point.x - zombie.x, 
    point.y - zombie.y
);
// calculate the correct rotation
rotation = Math.atan2(delta.y, delta.x);
rotation = radiansToDegrees(rotation);
if(Math.round(rotation - zombie.rotation)) {
    // the difference between the zombie's 
    // current rotation and the correct 
    // rotation is greater than 1 degree,
    // so the zombie should rotate
} else {
    // the zombie should move
}

Unfortunately, the condition was behaving strangely, with Math.round(rotation - zombie.rotation) returning all sorts of values from 10° to -10° when it should have been returning 0°.

After some digging, I found the culprit: the x and y values of DisplayObject instances get floored to the nearest 0.05 of a pixel, which at small distances changes the angle returned by Math.atan2() by as much at 10°!

Here’s a simple test that creates a random number (i.e. a number with a lot of digits), and assigns the value to a sprite’s rotation, x and y properties, then traces out the values:

var value:Number = Math.random();
var sprite:Sprite = new Sprite();
sprite.rotation = value;
sprite.x = value;
sprite.y = value;
trace(value, sprite.rotation, sprite.x, sprite.y);

And here are the results of a few test runs:

#value                  #sprite.rotation        #sprite.x   #sprite.y
0.26101896446198225     0.26101896446198225     0.25        0.25
0.5711805005557835      0.5711805005557835      0.55        0.55
0.3452326194383204      0.3452326194383204      0.3         0.3
0.1578897968865931      0.1578897968865931      0.15        0.15
0.7958266129717231      0.7958266129717231      0.75        0.75
0.1891973023302853      0.1891973023302853      0.15        0.15
0.05574001697823405     0.05574001697823405     0.05        0.05

As you can see, the values of the sprite’s x and y properties get floored down to the nearest 0.05 of a pixel (i.e. Math.floor(value * 20) / 20). The solution to the problem is to store the x and y coordinates used in the calculation separately (i.e. in a Point object), instead of reading them directly from the sprite.

2 comments on x and y precision in ActionScript 3
  1. geeks Says:

    Cool,

    and you solved it !!!
    The solution to the problem is to store the x and y coordinates used in the calculation separately (i.e. in a Point object), instead of reading them directly from the sprite.

    this is so wise

    thanks for the post

  2. Sharedtut Says:

    Great job, thank you for sharing.

Your Comment…

You can use these tags: <a> <blockquote> <strong> <em> <strike> <code> <pre> Use <pre lang="LANGUAGE"> for syntax highlighted code blocks.