跟随雪碧的XNA 2D照相机引擎

在XNA游戏中创build视差效果的最佳方式是什么? 我希望相机跟随我的精灵,因为它移动到世界各地,这样我就可以build立像缩放,平移,摇晃和其他效果的效果。 任何人都有一个如何完成这个例子,最好在一个GameComponent?

所以我想出了使用上面的教程的组合,并创build了下面的类。 它朝你的目标补充,并遵循它的周围。 试试看。

public interface IFocusable { Vector2 Position { get; } } public interface ICamera2D { /// <summary> /// Gets or sets the position of the camera /// </summary> /// <value>The position.</value> Vector2 Position { get; set; } /// <summary> /// Gets or sets the move speed of the camera. /// The camera will tween to its destination. /// </summary> /// <value>The move speed.</value> float MoveSpeed { get; set; } /// <summary> /// Gets or sets the rotation of the camera. /// </summary> /// <value>The rotation.</value> float Rotation { get; set; } /// <summary> /// Gets the origin of the viewport (accounts for Scale) /// </summary> /// <value>The origin.</value> Vector2 Origin { get; } /// <summary> /// Gets or sets the scale of the Camera /// </summary> /// <value>The scale.</value> float Scale { get; set; } /// <summary> /// Gets the screen center (does not account for Scale) /// </summary> /// <value>The screen center.</value> Vector2 ScreenCenter { get; } /// <summary> /// Gets the transform that can be applied to /// the SpriteBatch Class. /// </summary> /// <see cref="SpriteBatch"/> /// <value>The transform.</value> Matrix Transform { get; } /// <summary> /// Gets or sets the focus of the Camera. /// </summary> /// <seealso cref="IFocusable"/> /// <value>The focus.</value> IFocusable Focus { get; set; } /// <summary> /// Determines whether the target is in view given the specified position. /// This can be used to increase performance by not drawing objects /// directly in the viewport /// </summary> /// <param name="position">The position.</param> /// <param name="texture">The texture.</param> /// <returns> /// <c>true</c> if the target is in view at the specified position; otherwise, <c>false</c>. /// </returns> bool IsInView(Vector2 position, Texture2D texture); } public class Camera2D : GameComponent, ICamera2D { private Vector2 _position; protected float _viewportHeight; protected float _viewportWidth; public Camera2D(Game game) : base(game) {} #region Properties public Vector2 Position { get { return _position; } set { _position = value; } } public float Rotation { get; set; } public Vector2 Origin { get; set; } public float Scale { get; set; } public Vector2 ScreenCenter { get; protected set; } public Matrix Transform { get; set; } public IFocusable Focus { get; set; } public float MoveSpeed { get; set; } #endregion /// <summary> /// Called when the GameComponent needs to be initialized. /// </summary> public override void Initialize() { _viewportWidth = Game.GraphicsDevice.Viewport.Width; _viewportHeight = Game.GraphicsDevice.Viewport.Height; ScreenCenter = new Vector2(_viewportWidth/2, _viewportHeight/2); Scale = 1; MoveSpeed = 1.25f; base.Initialize(); } public override void Update(GameTime gameTime) { // Create the Transform used by any // spritebatch process Transform = Matrix.Identity* Matrix.CreateTranslation(-Position.X, -Position.Y, 0)* Matrix.CreateRotationZ(Rotation)* Matrix.CreateTranslation(Origin.X, Origin.Y, 0)* Matrix.CreateScale(new Vector3(Scale, Scale, Scale)); Origin = ScreenCenter / Scale; // Move the Camera to the position that it needs to go var delta = (float) gameTime.ElapsedGameTime.TotalSeconds; _position.X += (Focus.Position.X - Position.X) * MoveSpeed * delta; _position.Y += (Focus.Position.Y - Position.Y) * MoveSpeed * delta; base.Update(gameTime); } /// <summary> /// Determines whether the target is in view given the specified position. /// This can be used to increase performance by not drawing objects /// directly in the viewport /// </summary> /// <param name="position">The position.</param> /// <param name="texture">The texture.</param> /// <returns> /// <c>true</c> if [is in view] [the specified position]; otherwise, <c>false</c>. /// </returns> public bool IsInView(Vector2 position, Texture2D texture) { // If the object is not within the horizontal bounds of the screen if ( (position.X + texture.Width) < (Position.X - Origin.X) || (position.X) > (Position.X + Origin.X) ) return false; // If the object is not within the vertical bounds of the screen if ((position.Y + texture.Height) < (Position.Y - Origin.Y) || (position.Y) > (Position.Y + Origin.Y)) return false; // In View return true; } } 

这里是你如何使用它与SpriteBatch

 spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.FrontToBack, SaveStateMode.SaveState, Camera.Transform); spriteBatch.Draw(_heliTexture, _heliPosition, heliSourceRectangle, Color.White, 0.0f, new Vector2(0,0), 0.5f, SpriteEffects.FlipHorizontally, 0.0f); spriteBatch.End(); 

让我知道这是否帮助你,并感谢StackOverflow和社区。 W00t!

我知道这是一个古老的问题,但我有同一个,我发现这个伟大的Monogame相机库,所以我想我应该分享…

https://github.com/aloisdeniel/Comora

这是很容易安装,并跟随精灵,你只需要添加

this.camera.Position =你的精灵的位置;