snapping an angle to the closest cardinal direction

Posted by Josh E on Game Development See other posts from Game Development or by Josh E
Published on 2011-01-12T17:20:06Z Indexed on 2011/01/12 17:59 UTC
Read the original article Hit count: 237

Filed under:
|
|
|
|

I'm developing a 2D sprite-based game, and I'm finding that I'm having trouble with making the sprites rotate correctly. In a nutshell, I've got spritesheets for each of 5 directions (the other 3 come from just flipping the sprite horizontally), and I need to clamp the velocity/rotation of the sprite to one of those directions. My sprite class has a pre-computed list of radians corresponding to the cardinal directions like this:

protected readonly List<float> CardinalDirections = new List<float>
                           {
                               MathHelper.PiOver4,
                               MathHelper.PiOver2,
                               MathHelper.PiOver2 + MathHelper.PiOver4,
                               MathHelper.Pi, 
                               -MathHelper.PiOver4,
                               -MathHelper.PiOver2,
                               -MathHelper.PiOver2 + -MathHelper.PiOver4,
                               -MathHelper.Pi,
                           };

Here's the positional update code:

if (velocity == Vector2.Zero)
            return;

        var rot = ((float)Math.Atan2(velocity.Y, velocity.X));
        TurretRotation = SnapPositionToGrid(rot);

        var snappedX = (float)Math.Cos(TurretRotation);
        var snappedY = (float)Math.Sin(TurretRotation);
        var rotVector = new Vector2(snappedX, snappedY);

        velocity *= rotVector;
        //...snip

private float SnapPositionToGrid(float rotationToSnap)
    {
        if (rotationToSnap == 0)
            return 0.0f;

        var targetRotation = CardinalDirections.First(x => 
                (x - rotationToSnap >= -0.01 && x - rotationToSnap <= 0.01));
        return (float)Math.Round(targetRotation, 3);

    }

What am I doing wrong here? I know that the SnapPositionToGrid method is far from what it needs to be - the .First(..) call is on purpose so that it throws on no match, but I have no idea how I would go about accomplishing this, and unfortunately, Google hasn't helped too much either. Am I thinking about this the wrong way, or is the answer staring at me in the face?

© Game Development or respective owner

Related posts about XNA

Related posts about 2d