Getting DPad Input from Thumbsticks in XNA – The Right Way

If you want to simulate 4-way DPad movement with the left or right analog thumbstick in XNA, my advice is to never use Buttons.LeftThumbStickUp, etc. This is because the default behavior doesn’t take into account the dead zone for the stick, which varies from controller to controller.  (The dead zone is the location near the center of the stick position, where it won’t send any movement value to the Xbox.)

You might test on a controller with a large dead zone and have no problem, then someone else will play your game with a very small dead zone, and they will find the control “sticking” in that direction.  I’ve had some controllers where the dead zone was so precise, I could have my thumb off the joystick and it would still be transmitting a tiny movement value.

I suggest adding a large dead zone, to make sure you only get simulated DPad input for large, deliberate movements of the analog stick.  Here’s some code that works for me, adjust as necessary to fit your control scheme:

static Buttons GetThumbstickDirection(PlayerIndex player, bool leftStick)
{
    float thumbstickTolerance = 0.35f;

    GamePadState gs = GamePad.GetState(player);
    Vector2 direction = (leftStick) ? 
        gs.ThumbSticks.Left : gs.ThumbSticks.Right;

    float absX = Math.Abs(direction.X);
    float absY = Math.Abs(direction.Y);

    if (absX > absY && absX > thumbstickTolerance)
    {
        return (direction.X > 0) ? Buttons.DPadRight : Buttons.DPadLeft;
    }
    else if (absX < absY && absY > thumbstickTolerance)
    {
        return (direction.Y > 0) ? Buttons.DPadUp : Buttons.DPadDown;
    }
    return (Buttons)0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *