Absolute and relative mouse movement
Usually when dealing with mouse input you want the data from the mouse in two forms, one is absolute that you might use to draw a cursor or know which part of the window/screen a user has clicked on, and the other is relative where you are only interested in how much the mouse has moved.
Currently, the MouseState only seems to report the mouse movement in the absolute form. This means anyone using the mouse to control, for example, a first person camera would find their movement limited by the size of their window/screen. I have tried playing around with the Mouse.IsCaptured property but it doesn't seem to make much difference, quite possibly because I don't know how to use it.
Am I correct in thinking that getting relative mouse input data is not possible with the Mouse/MouseState classes? This is not a big problem as mouse input is only supported on Windows and there are other methods for getting the mouse input data but I am curious to know.
Cheers,
Leaf.
[984 byte] By [
Leaf.] at [2007-12-25]
You can try hiding the mouse pointer and after you read each absolute mouse position, reset the mouse pointer back to the middle of the screen. That way each read is effectily a relative one.Yes it seemed like a hacky workaround to me too, but I'm assured that a lot of games do it this way.
(seems there is no way to set the mouse pointer position in XNA)
Otherwise you are stuck going back to DirectInput or writing your own wrapper of windows raw messages.
Not tried it but how about?
public void GraphicsDevice.SetCursorPosition (
int x,
int y,
bool updateImmediate
)
Well, I got it to work using that, but at nasty price.
Int32
middleX = this
.graphics.Game.Window.ClientWidth / 2;Int32 middleY = this
.graphics.Game.Window.ClientHeight / 2;
mouseInfo =
Mouse.GetState();if
(mouseInfo.X != middleX || mouseInfo.Y != middleY)
{
if
(mouseInfo.X < middleX || graphics.IsFullScreen == true
)
{
mouseX = mouseInfo.X - middleX;
}
else
{
mouseX = middleX - mouseInfo.X;
}
if
(mouseInfo.Y < middleY || graphics.IsFullScreen == true
)
{
mouseY = mouseInfo.Y - middleY;
}
else
{
mouseY = middleY - mouseInfo.Y;
}
}
if
(graphics.IsFullScreen == false
)
{
//this is because in windowed its doing absolute to screen!
mouseX += 128; //this happens to be the offset of my window on screen
mouseY += 141;}
//reset the cursor back to the middle of the screen
graphics.GraphicsDevice.SetCursorPosition(middleX, middleY, true
);This works in both full screen and windowed, but in windowed I had a problem.
I had to add in those constants as the offset from my screen to window. I cant find a poperty/method in XNA to get the window position, or the screen dimensions.
Any ideas?
You can grab your window handle and platform invoke out to the Win32 API and ask it (normally WinForms handles this, but of course we don't have WinForms anymore). Under Xbox you'll always be running fullscreen, so there's no need to do it there.
In full screen, SetCursorPosition seems to only affect where the cursor is drawn, but the MouseState parameters are unaffected. In windowed mode, SetCursorPosition does affect the MouseState parameters. I think this is a bug. SetCursorPosition should have the same side effects on the MouseState parameters no matter what the fullscreen state is.
As a side note, I can't even get a cursor to draw in windowed mode, but that's probably my fault.