开发者

XNA - how to tell if a thumb stick was "twitched" in a certain direction

Is there anything in the API (3 or 4) to tell me if the stick moved in one direction, as in a menu where it's equivalent to hittin开发者_如何学运维g a direction on the DPad? There appear to be some Thumbstick* members in the Buttons enum, but I can't find decent documentation on them.

Just want to make sure I'm not missing something obvious before I go and roll my own. Thanks!


There is no XNA method to tell you if a thumbstick was "twitched" this frame.

The easiest method is to store the old thumbstick state. If the state was zero and is now non-zero, it has been twitched.

Addition:

Instead of checking if the state was zero and is now non-zero. You can use the thumbstick buttons from the enumeration you mention in your question to determine if the stick has been "twitched". In this case you are treating the stick like a DPad and have to test each direction independently. The following code shows this method:

private void ProcessUserInput()
{
    GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);

    if (m_lastGamePadState.IsButtonUp(Buttons.LeftThumbstickUp) && gamePadState.IsButtonDown(Buttons.LeftThumbstickUp))
    {
        PrevMenuItem();
    }

    if (m_lastGamePadState.IsButtonUp(Buttons.LeftThumbstickDown) && gamePadState.IsButtonDown(Buttons.LeftThumbstickDown))
    {
        NextMenuItem();
    }

    m_lastGamePadState = gamePadState;
}


The thumbsticks on an Xbox 360 controller can be pushed "in" like buttons, which map to GamePadButtons.LeftStick and GamePadButtons.RightStick. These are obviously not what you want.

Here is the code that I use for detecting "presses" in any direction (where padLeftPushActive is stored between frames):

Vector2 padLeftVector = gamePadState.ThumbSticks.Left;
bool lastPadLeftPushActive = padLeftPushActive;
if(padLeftVector.Length() > 0.85f)
    padLeftPushActive = true;
else if(padLeftVector.Length() < 0.75f)
    padLeftPushActive = false;

if(!lastPadLeftPushActive && padLeftPushActive)
{
    DoSomething(Vector2.Normalize(padLeftVector));
}

It should be fairly simple to modify this so that it detects just presses in the particular directions necessary for your menu.


Is the GamePadState.Thumbsticks property what you're looking for?


Here's the solution I came up with, in case it's useful for anyone:

    enum Stick {
        Left,
        Right,
    }
    GamePadState oldState;
    GamePadState newState;

    /// <summary>
    /// Checks if a thumbstick was quickly tapped in a certain direction. 
    /// This is useful for navigating menus and other situations where
    /// we treat a thumbstick as a D-Pad.
    /// </summary>
    /// <param name="which">Which stick to check: left or right</param>
    /// <param name="direction">A vector in the direction to check. 
    /// The length, which should be between 0.0 and 1.0, determines 
    /// the threshold.</param>
    /// <returns>True if a twitch was detected</returns>
    public bool WasStickTwitched(Stick which, Vector2 direction)
    {
        if (direction.X == 0 && direction.Y == 0)
            return false;

        Vector2 sold, snew;
        if (which == Stick.Left)
        {
            sold = oldState.ThumbSticks.Left;
            snew = newState.ThumbSticks.Left;
        }
        else
        {
            sold = oldState.ThumbSticks.Right;
            snew = newState.ThumbSticks.Right;
        }

        Vector2 twitch = snew;
        bool x = (direction.X == 0 || twitch.X / direction.X > 1);
        bool y = (direction.Y == 0 || twitch.Y / direction.Y > 1);
        bool tnew = x && y;

        twitch = sold;
        x      = (direction.X == 0 || twitch.X / direction.X > 1);
        y      = (direction.Y == 0 || twitch.Y / direction.Y > 1);
        bool told = x && y;

        return tnew && !told;
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜