问题
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 hitting 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!
回答1:
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;
}
回答2:
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.
回答3:
Is the GamePadState.Thumbsticks property what you're looking for?
回答4:
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;
}
来源:https://stackoverflow.com/questions/5073622/xna-how-to-tell-if-a-thumb-stick-was-twitched-in-a-certain-direction