This is my Transform. I got it from an example of a simple 2D camera.
public Matrix Transform(GraphicsDevice graphicsDevice)
{
float ViewportWidth = graphicsDevice.Viewport.Width;
float ViewportHeight = graphicsDevice.Viewport.Height;
matrixTransform =
Matrix.CreateTranslation(new Vector3(-cameraPosition.X, -cameraPosition.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
Matrix.CreateTranslation(
new Vector3(Viewpor开发者_C百科tWidth * 0.5f, ViewportHeight * 0.5f, 0));
return matrixTransform;
}
If I understand it correctly, it allows for a roll(rotation), sprite scale change on zoom, and translation between world and camera for simple up, down, left, right controls. However, it does not alter the Z depth.
But what I need is for the game world to zoom, not just the sprites drawn. And I assume in order to do this I need to change the Z distance between the camera and the world matrix.
I am VERY NEW to programming and have only a simple understanding of matrix in general. I have even less understanding as to how XNA uses them in the draw method. And so far I feel like pulling my hair out from a fruitless search for answers... I just need the world coordinates to scale on zoom, so that before my mouse at a pre-zoom X.60 Y.60 will be at X.600 Y.600 post-zoom (ie: zoom level 0.1). But my mouse has not moved, only the world got bigger in view (or shrank).
I know this question is old, but this is in case anyone comes across this problem and can't find a solution. @RogueDeus was trying to convert scaled input coordinates when he was zooming in or out with his camera. In order to scale the mouse, all you need is to get the inverse matrix of the scale.
So if his scale matrix was created as this:
Matrix.CreateScale(zoom, zoom, 0);
The mouse coordinates should be inverse scaled and shifted by the necessary translation:
float ViewportWidth = graphicsDevice.Viewport.Width;
float ViewportHeight = graphicsDevice.Viewport.Height;
Matrix scale = Matrix.CreateScale(zoom, zoom, 0);
Matrix inputScalar = Matrix.Invert(scale);
...
public MouseState transformMouse(MouseState mouse)
{
/// Shifts the position to 0-relative
Vector2 newPosition = new Vector2(mouse.X - ViewportWidth,
mouse.Y - ViewportHeight);
/// Scales the input to a proper size
newPosition = Vector2.Transform(newPosition, InputScalar);
return new MouseState((int)newPosition.X, (int)newPosition.Y,
mouse.ScrollWheelValue, mouse.LeftButton,
mouse.MiddleButton, mouse.RightButton,
mouse.XButton1, mouse.XButton2);
}
You are using 2D coordinates, therefore the Z coordinate is of absolutely no importance. In fact, the scale matrix you are using ( Matrix.CreateScale(new Vector3(Zoom, Zoom, 0))
) multiply the Z coordinate by 0, effectively setting it to 0.
As this scale matrix is in the view matrix, it will scale the entire world. I am not sure to really understand your problem. Could you try to explain it a litle more, please?
I seem to have figured out how to get the coordinates to scale...
I was assuming that the current mouse status would reflect the world matrix its clicked on, but apparently it never actually does this. It is always linked to the view matrix. (The screen itself) and that value needs to scale along with the world matrix (in the transform).
So as the transform is effected by Zoom in the Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) so too does the mouseState X & Y coordinates need to be scaled by it to virtually mirror the world matrix.
//Offsets any cam location by a zoom scaled window bounds
Vector2 CamCenterOffset
{
get { return new Vector2((game.Window.ClientBounds.Height / Zoom)
* 0.5f, (game.Window.ClientBounds.Width / Zoom) * 0.5f);
}
}
//Scales the mouse.X and mouse.Y by the same Zoom as everything.
Vector2 MouseCursorInWorld
{
get
{
currMouseState = Mouse.GetState();
return cameraPosition + new Vector2(currMouseState.X / Zoom,
currMouseState.Y / Zoom);
}
}
精彩评论