2016-03-15 4 views
1

Я создаю графический интерфейс для своей игры, и теперь я застрял в анимации. Мне нужно масштабировать шрифт, когда мышь нависает над ним и уменьшает его, когда это не так. Вот мой код:MonoGame - правильное масштабирование SpriteFont

// Update() 
if (!IsDisabled) 
{ 
    elapsedSecondsFast = (float)gameTime.ElapsedGameTime.TotalSeconds * 3; 
    if (Size.Contains(InputManager.MouseRect)) 
    { 
     scale += elapsedSecondsFast; 
     if (scale >= 1.05f) scale = 1.05f; 
    } 
    else 
    { 
     scale -= elapsedSecondsFast; 
     if (scale <= 1.0f) scale = 1.0f; 
    } 
} 
// Draw() 
if ((PrimaryFont != null) && (SecondaryFont != null) && (!string.IsNullOrEmpty(Text))) 
{ 
    if (IsHovered) TextOutliner.DrawBorderedText(spriteBatch, SecondaryFont, Text, new Vector2(TextRectangle.X, TextRectangle.Y), ForeColor, 0.0f, new Vector2((SecondaryFont.MeasureString(Text).X/2 * scale - SecondaryFont.MeasureString(Text).X/2), (SecondaryFont.MeasureString(Text).Y/2 * scale - SecondaryFont.MeasureString(Text).Y/2)), scale); 
    else TextOutliner.DrawBorderedText(spriteBatch, PrimaryFont, Text, new Vector2(TextRectangle.X, TextRectangle.Y), ForeColor, 0.0f, new Vector2(PrimaryFont.MeasureString(Text).X/2 * scale - PrimaryFont.MeasureString(Text).X/2, (PrimaryFont.MeasureString(Text).Y/2 * scale - PrimaryFont.MeasureString(Text).Y/2)), scale); 
} 

выше является GUIElement класс, который наследуется от моего Button класса. Позвольте мне объяснить мой код кратко:

  • PrimaryFont и SecondaryFont 2 SpriteFonts, которые используют один и тот же шрифт , но другой размер. Это дает мне масштабирование увеличения/уменьшения, которое мне нужно, не размывая мой PrimaryFont.
  • TextRectangle и Size - 2 разных прямоугольника. Так как у моей кнопки есть текстура и текст, я решил не нарисовать текст в файле текстуры, но у меня есть позиция над текстом над текстурой, чтобы «подделать» эффект. Таким образом, TextRectangle - это размер и расположение текста кнопки, а Size - размер и расположение текстуры кнопки. TextRectangle имеет center point в centerButton texture. До сих пор я использовал магические числа для достижения этого. В этом суть проблемы.
  • Вы можете увидеть мой origin, я передал его методу DrawBorderedText моего класса TextOutliner. Атрибуты находятся в том же порядке, что и звонок spriteBatch.DrawString(), только без SpriteEffects и layerDepth.

Проблема

Поскольку я масштабирование шрифта (origin = center я думаю) он больше не будет находиться в центре кнопки. И так как я использовал магические числа, чтобы расположить текст без масштабирования по центру текстуры кнопки, я не хочу, чтобы меня заставляли делать то же самое для масштабированного текста. Я ищу алгоритм, который всегда будет позиционировать текст в середине моей текстуры 270x72, независимо от того, масштабируется ли текст или нет, при сохранении анимации scale, показанной выше, для каждый экземпляр класса Button , Предпочтительно, чтобы точка начала координат находилась в центре.

Редактировать

Так что я должен сделать так:

if (IsHovered) TextOutliner.DrawBorderedText(spriteBatch, SecondaryFont, Text, new Vector2(TextRectangle.X, TextRectangle.Y), ForeColor, 0.0f, new Vector2((SecondaryFont.MeasureString(Text).X/2), (SecondaryFont.MeasureString(Text).Y/2)), scale); 
else TextOutliner.DrawBorderedText(spriteBatch, PrimaryFont, Text, new Vector2(TextRectangle.X, TextRectangle.Y), ForeColor, 0.0f, new Vector2(PrimaryFont.MeasureString(Text).X/2, (PrimaryFont.MeasureString(Text).Y/2)), scale); 

, а затем нарисовать текст кнопки на btn.Size.Width/2, btn.Size.Height/2, (int)MainGame.GameFontLarge.MeasureString("Play").X/2, (int)MainGame.GameFontLarge.MeasureString("Play").Y/2

+0

Я не думаю, что вам нужно масштабировать происхождение. Происхождение должно быть просто измерено размером/2 – LibertyLocked

+0

@LibertyLocked, что ломает позиции кнопок для меня. Также кажется, что анимация масштаба начинается с левого верхнего уровня, я хочу ее из центра. –

+0

Нарисуйте текст в центре/центре кнопки, затем сделайте исходное измерение измеренным/2. Он всегда масштабируется от источника. – LibertyLocked

ответ

2

Так что я в конце концов нашел алгоритм сам, и, наконец, отпала необходимость использования магических чисел для позиции текста. Вот моя техника:

TextOutliner.DrawBorderedText(spriteBatch, Font, Text, new Vector2(Size.X + ((Size.Width - Font.MeasureString(Text).X)/2), Size.Y + ((Size.Height - Font.MeasureString(Text).Y))/2), ForeColor, 0.0f, new Vector2((Font.MeasureString(Text).X/2 * scale - Font.MeasureString(Text).X/2), (Font.MeasureString(Text).Y/2 * scale - Font.MeasureString(Text).Y/2)), scale); 

Я не мог взять scale из уравнения origin как предложен @LibertyLocked, потому что шрифт был масштабирования из верхней левой точки после парения мыши, а не в центре, как я хочу, чтобы ,

+1

Один наконечник (лучшая читаемость и более высокая производительность): выполните измерение за один шаг до рисования и поместите эти значения внутри переменных. Нам будет намного легче отслеживать, что происходит. После этого вы должны попытаться извлечь это в метод расширения (например, «DrawStringCentered»), который принимает «SpriteFont» и «Rectangle». Если у вас есть такая необходимость, вы можете даже расширить этот метод, чтобы принять параметры горизонтального и вертикального выравнивания. – Groo

+0

Спасибо, я буду помнить об этом! –

Смежные вопросы