2015-08-30 50 views
0

我决定将我的游戏从窗口模式移动到全屏模式,这是我面临的第一个问题。我正在寻找一种基于屏幕分辨率调整我的所有精灵的方法。我的背景现在位于(0, 0)坐标中,但我需要将它和所有精灵按某种固定纵横比(16:9首选)进行缩放。并将它们调整到背景被拉伸以充满屏幕的那部分。而不是更多,而不是更少。根据分辨率对屏幕上的所有精灵进行缩放

我已经看过一些在线教程,但我真的无法理解他们使用的概念。你能解释一下你会怎么做?我使用RenderTarget2D读取并将它传递给spriteBatch.Begin()调用,具有某种效果,但必须有更多的代码。

我并不是想支持分辨率更改选项,而是将精灵调整为当前分辨率。

+0

您可以使用'SpriteBatch.Draw(Texture2D,Rectangle,Color)'(或重载)中的矩形将任何纹理调整为任意大小。其余的是数学。 – Mephy

+0

你能提供一个例子吗?我假设你的意思是将'Texture2D.Width' /'。Height'的重载乘以某个东西,如果是的话,是什么? –

回答

1

听起来好像你在说resolution independence

总的想法是你的游戏使用虚拟分辨率和规模向上或向下,以适应屏幕的实际分辨率进行。

var scaleX = (float)ActualWidth/VirtualWidth; 
var scaleY = (float)ActualHeight/VirtualHeight; 
var matrix = Matrix.CreateScale(scaleX, scaleY, 1.0f); 

_spriteBatch.Begin(transformMatrix: matrix); 

例如,如果您的虚拟分辨率是800x480,则只需渲染所有相关的精灵。然后在渲染精灵批处理之前,创建一个转换矩阵以传入Begin调用。

您应该知道的另一件事是,您需要反转缩放鼠标/触摸输入坐标以在虚拟分辨率中处理它们。在Update方法,你可以扩展反向鼠标的位置是这样的:

var mouseState = Mouse.GetState(); // you're probably already doing this 
var mousePosition = new Vector2(mouseState.X, mouseState.Y); 
var scaledMousePosition = Vector2.Transform(mousePosition, Matrix.Invert(matrix)); 

然后你就可以在所有的地方使用的换算值您目前使用mouseState.XmouseState.Y

如果要实施letterboxing或者postboxing,它会变得更加复杂。如果您想知道这是如何工作的,请查看MonoGame.Extended中的视口适配器。

+0

因此'ActualWidth'和'ActualHeight'是'GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width'和'GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height'吧?然后我将'VirtualWidth'和'VirtualHeight'设置为'1366x768'。我假设'mousePosition'是一个'MouseState'变量? –

+0

我倾向于使用'GraphicsDevice.Viewport.Width'和'GraphicsDevice.Viewport.Height'。你读过[博客文章](http://dylanwilson.net/resolution-independence-in-monogame-with-viewport-adapters)吗?是的,虚拟分辨率是你的代码目前所期望的。如果您已经在1366x768窗口中定位精灵,请使用虚拟分辨率。 – craftworkgames

+0

我正在阅读此刻。另外,如果我把上面的代码放在'Draw()'中,如果是'Update()',我不能使用'scaledMousePosition'作为临时变量'matrix'吗? –

1

根据比例尺(sW, sH),您可以将尺寸为(W, H)的纹理放置在位置(X, Y)中。起初,比例是(1, 1),所以精灵将被放置在矩形(X, Y, W, H)中。

现在,假设初始分辨率为800x600,但您现在需要的分辨率为1440x900。如果800 -> sW = 11440 -> sW = 1440/800 = 1.8。类似的,我们的新sH是1.5。

这是说的是:如果某物原本应该在初始分辨率的X坐标500上,它现在在新分辨率上的500 * 1.8 = 900 X位置上。对于边缘来说这很明显:如果之前在X = 800上出现了某种情况,它现在在800 * 1.8 = 1440上,仍然在屏幕的边缘!

说了算,我们只需要乘。回到第一段,我们可以说一个矩形(X, Y, W, H)可以通过(sW, sH)(X * sW, Y * sH, W * sW, H * sH)的比例进行重新调整。

这当然是通过假设原始分辨率由(1, 1)缩放计算出来的,请不要忘记这一点!

+0

所以我打算编写像“1366/800 = 1.7075”和“768/600 = 1.28”这样的游戏分辨率。所以现在我为我的背景添加了'新的Rectangle(0 * 1.7075,0 * 1.28,800 * 1.7075,600 * 1.28)',当然''(0,0)'位置乘以后会返回0,所以我可以使用那里有'0'。那么输入呢?我无法对我的'Point'变量进行硬编码,如果它的距离为500像素,我检查鼠标是否点击,对不对? –

+0

@JohnyP。输入已经在新的坐标系中,应该对照转换为新坐标系的矩形进行检查。我建议静态更改大小(在Photoshop中调整纹理大小或其他),而不是在运行时。 – Mephy