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):
1 2 3 4 5 |
Update(GameTime gameTime) { if (currentMouseState.LeftButton == ButtonState.Pressed) { //Create object at current mouse position } } |
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):
1 2 |
MouseState _currentMouseState; MouseState _previousMouseState; |
Add this code to the end of your LoadContent method:
1 2 |
_currentMouseState = Mouse.GetState(); _previousMouseState = _currentMouseState; |
Now, at the top of the Update method, add this:
1 2 |
_previousMouseState = _currentMouseState; _currentMouseState = Mouse.GetState(); |
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):
1 2 3 4 |
if (_previousMouseState.LeftButton == ButtonState.Released && _currentMouseState.LeftButton == ButtonState.Pressed) { //Create object at current mouse position } |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
if (_previousMouseState.LeftButton == ButtonState.Released && _currentMouseState.LeftButton == ButtonState.Pressed) { //Click! //Find the object under the mouse and save it to a variable. //If there's no object under the mouse, set the variable to null. //Note: Make sure the variable is declared in the class, not in // the Update method. } else if (_previousMouseState.LeftButton == ButtonState.Pressed && _currentMouseState.LeftButton == ButtonState.Pressed) { //Hold! //If the variable is not null, move the object to the same // position as the mouse } else if (_previousMouseState.LeftButton == ButtonState.Released && _currentMouseState.LeftButton == ButtonState.Pressed) { //Release! //If the variable is not null, move the object to the same // position as the mouse (i.e. "drop" it) and then set the // variable to null to remove the reference. } |
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. 🙂