Moving Items with Microsoft Visual Studio, XNA Game Studio and a GamePad

In my previous article, I briefly covered installing the XNA Game Studio. The article proceeded to how you how to create a simple application that displayed an image. You also learned how to change the size and location of that image within your code.

Using an Xbox Game Pad with Your Applications

Now, you’ll learn how to use an Xbox game pad with your applications. You’ll see how to use some of the buttons on the Xbox controller including the X, Y, A, and B button as well as the LeftShoulder, RightShoulder, LeftStick, RightStick, and other controls. Specifically, you’ll see how to move an image around on the page using some of these controls.

You should start with the final code listing from the previous article that helped you load an image. Alternatively, you can create a new XNA Windows Game project. From either listing, you’ll find two lines of code that were automatically added to the project when it was created. These lines are worth pointing out now:


if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
     this.Exit();

If you look at this code, you’ll see that it is referencing a game pad. If you have a wired Xbox controller, you can plug it into a USB port on your PC and use it. The above line of code will then exit the game if the back button on the game pad is pressed. You could also test for other buttons on the controller. For example, the following adds checks to see if the A button is pressed:

if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
{
    // Do something...
}

In addition to the A button, you can also check the B, X, Y, and other buttons for a press in the same way. You can also check for button presses on the left and right sticks as well. If you do this in the Update method, then you will check the status of the button each time the game loops, which will be around 30 times a second. As such, each time Update is checked, if the A button is pressed, the logic above will execute. For example, if you wanted to move a rectangle in your program, you could use the A button to move it down on the page. You could do this by adjusting where the rectangle is drawn. A rectangle called myRect could have its Y value incremented each time the program loops and it finds the A button is pressed:

if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
{
    if (myRect.Y < (GraphicsDevice.Viewport.Height - myRect.Height ))
        myRect.Y++;
}

This code would adjust the Y coordinate where the rectangle called myRect is being drawn on the screen. It would do this when the Y coordinate is less than the size of the window minus the size of the image. This means that the image will move down the window, but not off the window. Of course, this code only adjusts the Y coordinate in the rectangle. It doesn't actually draw the rectangle on the page, nor does it set up the rectangle initially. Of course, you learned how to do that in the previous article.

Using what has just been covered, you could use the X, Y, A, and B buttons to move the image around the window. To do this, you follow similar logic to what was presented earlier:

if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
{
    if (myRect.Y < (GraphicsDevice.Viewport.Height - myRect.Height ))
        myRect.Y++;
}
if (GamePad.GetState(PlayerIndex.One).Buttons.Y == ButtonState.Pressed)
{
    if (myRect.Y > 1)
        myRect.Y--;
}
if (GamePad.GetState(PlayerIndex.One).Buttons.B == ButtonState.Pressed)
{
    if (myRect.X < (GraphicsDevice.Viewport.Width - myRect.Width ))
        myRect.X++;
}
if (GamePad.GetState(PlayerIndex.One).Buttons.X == ButtonState.Pressed)
{
    if (myRect.X > 1)
        myRect.X--;
}

This code can be added to the update method of the listing from the previous article. Listing 1 provides you with the complete listing with this code added.

Listing 1. Moving a picture around with a gamepad

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace PictureMover
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        private Texture2D myPicture;
        private Rectangle myRect;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here

            myPicture = Content.Load<Texture2D>("CGPicture");
            myRect = new Rectangle(50, 100, myPicture.Width, (2 * myPicture.Height));
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values. </param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
            {
                if (myRect.Y < (GraphicsDevice.Viewport.Height - myRect.Height))
                    myRect.Y++;
            }
            if (GamePad.GetState(PlayerIndex.One).Buttons.Y == ButtonState.Pressed)
            {
                if (myRect.Y > 1)
                    myRect.Y--;
            }
            if (GamePad.GetState(PlayerIndex.One).Buttons.B == ButtonState.Pressed)
            {
                if (myRect.X <  (GraphicsDevice.Viewport.Width - myRect.Width ))
                    myRect.X++;
            }
            if (GamePad.GetState(PlayerIndex.One).Buttons.X == ButtonState.Pressed)
            {
                if (myRect.X > 1)
                    myRect.X--;
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            spriteBatch.Draw(myPicture, myRect, Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read