На самом деле существует очень простое решение. Как отметил Пинкерманн, вам нужно знать соотношение сторон (коэффициент экрана), но вы будете использовать его в методе SpriteBatch.Begin, где вы пройдете масштаб Vector2 через Matrix.CreateScale (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);
}
Надежда этот пример кода является полезным.
ПРИМЕЧАНИЕ: Выполнение этого способа, предложенного Пинкерманом, не является неправильным способом, однако я убежден, что помимо очевидного (изначально большего количества кода, но в конечном итоге меньше), то, что предложил Пинкерман, также может занимать больше производительности. Это только догадка, и это просто основано на том, что GPU, вероятно, более эффективен в расчетах, связанных с размещением экрана, чем у CPU.
Но не вешайте меня на нем.
@Edit:
Чтобы получить координаты мыши по отношению к объектам на экране:
public Vector2 GetMouseCoords()
{
var screenCoords = Mouse.GetPosition(); // Or whatever it's called.
var sceneCoords = screenCoords/Resolution.ScreenScale;
return sceneCoords;
}
Если вы держите BackBuffer в этой резолюции и порт только отображается вид на более низкий, Арен» t вы вроде бы тратите много времени на GPU, потенциально отставая от игры, если машина пользователя не может запустить ее в полном HD? – Renan
У вас могут быть переменные, основанные на разрешении, которое использует ваш код для рисования и масштабирования спрайтов. Вместо чего-то вроде 'Rectangle Destination = new Rectangle (0,0,1920/2,1080/2)' у вас может быть 'Rectangle Destination = новый Rectangle (0,0, width/2, height/2)', где ' width' и 'height' являются общедоступными переменными, которые равны разрешению экрана. – davidsbro