Moving Sprites Based on Gamepad Input
Now let’s get the sprite
moving around on the screen again. This time, you use the gamepad as
your input device. Use the left thumb stick to move the sprite around on
the screen. The A and X buttons flip the sprite horizontally and
vertically. The direction pad’s up and down buttons scale the sprite up
and down. First, declare member variables to hold the sprite’s texture,
position, and other values. In your game class, add the following member
variables:
Texture2D spriteTexture;
Vector2 spritePosition = new Vector2(200, 200);
Vector2 spriteCenter;
float spriteSpeed = 100f;
GamePadState lastGamePadState;
float rotation;
float scale = 1.0f;
SpriteEffects flipOptions;
Next, load a texture to use as your sprite and set the sprite’s center based on the texture width and height. In the game’s LoadContent method, add the following lines of code:
spriteTexture = Content.Load<Texture2D>("XnaLogo");
spriteCenter.X = spriteTexture.Width / 2.0f;
spriteCenter.Y = spriteTexture.Height / 2.0f;
Now, add logic to the game’s Update method to read the current gamepad state and set the sprite’s position, rotation, scale, and flip orientation. In your game’s Update method, add the following lines of code:
// Read the current gamepad state
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);
// Move the sprite based on the left thumb stick
spritePosition.X += spriteSpeed *
currentGamePadState.ThumbSticks.Left.X *
(float)gameTime.ElapsedGameTime.TotalSeconds;
spritePosition.Y -= spriteSpeed *
currentGamePadState.ThumbSticks.Left.Y *
(float)gameTime.ElapsedGameTime.TotalSeconds;
// Flip the sprite horizontally if the A button is pressed
if (currentGamePadState.Buttons.A == ButtonState.Pressed &&
lastGamePadState.Buttons.A == ButtonState.Released)
{
flipOptions ^= SpriteEffects.FlipHorizontally;
}
// Flip the sprite vertically if the X button is pressed
if (currentGamePadState.Buttons.X == ButtonState.Pressed &&
lastGamePadState.Buttons.X == ButtonState.Released)
{
flipOptions ^= SpriteEffects.FlipVertically;
}
// Set rotation based on trigger positions
rotation = (-currentGamePadState.Triggers.Left +
currentGamePadState.Triggers.Right) *
MathHelper.Pi;
// Set scale with DPad Up and Down buttons
if (currentGamePadState.DPad.Up == ButtonState.Pressed)
scale += (float)gameTime.ElapsedGameTime.TotalSeconds;
else if (currentGamePadState.DPad.Down == ButtonState.Pressed)
scale -= (float)gameTime.ElapsedGameTime.TotalSeconds;
// Save the last frames state
lastGamePadState = currentGamePadState;
The only remaining bit of code you need now is the sprite’s draw code. In your game’s Draw method, add the following lines of code:
// Draw the sprite
spriteBatch.Begin();
spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White,
rotation, spriteCenter, 1.0f, flipOptions, 0);
spriteBatch.End();
Run the resulting game. The gamepad controls the sprite’s position, rotation, scale, and flip orientation (see Figure 2).
Thumb Stick Dead Zones
When
you request the state of the gamepad, by default, a dead zone is
applied to the thumb sticks. The thumb sticks on controllers do not
always return directly to the center resting position when released. If
you use the raw values of the thumb sticks, your game continues to read
thumb stick values other than 0. This can cause the game character to
move when the user is not pressing the thumb stick. The GamePadDeadZone enum defines three types of dead zones. The default used when calling GetState is IndependentAxes, which compares each axis separately to determine whether the values should be set to 0. The Circular dead zone uses the X and Y positions in combination to determine whether the values should be set to 0. The last type is None, which causes GetState to return the raw values from the thumb sticks. Use None to implement your own dead zone processing.
Other Types of Controllers
Up to this point, we have
focused on the Xbox 360 controller gamepad, but the XNA Game Studio APIs
support a number of different gamepad types. To determine the type of
gamepad, use the GamePad.GetCapabilities method to return a GamePadCapabilities structure.
The type of gamepad is defined by the GamePadType property. It returns a GamePadType enum value for the many different types of gamepads. Table 7 contains the enumeration values for GamePadType.
Table 7. GamePadType Enumerations
Name | Description |
---|
GamePad | Default Xbox 360 controller |
Guitar | Guitar controller used for music games |
AlternateGuitar | Guitar controller used for music games |
DrumKit | Drum controller used for music games |
ArcadeStick | Arcade stick used for fighting or arcade games |
DancePad | Dance pad used for rhythmic dancing games |
FlightStick | Flight stick used for flying games |
Wheel | Wheel controller used for driving games |
BigButtonPad | Big Button controller used for trivia games |
Unknown | The controller type is unknown and not supported |
Using the GamePadType,
you can determine whether the gamepad is the default controller or
whether another type of gamepad is connected. This is helpful for games
that require specific controllers, such as the DancePad or DrumKit. For racing games and flying games, the Wheel and FlightStick
gamepad types can be used by a player. Your game logic is most likely
that you want to handle user input differently from a Wheel than an Xbox
360 controller. To determine whether player two’s gamepad is a Guiter, use the following lines of code:
GamePadCapabilities gamePadCapabilities = GamePad.GetCapabilities(PlayerIndex.Two);
if (gamePadCapabilities.GamePadType == GamePadType.Guitar)
{
// Player two is using a Guitar
}
Note
A GamePadType is Unknown when the gamepad type is not supported by XNA Game Studio.
Along with the GamePadType, the GamePadCapabilities
contains many properties that enable you to determine whether the
controller supports specific buttons, thumb sticks, or triggers.
The big button controller has a unique BigButton along with four smaller A, B, X, Y buttons (see Figure 3).
This controller is great for trivia games where users want to quickly
hit a big button to ring in their answer. The four other buttons can
then be used to specify their answers.
Is the Gamepad Connected?
What happens if you read the state of a gamepad that is not connected? Although XNA Game Studio supports up to four PlayerIndex values when calling GamePad.GetState, it does not mean that four gamepads are connected. To determine whether a gamepad is connected, use the GamePadState.IsConnected
property. This is a simple boolean value that tells you whether the
gamepad is connected or not. To determine whether player four’s
controller is connected, use the following lines of code:
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.Four);
bool playerFourConnected = currentGamePadState.IsConnected;
Note
The GamePadCapabilities structure also contains a IsConnected property that can be used to determine whether the gamepad is connected.