Change and scale resolution of XNA game

Joh*_*son 2 c# xna resolution

我有一个游戏,初始化为1920x1080.所有精灵,矢量等都特别正确放置,以匹配1920x1080类型.

我有一个enum,说明什么res,游戏被告知使用.1920x1080将成为标准.有没有办法,比方说,分辨率为1280x960,就这样:

  • 游戏窗口是1280x960
  • 游戏分辨率(后备缓冲区)仍然是1920x1080,但缩小到适合窗口 - 1280x960.

有点像,在绘制事件之前,将屏幕捕获到a中Texture2D,并正确显示它以适合游戏窗口.

Fal*_*til 5

实际上有一个非常简单的解决方案.正如Pinckerman所指出的,你需要知道宽高比(屏幕比率),但是你将在SpriteBatch.Begin方法中使用它,在那里你将通过Matrix.CreateScale传递Vector2比例(Vector3这里,其中Z是1),并将其用作SpriteBatch.Begin方法中的最终参数.

在这种情况下,大多数其他参数可以保留为空.

基本上它的作用是,它告诉spritebatch绘制所有应用于位置和大小的偏移量(比例).这意味着,在我的情况下,当我在640x400上放置一些东西时,无论我在屏幕上运行什么分辨率,它仍然从屏幕的死点开始.如果你问我,非常有用.

我当前项目的示例:

/// <summary>
/// Resolution
/// </summary>
public static class Resolution
{
    private static Vector3 ScalingFactor;
    private static int _preferredBackBufferWidth;
    private static int _preferredBackBufferHeight;

    /// <summary>
    /// The virtual screen size. Default is 1280x800. See the non-existent documentation on how this works.
    /// </summary>
    public static Vector2 VirtualScreen = new Vector2(1280, 800);

    /// <summary>
    /// The screen scale
    /// </summary>
    public static Vector2 ScreenAspectRatio = new Vector2(1, 1);

    /// <summary>
    /// The scale used for beginning the SpriteBatch.
    /// </summary>
    public static Matrix Scale;

    /// <summary>
    /// The scale result of merging VirtualScreen with WindowScreen.
    /// </summary>
    public static Vector2 ScreenScale;

    /// <summary>
    /// Updates the specified graphics device to use the configured resolution.
    /// </summary>
    /// <param name="device">The device.</param>
    /// <exception cref="System.ArgumentNullException">device</exception>
    public static void Update(GraphicsDeviceManager device)
    {
        if (device == null) throw new ArgumentNullException("device");

        //Calculate ScalingFactor
        _preferredBackBufferWidth = device.PreferredBackBufferWidth;
        float widthScale = _preferredBackBufferWidth / VirtualScreen.X;

        _preferredBackBufferHeight = device.PreferredBackBufferHeight;
        float heightScale = _preferredBackBufferHeight / VirtualScreen.Y;

        ScreenScale = new Vector2(widthScale, heightScale);

        ScreenAspectRatio = new Vector2(widthScale / heightScale);
        ScalingFactor = new Vector3(widthScale, heightScale, 1);
        Scale = Matrix.CreateScale(ScalingFactor);
        device.ApplyChanges();
    }


    /// <summary>
    /// <para>Determines the draw scaling.</para>
    /// <para>Used to make the mouse scale correctly according to the virtual resolution,
    /// no matter the actual resolution.</para>
    /// <para>Example: 1920x1080 applied to 1280x800: new Vector2(1.5f, 1,35f)</para>
    /// </summary>
    /// <returns></returns>
    public static Vector2 DetermineDrawScaling()
    {
        var x = _preferredBackBufferWidth / VirtualScreen.X;
        var y = _preferredBackBufferHeight / VirtualScreen.Y;
        return new Vector2(x, y);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

    /// <summary>
    /// Draws the game objects to the screen. Calls Root.Draw.
    /// </summary>
    /// <param name="gameTime">The game time.</param>
    protected override void Draw(GameTime gameTime)
    {
        // TODO: Camera
        SpriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null, Resolution.Scale);
        Root.Draw(SpriteBatch, gameTime);
        SpriteBatch.End();

        base.Draw(gameTime);
    }
Run Code Online (Sandbox Code Playgroud)

希望这个示例代码很有帮助.

注意:按照Pinckerman提出的方式进行操作并不是一种错误的方式,但我会相信除了明显的(最初更多的代码,但从长远来看更少),Pinckerman建议的可能也会占用更多的性能.这只是一种预感,它仅仅基于GPU可能在与屏幕放置相关的计算方面比CPU更有效.

但是不要把我挂在上面.

@编辑:

要获得与屏幕上的对象相关的鼠标坐标:

public Vector2 GetMouseCoords()
{
    var screenCoords = Mouse.GetPosition(); // Or whatever it's called.
    var sceneCoords = screenCoords / Resolution.ScreenScale;
    return sceneCoords;
}
Run Code Online (Sandbox Code Playgroud)