我有一款游戏,初始化为1920x1080。所有精灵,矢量等都特别正确放置,以匹配1920x1080类型。
我有一个enum
,说明游戏被告知使用什么res。 1920x1080将成为标准。
有没有办法,比方说,分辨率为1280x960,就像这样:
有点像,在绘制事件之前,将屏幕捕获到Texture2D
,并正确缩放显示,以适应游戏窗口。
答案 0 :(得分: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);
}
}
用法:
/// <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);
}
希望这个示例代码很有帮助。
注意:按照Pinckerman提出的方式进行操作并不是一种错误的方式,但我会相信除了显而易见的(最初更多的代码,但从长远来看更少),Pinckerman建议的也可能采取提高性能。这只是一种预感,它仅仅基于GPU可能在与屏幕放置相关的计算方面比CPU更有效。
但不要把我挂在上面。
@Edit:
获取与屏幕上对象相关的鼠标坐标:
public Vector2 GetMouseCoords()
{
var screenCoords = Mouse.GetPosition(); // Or whatever it's called.
var sceneCoords = screenCoords / Resolution.ScreenScale;
return sceneCoords;
}
答案 1 :(得分:4)
我认为您必须手动修改您需要的每个Vector2
或Rectangle
,使其与您的分辨率相关,或者(如果可以)使用基于Window.ClientBounds.Width
的变量或Window.ClientBounds.Height
,正如 davidsbro 所写
像这样:
Vector2 largeResolution = new Vector2(1920, 1080);
Vector2 smallResolution = new Vector2(1280, 960);
// you should have already set your currentResolution previously
Vector2 screenRatio = currentResolution / largeResolution;
现在你的初始化成为:
Vector2 position = new Vector2(200, 400) * screenRatio;
Rectangle imageRect = new Rectangle((int)(100 * screenRatio.X), (int)(200 * screenRatio.Y), ... );
通过这种方式,您只需要添加该产品,因此如果您当前的分辨率很大,那么您的变量仍然是相同的,否则如果它是小的,那么每个变量都将被缩放。