O'Reilly logo

Learning XNA 4.0 by Aaron Reed

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Gamepad Input

If you’re developing a game for Windows, you can still program for an Xbox 360 controller. You’ll have to have a wired controller, or you can purchase an Xbox 360 Wireless Receiver for around $20, which will allow you to connect up to four wireless controllers to a PC.

Tip

The wireless Xbox 360 controller actually does come with a wire if you buy the charge pack for that controller. However, there is no data transfer over that cable, so even when it’s plugged in, it’s still a wireless controller. The cable on the charge pack transfers electricity for the charge and nothing more.

Just as XNA provides a Mouse class for mouse input and a Keyboard class for keyboard input, it provides a GamePad class for reading input from an Xbox 360 gamepad. And yes, that’s right, there’s a GetState method for the GamePad class, just as there is for the other devices. There’s something to be said for standards, and Microsoft’s XNA Framework is, for the most part, a superb example of how standardization across a large-scale system (in this case, a framework and API) can be of such great benefit. Most of the time, you can tell how to use an object just by understanding the type of the object and knowing how similarly typed objects function. That’s a tribute to a great design by the XNA team—kudos to them.

The GetState method for the GamePad class accepts an enum parameter called PlayerIndex that indicates which player’s controller you want to access, and it returns a GamePadState struct that you can use to get data from the selected controller. Key properties of the GamePadState struct are listed in Table 4-3.

Table 4-3. Key properties of the GamePadState struct

Property

Type

Description

Buttons

GamePadButtons

Returns a struct that tells which buttons are currently pressed. Each button is represented by a ButtonState enum that specifies whether the button is pressed or not pressed.

DPad

GamePadDPad

Returns a struct that tells which directions on the DPad are pressed. The DPad struct has four buttons (up, down, left, and right), each of which is represented by a ButtonState enum that specifies whether the button is pressed or not pressed.

IsConnected

boolean

Indicates whether the controller is currently connected to the Xbox 360.

ThumbSticks

GamePadThumbSticks

Returns a struct that determines the directions of the thumbsticks. Each thumbstick (left and right) is a Vector2 object with X and Y values that have limits of −1 to 1 (e.g., for the left thumbstick, if you push it all the way left, its X value will be −1; if you don’t push it at all, the X value will be 0; and if you push it all the way to the right, the X value will be 1).

Triggers

GamePadTriggers

Returns a struct that tells whether the triggers are pressed. The Triggers struct contains two float values (left and right). A value of 0 means the trigger is not pressed at all, whereas a value of 1 means the trigger is fully pressed.

The GamePadState struct contains two methods that will give you most of the functionality you need. These methods are listed in Table 4-4.

Table 4-4. Key methods of the GamePadState struct

Method

Description

bool IsButtonDown(Buttons)

Pass in a button or multiple buttons with a bitwise OR. Returns true if all buttons are down, and false otherwise.

bool IsButtonUp(Buttons)

Pass in a button or multiple buttons with a bitwise OR. Returns true if all buttons are up, and false otherwise.

Looking at the properties in Table 4-3, you’ll notice that some of the controls are represented by Boolean or two-state values (either on or off), and others are represented by values that fluctuate between a range of numbers (0 to 1, or −1 to 1). These ranged properties are referred to as analog controls, and because they don’t have a simple on or off value, they offer more accuracy and more precision in a gaming control. You might have noticed that in some games on an Xbox 360 you can move at different speeds with the triggers or thumbsticks. This is because as you press either button in a given direction, the controller will send a signal to the application in varying strengths. This is an important concept to remember when programming against an Xbox 360 controller and a feature that you’ll want to incorporate into games that you develop. We cover how to do that in this section.

All right, let’s add some code that will let you control your sprite with your Xbox 360 gamepad. Just as before, leave the code for the mouse and keyboard there, too, and you’ll have three ways to control your sprite.

Because the thumbsticks can contain X and Y values ranging from −1 to 1, you’ll want to multiply those values of the ThumbSticks property by the ringsSpeed variable. That way, if the thumbstick is pressed all the way in one direction, the sprite will move at full speed in that direction; if the thumbstick is only slightly pushed in one direction, it will move more slowly in that direction.

The following code will adjust your sprite’s position according to how much and in which direction the left thumbstick on player one’s controller is pressed. Add this code to the Update method, just below the code for the keyboard and mouse input:

GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
ringsPosition.X += ringsSpeed * gamepadState.ThumbSticks.Left.X;
ringsPosition.Y −= ringsSpeed * gamepadState.ThumbSticks.Left.Y;

Compile and run the application now, and you’ll have full control of your three rings sprite using your Xbox 360 controller.

Let’s spice things up a bit. Using an Xbox 360 controller should be a bit more fun than it currently is. Let’s add a turbo functionality that doubles your movement speed when active. Of course, when moving so rapidly around the screen in turbo mode, you should feel some vibration in your controller due to the dangerous velocity at which you’ll be moving your sprite. You’ve probably felt the vibrations in an Xbox 360 controller before. This type of mechanism is referred to as force feedback, and it can greatly enhance the gameplay experience because it adds yet another sense that pulls the user into the game.

The method SetVibration will set vibration motor speeds for a controller. The method returns a Boolean value indicating whether it was successful (false means that either the controller is disconnected or there is some other problem). The method accepts a player index, and a float value (from 0 to 1) for the left and right motors of the controller. Set the values to zero to stop the controller from vibrating. Anything above zero will vibrate the controller at varying speeds. Modify the code you just added to move the sprite with the Xbox 360 controller to include the following:

GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
if (gamepadState.Buttons.A == ButtonState.Pressed)
{
    ringsPosition.X += ringsSpeed * 2 * gamepadState.ThumbSticks.Left.X;
    ringsPosition.Y −= ringsSpeed * 2 * gamepadState.ThumbSticks.Left.Y;
    GamePad.SetVibration(PlayerIndex.One, 1f, 1f);
}
else
{
    ringsPosition.X += ringsSpeed * gamepadState.ThumbSticks.Left.X;
    ringsPosition.Y −= ringsSpeed * gamepadState.ThumbSticks.Left.Y;
    GamePad.SetVibration(PlayerIndex.One, 0, 0);
}

The code first checks to see if the A button on the controller is pressed. If it is, turbo mode is activated, which means that you’ll move the sprite at twice the normal speed and activate the vibration mechanism on the controller. If A is not pressed, you deactivate the vibration and move at normal speed.

Compile and run the game to get a sense of how it works.

As you can see, the gamepad adds a different dimension of input and gives a different feel to the game itself. It’s a powerful tool, but it won’t work well with all game types. Make sure you think about what type of input device is best for the type of game you are creating, because the input mechanism can go a long way toward determining how fun your game is to play.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required