I was reviewing some of the search terms that brought people to my website. It seems like a lot of them are related to using the mouse in XNA, so I figured I’d write a quick post about determining the mouse or keyboard state in XNA. Though, that said, this applies to most anything that polls input and has a main game loop.

The Basics

First, let’s get some basics down. The way that input works in XNA is called “polling”. You use the classes provided by XNA to poll (check) the state of the mouse ( Mouse.GetState()) or keyboard ( Keyboard.GetState()) at a certain point in time. In your game loop, you can get the current state of the mouse and keyboard and use that to determine what the game should do.

Now, you’ll soon realize that it’s not very helpful only knowing what the mouse is currently doing. Take this for example: let’s say that you have code for clicking on the screen to create an object like so (pseudo code):

This seems like it makes sense, but what happens if the user has the mouse held down for more than one frame? Uh oh, this code will spawn an item PER FRAME, not per click as we want.

So, how do we get around this? It’s quite easy, really. We just keep track of the state of the mouse on the previous frame and then compare that state with the current state.

The Setup

Let’s set up our class for handling mouse input. Add these two fields to the top of your class right below the class Game1 { line (the name of your class may be different, no problem):

Add this code to the end of your LoadContent method:

Now, at the top of the Update method, add this:

The first two lines just declare the variables we’re going to use. As you may have guessed, _currentMouseState is going to hold the current state of the mouse and _previousMouseState is going to hold the state of the mouse on the previous frame.

The LoadContent code initializes the two values to the current mouse state so that they’re no longer null.

The Update is where the magic happens. First of all, we set _previousMouseState = _currentMouseState;. Remember that we don’t reset _currentMouseState at the end of the Update method, so this is actually setting _previousMouseState to the mouse state as it was on the previous call to Update. We then set the _currentMouseState to the current state of the mouse.

Next, we’ll look at how to use these.

Click, Hold, Release

There are four distinct states related to button presses on both the keyboard and mouse. They are:

State Previous Value Current Value Description
None Released Released The button is not pressed at all.
Click Released Pressed The button has been pressed for the first time between the last Update and this one.
Hold Pressed Pressed The button is being held down.
Release Pressed Released The button has been released since the previous Update.

Note: the first state should be considered “Released” since the button is not being pressed, but since you’ll rarely need to check for that I decided to call it “None” to prevent confusion with the “Release” action/state. Also, these are my names, I don’t know if there are more official names defined somewhere.

Putting It To Use

So, taking this into account, if we want to place an item only when the player first clicks on the screen, we’d do it using this code (in the Update method):

This will ensure that we only create the item once when the click is first registered.

So that’s really it, you just use different combinations of checks depending on what you want to do.

Extra Example

Here’s an example that uses the click, hold and release states for moving an object with the mouse. The focus is on checking the mouse state, not on the actual movement code, so I’ve just described the basic idea in comments.

Conclusion

So that’s about it. A mouse or keyboard button can be in one of four states: None, Click, Hold, or Release. In order to check what state it’s in, you need to keep a copy of the previous state to compare to the current state. These four states should give you all the control you need to handle any kind of mouse or keyboard events in your game.

Drop a comment if you have any questions or, well, comments. :)