Как мне масштабировать графику игры?
Я делаю игру на C# и XNA 4.0. Это в значительной степени закончено, но теперь я хочу добавить настройки, чтобы игроки могли изменить размер окна, если они захотят. Текущая настройка выглядит следующим образом:
void Initialize()
{
//The window size is initally 800x480
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 480;
graphics.ApplyChanges();
}
void Update()
{
//If the player completes an action, the window size is changed
if (windowSizeChanged)
{
graphics.PreferredBackBufferWidth = 1024;
graphics.PreferredBackBufferHeight = 720;
graphics.ApplyChanges();
}
}
Используя этот код, вот как выглядит игра в определенных разрешениях:
800x480
1024x720
Как можно надеяться, вы можете видеть, что при изменении размера окна это не влияет на реальную графику игры. Спрайты и хитбоксы всех объектов остаются одинакового размера, поэтому вместо этого они заполняют небольшую рамку в углу экрана, а не во всем окне. Может кто-нибудь сказать мне, как я могу масштабировать спрайтов, чтобы они заполняли окно? Я предполагаю, что мне нужно будет использовать какую-то матрицу, но может ли кто-нибудь указать мне правильное направление?
Редактировать:
Вот код розыгрыша.
void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
spriteBatch.Begin();
//Background texture drawn at default window size
spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);
//Each object in the level (player, block, etc.) is drawn with a specific texture and a rectangle variable specifying the size and coordinates
//E.g. Each block is a size of 64x64 pixels and in this level they are placed at X-coordinates 0, 64, 128 and so on
//Each Y-coordinate for the blocks in this level is '480 - 64' (Window height minus block height)
foreach (/*Object in level*/)
{
spriteBatch.Draw(object.Texture, object.TextureSize, Color.White);
}
spriteBatch.End();
}
1 ответ
По умолчанию SpriteBatch предполагает, что ваше мировое пространство совпадает с пространством клиента, что соответствует размеру окна. Вы можете прочитать о SpriteBatch и различных местах в посте Эндрю Рассела.
Когда вы изменяете размер буфера, размер окна также изменяется, изменяя пространство мира вместе с ним (что вам не нужно). Чтобы этого не допустить, вы должны вставить матрицу преобразования между конвейером преобразования, чтобы сделать это исправление.
SpriteBatch.Begin
позволяет именно это в одной из своих перегрузок.
Существует множество способов приблизиться к масштабированию, но я предполагаю, что вы хотите масштабировать равномерно, то есть спрайты не растягиваются при изменении соотношения сторон по сравнению с исходным соотношением сторон. Следующий код отрегулирует масштабирование в зависимости от начальной высоты экрана.
...
const float initialScreenHeight = 480f;
Matrix transform = Matrix.CreateScale(GraphicsDevice.Viewport.Height / viewportHeightInWorldSpace);
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, transform);
...
Обратите внимание, что при изменении разрешения таким образом, что соотношение сторон изменяется по сравнению с исходным соотношением сторон, вы столкнетесь с такими проблемами, как рисование за пределами экрана (вправо) или не рисование у правого края экрана (получение аналогичного синего цвета). фон как сейчас).
Кроме того, вы не хотите вычислять эту матрицу масштабирования для каждого кадра в методе Draw, а только при изменении разрешения.