For a while I have had some basic code to handle mouse functions in XNA Applications,
But as some of these are old and each have some different functions I thought this morning that I would put the simple mouse functions into a Drawable XNA Game Component. The component that I have put together will draw a custom mouse pointer on the screen and restrict the pointer to the current game window, when you leave the window the mouse will return to the normal mouse pointer you use in windows. At the same time the mouse will change color when the mouse buttons are pressed. There are a lot more functions that could be added to this, for example handling the wheel or adding events to the mouse states. One of the functions that I will be adding soon is a shadowed effect to the mouse pointer.
To use this game component add the following code to the top of the game class just under the initialization for the game manager and content manager so that it looks like this...
[code language="C#"]
GraphicsDeviceManager graphics;
ContentManager content;
GameComponents.MousePointer mousePointer;
[/code]
Next change you initialization code to look like this...
[code language="C#"]
protected override void Initialize()
{
// TODO: Add your initialization logic here
this.Window.Title = "Virtual Realm - Custom Mouse Pointer Example";
this.mousePointer = new CustomMouse.GameComponents.MousePointer(this);
this.mousePointer.DrawOrder = 1000;
this.mousePointer.RestrictZone = new Rectangle(0, 0,
this.graphics.GraphicsDevice.Viewport.Width,
this.graphics.GraphicsDevice.Viewport.Height);
this.Components.Add(this.mousePointer);
base.Initialize();
}
[/code]
I have set up a restrictZone that will restrict the mouse to the screen, this makes sure that the icon will stay in the sceens viewport, also changing the draw order to a high number (1000) will make sure that the mouse cursor is drawn above all other items on the screen.
The final stge is to load the content for the pointer, in this example I am using a simple arrow texture, but you could use anything you like to work in with your application.
[code language="C#"]
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content
this.mousePointer.PointerTexture = content.Load<Texture2D>(@"Content/Arrow");
}
// TODO: Load any ResourceManagementMode.Manual content
}
[/code]
Now here is the Game Component code, I have created a folder called GameComponents where I put the game components I am working on, this helps to keep the code looking clean. Create the directory and add the following class file to application.
[code language="C#"]
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion
namespace CustomMouse.GameComponents
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class MousePointer : Microsoft.Xna.Framework.DrawableGameComponent
{
private SpriteBatch spriteBatch;
public Vector2 MousePosition;
private MouseState CurrentMouseState;
private MouseState PreviousMouseState;
private Color pointerColor = Color.White;
private Texture2D pointerTexture;
public Texture2D PointerTexture
{
get { return pointerTexture; }
set { pointerTexture = value; }
}
private Rectangle restrictZone;
public Rectangle RestrictZone
{
get { return restrictZone; }
set { restrictZone = value; }
}
public MousePointer(Game game)
: base(game)
{
// TODO: Construct any child components here
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
}
// TODO: Load any ResourceManagementMode.Manual content
base.LoadGraphicsContent(loadAllContent);
}
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
base.UnloadGraphicsContent(unloadAllContent);
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
this.CurrentMouseState = Mouse.GetState();
this.MousePosition.X = this.CurrentMouseState.X;
this.MousePosition.Y = this.CurrentMouseState.Y;
// Restrict the Mouse so that it stays inside the current display
if (this.MousePosition.X < 0)
this.MousePosition.X = 0;
if (this.MousePosition.X > this.restrictZone.Width)
this.MousePosition.X = this.restrictZone.Width;
if (this.MousePosition.Y < 0)
this.MousePosition.Y = 0;
if (this.MousePosition.Y > this.restrictZone.Height)
this.MousePosition.Y = this.restrictZone.Height;
if (this.CurrentMouseState.LeftButton == ButtonState.Pressed)
{
this.pointerColor = Color.Red;
}
else
{
this.pointerColor = Color.White;
}
if (this.CurrentMouseState.RightButton == ButtonState.Pressed)
{
this.pointerColor = Color.Red;
}
else
{
this.pointerColor = Color.White;
}
this.PreviousMouseState = this.CurrentMouseState;
base.Update(gameTime);
}
/// <summary>
/// Allows the game commponent to Draw itself
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values</param>
public override void Draw(GameTime gameTime)
{
this.spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
this.spriteBatch.Draw(this.pointerTexture, this.MousePosition, this.pointerColor);
this.spriteBatch.End();
base.Draw(gameTime);
}
}
}
[/code]
I do hope that someone finds this useful, if you have any sugestions please drop me a line.