我在stackoverflow上问了这个问题,但认为这可能是一个更好的领域,要求更好的回答。
我的问题是,我正在尝试创建一个相机类,并使其相机遵循适当的RHS,但是Y轴似乎是倒转的,因为在屏幕上0从顶部开始。
这是我的Camera2D类:
class Camera2D { private Vector2 _position; private float _zoom; private float _rotation; private float _cameraSpeed; private Viewport _viewport; private Matrix _viewMatrix; private Matrix _viewMatrixIverse; public static float MinZoom = float.Epsilon; public static float MaxZoom = float.MaxValue; public Camera2D(Viewport viewport) { _viewMatrix = Matrix.Identity; _viewport = viewport; _cameraSpeed = 4.0f; _zoom = 1.0f; _rotation = 0.0f; _position = Vector2.Zero; } public void Move(Vector2 amount) { _position += amount; } public void Zoom(float amount) { _zoom += amount; _zoom = MathHelper.Clamp(_zoom, MaxZoom, MinZoom); UpdateViewTransform(); } public Vector2 Position { get { return _position; } set { _position = value; UpdateViewTransform(); } } public Matrix ViewMatrix { get { return _viewMatrix; } } private void UpdateViewTransform() { Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0)) * Matrix.CreateScale(new Vector3(1f, 1f, 1f)); _viewMatrix = Matrix.CreateRotationZ(_rotation) * Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) * Matrix.CreateTranslation(_position.X, _position.Y, 0.0f); _viewMatrix = proj * _viewMatrix; } }
我用以下方式使用SpriteBatchtesting它:
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Vector2 position = new Vector2(0, 0); // TODO: Add your drawing code here spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, camera.ViewMatrix); Texture2D circle = CreateCircle(100); spriteBatch.Draw(circle, position, Color.Red); spriteBatch.End(); base.Draw(gameTime); }
这是错误的:Matrix.CreateTranslation(_position.X,_position.Y,0.0f)
使它像这样:Matrix.CreateTranslation(-_ position.X,-_position.Y,0.0f)
说明:matrix指定如何改变世界,而不是如何改变相机。 这就是为什么你需要插入负值 。
我所有的Camera类都以此为基础开始:
public class Camera { private Vector2 position = Vector2.Zero; public float Left { get { return position.X; } set { position.X = value; } } public float Top { get { return position.Y; } set { position.Y = value; } } public Matrix TransformMatrix { get { return Matrix.CreateTranslation( new Vector3( -position, 0f ) ); } } public Camera( ) { } } // Camera
public class Camera { private Vector2 position = Vector2.Zero; public float Left { get { return position.X; } set { position.X = value; } } public float Top { get { return position.Y; } set { position.Y = value; } } public Matrix TransformMatrix { get { return Matrix.CreateTranslation( new Vector3( -position, 0f ) ); } } public Camera( ) { } } // Camera
我使用Matrix.CreateTranslation
在Matrix.CreateTranslation
函数调用中插入负值( Matrix.CreateTranslation
)来突出显示的相同方法,并且从来没有遇到过相机向错误方向移动的问题。 我的相机就像你的一样使用:
spriteBatch.Begin( SpriteSortMode.Deferred, BlendState.Additive, SamplerState.AnisotropicClamp, null, null, null, camera.TransformMatrix ); spriteBatch.Draw( someTexture, x, y, width, height, color ); spriteBatch.End();
所以在逻辑思维之后,我能够推断出适当的转变。 我将概述这里的步骤,以防止任何人想要真正的崩溃:
了解什么是相机变换或视图变换很重要。 视图变换通常是从坐标相对于相机到世界空间坐标所需要的。 视图变换的倒数将会相对于你的相机做一个世界坐标!
创建视图matrix
现在matrix的逆matrix将做世界坐标 – >查看坐标。
我也select将相机置于屏幕中央,所以我包含了一个预先附加的翻译。
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0)); _viewMatrix = Matrix.CreateRotationZ(moveComponent.Rotation) * Matrix.CreateTranslation(moveComponent.Position.X, -1 * moveComponent.Position.Y, 0.0f) * Matrix.CreateScale(new Vector3(zoomComponent.Zoom, zoomComponent.Zoom, 1.0f)); _viewMatrix = proj * Matrix.Invert(_viewMatrix);