HomeUncategorized › Mouse Traps

Mouse Traps

Recently there was a discussion in the ##XNA channel on Freenode about how to constrain the mouse to the game-window. The solution proved to be non-obvious and required a little bit of creativity to implement.

[The Mouse]

Add the following to your using statements:

using System.Runtime.InteropServices;

Inside your Game class, add the following:

[DllImport("user32.dll")]
static extern void ClipCursor(ref Rectangle rect);
[DllImport("user32.dll")]
static extern void ClipCursor(IntPtr rect);

Add the following code to your game’s Initialize() method:

this.IsMouseVisible = true;

Rectangle rect = Window.ClientBounds;
rect.Width += rect.X;
rect.Height += rect.Y;

ClipCursor(ref rect);

Finally, inside your game’s Update() method add:

if (IsActive)
{
     Rectangle rect = Window.ClientBounds;
     rect.Width += rect.X;
     rect.Height += rect.Y;

     ClipCursor(ref rect);
}

[The Trap]

A few things to note about the above. The ClipCursor() function expects a pointer to a Rectangle, so we pass in a reference. To allow the cursor to move freely anywhere on the screen again, one has to pass null instead of a rectangle. Since you can’t pass in a null reference in C#, we have to overload the ClipCursor() function with a second one that allows for a null parameter (IntPtr rect).

ClipCursor() assumes that the rectangle contains the coordinates of the bounding area. Window.ClientBounds contains an XNA/C# style rectangle, which is defined by (X, Y, Width, Height). To get the actual bounding area, one has to adjust the Width/Height with the X/Y.

There is some debate over whether keeping the mouse inside the window border is a good idea or not. Situations where it’s required are probably pretty rare, but there are some high-profile games that do it (e.g. Minecraft).

[References]

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.mouse.aspx

http://msdn.microsoft.com/en-us/library/ms648383(v=vs.85).aspx

http://forums.create.msdn.com/forums/p/3553/18364.aspx

Comments are closed.