XNA游戏的更改和缩放分辨率 [英] Change and scale resolution of XNA game

查看:178
本文介绍了XNA游戏的更改和缩放分辨率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个游戏,初始化为1920x1080运行.所有的精灵,向量等都应正确放置,以匹配1920x1080的流派.

I have a game, initialized to run at 1920x1080. All sprites, Vectors etc. are specificly properly placed, to match the 1920x1080 genre.

我有一个enum,说明了游戏要使用的分辨率. 1920x1080将是标准配置. 可以这样说,是否有一种分辨率为1280x960的方法:

I have an enum, stating what res, the game is told to use. 1920x1080 would be the standard. Is there a way to, let's say, have a resolution of 1280x960, in the way of this:

  • 游戏窗口为1280x960
  • 游戏分辨率(后缓冲)仍为1920x1080,但会缩小以适合窗口-1280x960.

有点像在绘制事件之前,将屏幕捕获到Texture2D,并按适当比例显示以适合游戏窗口.

A bit like, just before the draw event, capture the screen into a Texture2D, and display it properly scaled, to fit the game window.

推荐答案

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

Actually there is a very simple solution to this. As Pinckerman did point out, you need to know the aspect ratio (screen ratio), but you will be using it in the SpriteBatch.Begin method, where you will pass the Vector2 scale through a Matrix.CreateScale(Vector3 Here, where Z is 1), and use it as final argument in the SpriteBatch.Begin method.

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

Most other arguments in this case can be left Null.

基本上它是做什么的,它告诉spritebatch使用在位置和大小上都具有偏移量(比例)的所有内容进行绘制.这意味着,就我而言,无论我在屏幕上运行何种分辨率,在640x400上放置一些东西时,它仍然会从屏幕的死点开始.如果你问我,这很有用.

Basically what it does is, it tells the spritebatch to draw everything with an offset (the scale) applied to both position and size. This means that when, in my case, I place something on 640x400, no matter what resolution I run in the screen, it still starts off dead center of the screen. Quite useful if you ask me.

我当前项目中的示例:

/// <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);
    }
}

和用法:

    /// <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);
    }

希望此示例代码会有所帮助.

Hope this example code is helpful.

注意:按照Pinckerman的建议进行操作并不是错误的方法,但是我认为,除了显而易见的(最初更多的代码,但从长远来看更少的代码)之外,Pinckerman的建议也可能需要提高性能.这只是预感,只是基于GPU可能在计算与屏幕位置有关的计算方面比CPU更有效.

NOTE: Doing it the way Pinckerman suggested isn't a wrong way, however I'm led to believe that apart from the obvious (initially more code, but in the long run way less), what Pinckerman suggested may also take up more performance. This is only a hunch, and it's merely based on the GPU probably being more efficient in calculations related to screen placement than the CPU.

但是不要让我挂断电话.

But don't hang me up on it.

@

要获取与屏幕上的对象有关的鼠标坐标:

To get Mouse coordinates in relation to objects on the screen:

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

这篇关于XNA游戏的更改和缩放分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆