使用BmFont(MonoGame)

时间:2016-01-13 05:56:04

标签: vb.net xna monogame

使用BmFont绘图时是否有中心文字的方法?我正在使用此处的代码:Using a BMP image as font in Monogame

我做的唯一代码更改是我向_TextWidth添加了DrawText int,使用DX - X获取文本长度,然后使用函数GetTextLength将其返回到按钮类,然后使用((button width - text width) / 2)获取文本的起始点,使其居中。但是,似乎存在一些问题,文本并没有使用自己的文本宽度居中,而是使用下一个按钮的文本宽度。返回文本宽度很好,但由于某些原因,当它在屏幕上绘制时,它总是错误的值。

添加/更改了代码:

Public Sub DrawText(ByVal spritebatch As SpriteBatch, ByVal X As Integer, ByVal Y As Integer, ByVal Text As String)
    Dim DX As Integer = X
    Dim DY As Integer = Y
    For Each C As Char In Text
        Dim FC As New FontChar
        If _CharacterMap.TryGetValue(C, FC) Then
            Dim sourceRectangle = New Rectangle(FC.X, FC.Y, FC.Width, FC.Height)
            Dim position = New Vector2(DX + FC.XOffset, DY + FC.YOffset)
            spritebatch.Draw(_Texture, position, sourceRectangle, Color.White)
            DX += FC.XAdvance
        End If
    Next
    _TextWidth = DX - X
End Sub

Public Function GetTextLength() As Integer
    Return _TextWidth
End Function

屏幕截图:

Uncentered text, which could be centered if the right values were used for each button

1 个答案:

答案 0 :(得分:0)

MonoGame.Extended具有BMFont渲染器的实现,并对该旧教程进行了一些改进,包括SpriteBatch.DrawString扩展。

我还有关于如何设置它的my blog教程。但是,它没有处理文本的居中问题,所以我现在就讨论它。

如果您选择使用MonoGame.Extended,您应该能够获得如下的居中效果。

首先,像往常一样SpriteFont加载位图字体。请注意,为此,您需要使用MonoGame管道工具设置MonoGame.Extended。

_bitmapFont = Content.Load(Of BitmapFont)("my-font")

接下来,在您的Draw方法中,您可以使用GetStringRectangle来衡量文字的大小,然后计算正确的位置。这样的事情(对不起,如果我的VB.net有点生锈):

Dim text = "Start game"
Dim textRectangle = _bitmapFont.GetStringRectangle(text, Vector2.Zero)
Dim textOffset = buttonWidth / 2F - textRectangle.Width / 2F

_spriteBatch.DrawString(_bitmapFont, text, buttonPosition + textOffset, Color.White)

当然,您不必使用MonoGame.Extended即使您不想这样做也是如此。我认为你的代码只是有一个bug,因为看起来它的目的是做MonoGame.Extended所做的事情。

据我所知,您的代码正在计算DrawText方法中文本的​​宽度,并在GetTextLength方法中返回。这种方法的问题在于,如果您在 GetTextLength之前调用DrawText ,那么您将获得错误的值。

我假设你正在做这样的事情:

Dim y = buttonPos.Y
Dim x = buttonPos.X - buttonWidth / 2F - GetTextLength() / 2F

DrawText(_spriteBatch, x, y, text)

不幸的是,这会有效,因为GetTextLength DrawText运行之后才会返回正确的值。

当然,修复方法是实际计算文本长度,而不是在绘制操作期间将其存储在成员变量中。

Public Function GetTextLength(ByVal Text As String) As String
    Dim TextWidth As Integer
    For Each C As Char In Text
    Dim FC As New FontChar
    If _CharacterMap.TryGetValue(C, FC) Then
        TextWidth += FC.XAdvance
    End If
    Next
    GetTextLength = TextWidth
End Sub