当前位置:  开发笔记 > 编程语言 > 正文

遵循精灵的XNA 2D相机引擎

如何解决《遵循精灵的XNA2D相机引擎》经验,为你挑选了2个好方法。

在XNA游戏中创建视差效果的最佳方法是什么?我希望相机能够跟踪我的精灵,因为它在世界各地移动,这样我就可以构建缩放,平移,摇动和其他效果等效果.任何人都有一个很好的例子说明如何做到这一点,最好是在GameComponent中?



1> Khalid Abuha..:

所以我使用上面的教程的组合想出来,并创建了下面的类.它向你的目标补间并跟随它.试试看.

public interface IFocusable
{
    Vector2 Position { get; }
}

public interface ICamera2D
{
    /// 
    /// Gets or sets the position of the camera
    /// 
    /// The position.
    Vector2 Position { get; set; }

    /// 
    /// Gets or sets the move speed of the camera.
    /// The camera will tween to its destination.
    /// 
    /// The move speed.
    float MoveSpeed { get; set; }

    /// 
    /// Gets or sets the rotation of the camera.
    /// 
    /// The rotation.
    float Rotation { get; set; }

    /// 
    /// Gets the origin of the viewport (accounts for Scale)
    ///         
    /// The origin.
    Vector2 Origin { get; }

    /// 
    /// Gets or sets the scale of the Camera
    /// 
    /// The scale.
    float Scale { get; set; }

    /// 
    /// Gets the screen center (does not account for Scale)
    /// 
    /// The screen center.
    Vector2 ScreenCenter { get; }

    /// 
    /// Gets the transform that can be applied to 
    /// the SpriteBatch Class.
    /// 
    /// 
    /// The transform.
    Matrix Transform { get; }

    /// 
    /// Gets or sets the focus of the Camera.
    /// 
    /// 
    /// The focus.
    IFocusable Focus { get; set; }

    /// 
    /// 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
    /// 
    /// The position.
    /// The texture.
    /// 
    ///     true if the target is in view at the specified position; otherwise, false.
    /// 
    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

    /// 
    /// Called when the GameComponent needs to be initialized. 
    /// 
    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);
    }

    /// 
    /// 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
    /// 
    /// The position.
    /// The texture.
    /// 
    ///     true if [is in view] [the specified position]; otherwise, false.
    /// 
    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!


如果`IFocusable`Focus属性永远不应该是空的,那么如果ctor是:`Camera2D(游戏游戏,IFocusable聚焦)会更好
在Update方法中,您可能希望在计算转换矩阵之前计算Origin属性.否则,使用转换的原点与基于比例的最新计算原点之间将存在暂时差异.此外,您可以在不显式创建新Vector3的情况下执行Matrix.CreateScale(Scale).

2> David Brown..:

以下是在XNA中实现2D相机的一些教程:

    http://www.paradeofrain.com/?page_id=32

    http://gamecamp.no/blogs/tutorials/archive/2008/01/29/creating-a-simple-xna-camera-class.aspx

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有