The ModifyMouseState event is an event you can add to the Mouse object to set/modify the Microsoft.Xna.Framework.Input.MouseState used by the mouse for positioning and clicking. This is useful if you are working on a platform which does not have mouse input but you would like to simulate mouse input, or if you are working on a platform which requires modifications of the mouse input.
The following code can be used in a WPF project to properly set the mouse position. Add the following to your Game's Initialize function:
Add the following implementation:
The Mouse class provides functionality for grabbing and moving any object which implements the PositionedObject class. This includes common FlatRedBall types like and as well as entities created in Glue. The following code creates 9 and allows the user to click and drag to control the . This code can be added to any FlatRedBall Screen
Setting the GrabbedPositionedObject does the following:
Stores the reference in the GrabbedPositionedObject property
Stores offset variables - this is the difference between the GrabbedPositionedObject's position and the cursor's world coordinates.
Updates the GrabbedPositionedObject's position every frame using the Mouse's world coordinates and the offset values. This is performed automatically - there is no need to manually manage positions when using GrabbedPositionedObject.
In the example above the Sprites do not have any parents so they can be grabbed and moved freely by the cursor. It is common to have Sprites as part of Glue entities, in which case the Sprite is attached to the entity. If the GrabbedPositionedObject has a non-null Parent, then it cannot be moved. In this situation it is more common to grab (and move) the parent entity.
The Mouse class provides functionality for getting input data from the physical mouse. This class is automatically instantiated by and accessible through the InputManager.
There are many ways to get data from the mouse. The following section of code is a series of if-statements which could be used to detect input from the mouse.
The mouse scroll wheel is exposed through the InputManager.Mouse.ScrollWheel property. The ScrollWheel property returns the number of "clicks" that the scroll wheel has moved since last frame. The following code controls the Z position of the camera based on the ScrollWheel property.
The Mouse class provides information about the cursor's pixel coordinates.
The mouse coordinates are top left justified, so (0,0) represents the top left corner of the screen. Keep in mind that the pixel coordinates are relative to the top-left of the screen, but not bound by your game screen. That means that if the cursor is to the left (outside of) your game screen, then the X value will be negative. Also, the mouse will continue to return values when the cursor is to the right or below the game screen, resulting in values which are potentially larger than the width or height of the screen.
The Mouse reports the world coordinates of the cursor through the functions WorldXAt and WorldYAt.
Certain activities should only occur if the mouse is in the window. To test for this, use the following code: Add the following using statement:
The following code performs the check:
The SetScreenPosition method allows for control over the native Windows mouse. This method can be used to override the behavior of the mouse.
The IsOn3D method is a method which can be used to detect whether the mouse is over a variety of different objects. The reason it is called IsOn3D is because it performs a 3D test (ray cast) so it works regardless of the camera orientation of the orientation of the object being tested.
The following code creates a Text object. This text object will turn white when the mouse moves over the Text, but will remain blue if the mouse is not over it.
Add the following using statements:
Add the following at class scope:
Add the following to Initialize after initializing FlatRedBall:
Add the following to Update:
Warning: You should always use the non-generic version of IsOn3D when performing tests on Text objects. Want to know more? Read on!
There are a number of overloads for the IsOn3D method. The two which apply to the Text object are:
You may be wondering which to use, why there are two versions, and how you can pick which version you are using.
First, you should use the non-generic version. That is, you should use the version that takes a Text argument.
So why are there two versions? The reason is because the generic IsOn3D is a method that is used to test whether the Mouse is over types such as Sprites and SpriteFrames. Since these objects all implement IPositionable, IRotatable, and IReadOnlyScalable, then this generic function works well.
The reason that the Text object can use the generic version of IsOn3D is because it also implements the necessary interfaces; however, even though it implements the IReadOnlyScalable, it is slightly different from the Sprite and SpriteFrame classes.
The Sprite and SpriteFrame classes both are always centered on their position. This means that the right edge of these objects is always X + ScaleX. However, this is not the case for the Text object due to its VerticalAlignment and HorizontalAlignment properties. These properties can change how the Text is drawn relative to its actual position. For this reason, the assumption that the Text's position is at its center is not valid.
This means that if the Text object is centered both horizontally and vertically, then the generic IsOn3D will accurately determine whether the mouse is over the Text. But if either property is not centered, then the generic IsOn3D will not perform accurately.
The non-generic version of IsOn3D (which has a Text argument) can perform Text-specific logic to accurately determine whether the mouse is over the Text object regardless of the HorizontalAlignment or VerticalAlignment.
This brings us to the third question - how can you pick which you are using? This all depends on how you call the method. The following code shows how to call each version:
The following code creates two Cameras. Both cameras view a Sprite. If the cursor is over the Sprite on either Camera then it turns purple.
Add the following using statements:
Add the following at class scope:
Add the following to Initialize after initializing FlatRedBall:
Add the following to Update:
At the time of this writing there is no method to simply return all of the objects that the Mouse is over - instead you will have to manually loop through all objects to test whether the mouse is over the object. This means there are a few things to consider:
Performance may suffer if you have a lot of objects in your scene. If you are suffering from performance issues you may need to perform some type of higher-level partitioning to reduce calls to this method.
You will need to manually loop through objects and maintain a list of objects which you are over if you are interested in performing multiple-selection.
Some games benefit from keeping the mouse within the screen bounds. The two common scenarios for keeping the mouse within the screen bounds are:
A first person shooter uses the mouse to move around. The mouse should be invisible and not move outside of the window when the window has focus.
Real time strategy games often implement "edge scrolling" (scrolling the camera when the mouse reaches the edge of the screen).
If the mouse is invisible then the easiest way to keep the mouse in screen is to continually reset its position every frame:
The mouse can be bound to the window as shown in the following code:
Code obtained from http://xboxforums.create.msdn.com/forums/p/3553/18372.aspx