MULTIMEDIA

Microsoft XNA Game Studio 3.0 : Getting Player Input - Reading a Gamepad

2/19/2011 4:38:51 PM

1. Introduction

You now know the basics of computer game programming. You know that a program is actually a sequence of statements, each of which performs a single action. You have seen that statements are held inside methods, each of which performs a particular task, and that methods are held in classes along with data. The program itself works on data values, which are held in variables of a particular type, and the program can make decisions based on the values that the variables have.

Now you are going to expand your understanding to include how to receive input from the outside world so that games can actually react to what the player does. You shall see that once we have done this, a number of possibilities open up, and you can create some truly silly games, including "Color Nerve," "Mind Reader," "The Thing That Goes Bump in the Night," and "Gamepad Racer."


Before you start looking at gamepads, though, you need to decide how the program will actually work. Consider the following statement of C# from the previous mood-light program, which is part of the Update method:

if (redCountingUp) redIntensity++;

This is one of the tests that controls the intensity of the red part of the color. What it is saying is "If the Boolean value redCountingUp is True, increase the value of redIntensity by 1." The statement is processed each time Update is called (at the moment that is 60 times a second), so this means that if redCountingUp is True, the red intensity of the screen gets progressively brighter over time.

You want to write some code that says, "If the red button on Gamepad 1 is being pressed, increase the value of redIntensity by 1." Then, if the player holds down the button, the screen gets redder. So all you have to do is change this test to read the button on the gamepad, and you can create a user-controlled light easily.

2. Reading a Gamepad

The gamepads are actually very complex devices. They are connected to the host device either by a universal serial bus (USB) cable or by a wireless connection. As far as you are concerned, the way that programs work with gamepads does not depend on how they are connected. The connection to a gamepad can be used to read the buttons and joysticks and can also be used to send commands to the gamepad—for example, to turn the vibration effect on and off. The Xbox and XNA provide support for up to four gamepads connected simultaneously. The Zune has a single gamepad with two buttons that can be used for input. It is used in exactly the same way as the Xbox gamepad.

2.1. Gamepads and Classes

The gamepad information is represented in XNA by means of a class called GamePadState. The job of this class is to provide the connection between the program and the physical gamepad that the player is holding. To understand how you are going to use this, you have to learn a bit more about how classes work.

A class contains data (variables that can hold stuff) and methods (code that can do stuff). You can think of a class as an office, with a desk holding the variables and people acting as the methods. Figure 1 shows the office plan for the class Game1, which you have seen is the basis of an XNA game.

This class contains some variables on the desk (in this case, the background color intensities) and two methods, which we have called Mr. Draw and Mrs. Update. Each method has a corresponding telephone. Programs can place calls to the telephones to request that the method perform the required task.

Figure 1. The Game1 class as an office plan



Note:

Our Great Programmer has been reading these notes and finds them quite amusing. She says that classes are not exactly like offices, but she thinks that for the purpose of getting an understanding of how programs are constructed, it is okay to regard them as such.


When an XNA game starts, the XNA system makes an instance of the Game1 class that it then can ask to Draw and Update. When an instance of a class is created, the instructions for the methods that it contains are loaded into memory and space is set aside for the data variables that the instance holds.

The class files that you write give the plans for the class so when the program runs, instances of each class can be created. In real life, you would make a game office by building a room, putting a desk and some telephones in the room, and then hiring a Mr. Draw and a Mrs. Update. The process of making an instance of a class is similar. However, to save memory, the running program uses only one copy of the method code, which is shared among all the instances of a class.


Note:


It is important to remember that this happens when a program runs. The process of creating instances of classes is not performed by the compiler. The job of the compiler is to convert your C# source code into instructions that the target device runs. By the time that your program has control, the compiler has done its job, and the computer is just running the machine language output that the compiler produced.


2.2. Finding a Gamepad

XNA also looks after a lot of other things when a game is running, one of which is the GamePad class connected to all the gamepads. You don’t have to know how the gamepad is actually connected; for all you know, it might use tiny pixies traveling up and down the wires carrying pixie notes written on pixie paper saying "Master has pressed the Red Button," but then again it might not. Figure 2 shows how the GamePad class would look if it were an office.

Figure 2. The GamePad class as an office


The GamePad class contains a method called GetState, which gets the state of one of the gamepads. When GetState is called, it looks at one of the gamepads, reads its settings, and then sends information back for use in the statement it was called from.

The GetState method is supplied with a parameter that identifies the gamepad to be read. A parameter is a way that a call can give information to a method. You have seen these before; in your very first programs, you were passing Color parameters into the Clear method to select the color of the screen that you wanted.

In the case of the GetState method, the parameter identifies the gamepad that you want to read. If you are thinking in terms of offices, you can think of a parameter as part of the instructions that come down the telephone. When the phone rings and Mr. GetState answers it, he is asked, "Get me the state of Gamepad 1." The information about the state of the gamepad is sent back in a GamePadState structure, which is shown in Figure 3.

Figure 3. GamePadState structure with the green A button pressed


You can think of this as a set of items filled in on a form if you wish, but actually it is a C# structure that contains the data members shown in Figure 3, as well as some other data.

So, if Mrs. Update wants to know the state of one of the gamepads on the Xbox, she calls the GetState method in the GamePad class and asks, "Can you give me the state of the gamepad for Player 1, please?" Mr. GetState jumps up, fills in a "GamePadState" form, and sends it back to her. Figure 4 gives the breakdown of the C# statement that gets the state of a gamepad into a variable of type GamePadState.

Figure 4. Getting the status of a gamepad


3. Testing the Gamepad Status

Now that you have the status, you can use it in the program to see if a button has been pressed. Figure 5 shows the breakdown of the C# statement that will perform the test.

Figure 5. Testing a button on a gamepad


This compares the state of the red button B with the value ButtonState.Pressed. If the two are equal, this means that the button is down, and the Update method must make the red intensity bigger. You can then use the same principle to manage the blue and green values, which means that you now have an Update method that looks like the following:

protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

GamePadState pad1 = GamePad.GetState(PlayerIndex.One);

if (pad1.Buttons.B == ButtonState.Pressed) redIntensity++;
if (pad1.Buttons.X == ButtonState.Pressed) blueIntensity++;
if (pad1.Buttons.A == ButtonState.Pressed) greenIntensity++;

base.Update(gameTime);
}


The only problem with the Update method described here is that the program doesn’t handle the yellow button yet. When the yellow button is pressed, the program needs to increase the green and the red intensities; that is, it must perform two statements if the condition is true. It turns out that doing so is very easy; you can just put the two statements into a block that is controlled by the condition, as shown here:

if (pad1.Buttons.Y == ButtonState.Pressed)
{
redIntensity++;
greenIntensity++;
}

You have seen blocks before; the body of a method (the bit that does the work) is a block. In C# terms, a block is a number of statements that are enclosed in curly braces. The code shown here performs both statements if the condition is true because they are in a block controlled by the condition.


Note:

Our Great Programmer tends to use blocks after if conditions even when she doesn’t actually need to. She says that it makes the program text clearer and that it is much easier to add extra statements later if you need to.


If you put the preceding statements into the Update method of one of your earlier Mood-Light programs, you get compiler warning messages because the new version of Update doesn’t use all the variables that were created for previous versions of the program. To get rid of these warnings, you must delete the statements that create the unused variables. The Great Programmer doesn’t like it when programs have variables in them that are not used. She says this looks unprofessional, and I agree with her.

4. Zune Buttons

You can run this program on a Zune. However, it doesn’t have colored buttons—the Play button is the same as button B (Red) on a gamepad, and pressing the center of the joypad is the same as pressing A (Green), but the other buttons are not supported. However, you can create a Moodlight for the Zune by using the Dpad inputs as follows:

if (pad1.DPad.Left == ButtonState.Pressed) blueIntensity++;
if (pad1.DPad.Right == ButtonState.Pressed) redIntensity++;
if (pad1.DPad.Down == ButtonState.Pressed) greenIntensity++;
if (pad1.DPad.Up == ButtonState.Pressed)
{
redIntensity++;
greenIntensity++;
}

The Zune control pad is mapped onto the Dpad on the gamepad, so this code also allows the MoodLight to be controlled by the Dpad on a gamepad.

Game Idea: Color Nerve


Every now and then, we are going to try out a game idea. These start out very simply and then build up to more complicated and interesting games. You can use the Manual MoodLight code to create your first game. You noticed that if you keep making a value bigger, there comes a point where it won’t fit in the memory store allocated for it, and then it overflows. This is what caused the screen to go from bright white to black. However, you can use this to create our first "Very Silly Game."

Color Nerve is a game for two or more players. The players take turns pressing one or more buttons on the gamepad. (The other players must watch carefully to make sure that they actually do press at least one button.) Each player can press as many buttons as he wants for as long as he wants during his turn, but if the screen changes suddenly (because one of the color values has gone from 255 to 0), he is out, and the game continues. The last player left in the game is the winner.

This game can be very tactical. Players can press the buttons for very short times, or at the start of the game, they can show their nerve by holding the buttons down for longer periods, trying to cause problems for the next player. They can also try to work out which color has wrapped around so that they can press that button when it is their turn.


Other  
  •  iPhone 3D Programming : Blending and Augmented Reality - Shifting Texture Color with Per-Vertex Color
  •  iPhone 3D Programming : Blending and Augmented Reality - Blending Extensions and Their Uses
  •  iPhone 3D Programming : Blending and Augmented Reality - Blending Caveats
  •  Building LOB Applications : Using Visual Studio 2010 WCF RIA Data Services Tooling
  •  Building LOB Applications : Implementing CRUD Operations in WCF Data Services
  •  iPhone 3D Programming : Blending and Augmented Reality - Wrangle Premultiplied Alpha
  •  iPhone 3D Programming : Blending and Augmented Reality - Blending Recipe
  •  Microsoft XNA Game Studio 3.0 : Controlling Color (part 3)
  •  Microsoft XNA Game Studio 3.0 : Controlling Color (part 2)
  •  Microsoft XNA Game Studio 3.0 : Controlling Color (part 1) - Games and Classes & Classes as Offices
  •  Microsoft XNA Game Studio 3.0 : Working with Colors
  •  iPhone 3D Programming : Textures and Image Capture - Creating Textures with the Camera
  •  iPhone 3D Programming : Textures and Image Capture - Dealing with Size Constraints
  •  Programming with DirectX : Game Math - Vectors
  •  iPhone 3D Programming : Textures and Image Capture - Generating and Transforming OpenGL Textures with Quartz
  •  iPhone 3D Programming : Textures and Image Capture - The PowerVR SDK and Low-Precision Textures
  •  Building LOB Applications : Using Visual Studio 2010 WCF Data Services Tooling
  •  Building LOB Applications : Accessing RESTful Data using OData
  •  Programming with DirectX : Additional Texture Mapping - Image Filters
  •  Microsoft XNA Game Studio 3.0 : Making a Game Program
  •  
    Most View
    The Best Apps and Gear of 2012 (Part 10)
    Stereo Speakers Awards – Q1 2013 (Part 3)
    Top 10 Televisions – Q1 2013
    SQL Server 2005 : Advanced OLAP - Partitions, Aggregation Design, Storage Settings, and Proactive Caching
    The Ultimate PC Security Toolbox (Part 2)
    What’s New In Speakers? – April 2013 (Part 1)
    Accelerating USB 3.0 Implementations - Time Is Money
    The Cat You Have To Have (Part 4)
    How To Buy… A Gaming Case (Part 1)
    Asus Padfone - A Powerful Smartphone
    Top 10
    10 Contenders For The 'Ultimate Protector' Crown (Part 5) : Microsoft Security Essentials 4.1, AVG Antivirus Free 2013
    10 Contenders For The 'Ultimate Protector' Crown (Part 4) : Norton Internet Security, Avast Free Antivirus Version 7
    10 Contenders For The 'Ultimate Protector' Crown (Part 3) : Eset Smart Security 6, Kaspersky Internet Security 2013, Zonealarm Internet Security 2013
    10 Contenders For The 'Ultimate Protector' Crown (Part 2) : Bitdefender Total Security 2013, Trend Micro Maximum Security, Mcafee Internet Security 2013
    10 Contenders For The 'Ultimate Protector' Crown (Part 1)
    Sony Xperia TL - Much Improved But Still Imperfect (Part 3)
    Sony Xperia TL - Much Improved But Still Imperfect (Part 2)
    Sony Xperia TL - Much Improved But Still Imperfect (Part 1)
    Simple.TV - Transmits TV Programs To Mobile (Part 2)
    Simple.TV - Transmits TV Programs To Mobile (Part 1)