Масштабирование спрайтов (не текстур) для целевого размера / устройства области просмотра в MonoGame

Когда вам нужно отобразить серию визуальных компонентов (спрайтов) в контексте игры, каждый из которых принимает буквальную высоту и ширину, которые должны быть относительно высоты и ширины области просмотра (не обязательно с соотношением сторон) целевого устройства:

  • Есть ли класс масштабирования, который поможет динамически подобрать коэффициент масштабирования на основе текущего размера области просмотра устройства?
  • Придется ли мне использовать собственный алгоритм масштабирования?
  • О каких-либо кроссплатформенных проблемах, о которых мне следует знать?

Это не вопрос, связанный с загрузкой ресурсов на основе целевого устройства, и не вопрос о том, как выполнить масштабирование спрайта (которое описано здесь: http://msdn.microsoft.com/en-us/library/bb194913.aspx), скорее вопрос о том, как определить масштаб спрайтов в зависимости от размера порта просмотра.


person holsee    schedule 08.02.2013    source источник
comment
Масштаб каких спрайтов, какого размера, по сравнению с каким размером области просмотра? Пример был бы отличным.   -  person user1306322    schedule 08.02.2013


Ответы (2)


Вы всегда можете создать собственную реализацию масштабирования.

Например, размеры целевого окна просмотра по умолчанию:

const int defaultWidth = 1280, defaultHeight = 720;

И ваши текущие размеры экрана 800×600, что дает вам (давайте использовать Vector2 вместо двух чисел с плавающей запятой):

int currentWidth  = GraphicsDevice.Viewport.Width,
    currentHeight = GraphicsDevice.Viewport.Height;

Vector2 scale = new Vector2(currentWidth  / defaultWidth,
                            currentHeight / defaultHeight);

Это дает вам {0.625; 0.83333}. Теперь вы можете использовать это в удобной SpriteBatch.Draw() перегрузке, который принимает переменную масштабирования Vector2:

public void Draw (
     Texture2D texture,
     Vector2 position,
     Nullable<Rectangle> sourceRectangle,
     Color color,
     float rotation,
     Vector2 origin,
     Vector2 scale,
     SpriteEffects effects,
     float layerDepth
)

В качестве альтернативы вы можете нарисовать все свои вещи в RenderTarget2D и скопировать полученное изображение оттуда в растянутую текстуру на главном экране, но это все равно потребует вышеуказанной перегрузки SpriteBatch.Draw(), хотя это может сэкономить ваше время, если у вас много вызовов отрисовки. .

person user1306322    schedule 08.02.2013
comment
Это наверняка правильный ответ, но для моих нужд он не соответствует тому, что масштабирование испортилось с обнаружением жестов касания (не упоминается в вопросе). Мой ответ очень просто решил мои проблемы, но я понимаю, что это может быть не самое чистое решение в будущем. Поэтому я отметил это как правильный ответ. - person holsee; 09.02.2013
comment
Привет, я использовал эти коды, не могли бы вы рассказать мне, как я могу масштабировать сенсорный ввод после этого .... - person uncle_scrooge; 01.10.2015
comment
@uncle_scrooge, если вы хотите получить ответ на другой вопрос, вы должны либо найти такой вопрос, либо задать его, а не оставлять комментарий. - person user1306322; 01.10.2015
comment
это не другой вопрос ... это полностью связано с этим. после масштабирования входные данные не будут работать ... вы это знаете ... - person uncle_scrooge; 01.10.2015
comment
в любом случае, вероятно, вы что-то сделали для сенсорного ввода ур ... кстати, я уже создал вопрос по этому поводу два дня назад .... Пожалуйста, ответьте, если хотите .. ниже ссылка .. - person uncle_scrooge; 01.10.2015
comment
Я вообще не использую сенсорный ввод. Мое кодирование XNA было ограничено только ПК, поэтому нет, я не знаю и не могу помочь вам с сенсорным вводом. Ваш вопрос может быть связан или не быть связанным, но это не тот же вопрос. В противном случае вы найдете здесь ответ. - person user1306322; 01.10.2015

Другой вариант создания шкалы - использовать:

var scaleMatrix = Matrix.CreateScale(
           (float)GraphicsDevice.Viewport.Width / View.Width,
           (float)GraphicsDevice.Viewport.Width / View.Width, 1f);

http://msdn.microsoft.com/en-gb/library/bb195692.aspx.

Но это не соответствовало моим потребностям, так как тогда мне пришлось бы свернуть свое собственное преобразование, чтобы сопоставить местоположение сенсорного ввода с «преобразованными» спрайтами (которые реагируют на сенсорный ввод пользователя, зная свое собственное положение и размер).

В итоге я применил процентный подход.

Я в основном получил высоту и ширину области просмотра ...

GraphicsDevice.Viewport.Width  
GraphicsDevice.Viewport.Height

... затем рассчитал высоту и ширину моих спрайтов (примечание: «как упоминалось в вопросе, они принимают буквальную высоту и ширину») на основе их относительного размера по отношению к экрану, используя проценты.

//I want the buttons height and width to be 20% of the viewport 
var x, y = GraphicsDevice.Viewport.Width * 0.2f; //20% of screen width
var btnsize = new Vector(x,y);
var button = new GameButton(btnsize);

Затем, когда у меня есть размер кнопки, я могу рассчитать положение на экране для визуализации кнопки на основе размера кнопки и доступного размера области просмотра, а не работать в относительном положении в процентах.

person holsee    schedule 09.02.2013