使用 BmFont (MonoGame) 时居中文本
Center text when using BmFont (MonoGame)
有没有办法在使用 BmFont 绘图时使文本居中?我正在使用此处的代码:
我所做的唯一代码更改是我向 DrawText
添加了一个 _TextWidth
int,它使用 DX - X
获取文本长度,然后使用函数 GetTextLength
来return 它到按钮 class,然后它使用 ((button width - text width) / 2)
获取文本的起点,并将其居中。但是,似乎存在一些问题,文本不会使用自己的文本宽度居中,而是使用下一个按钮的文本宽度。返回文本宽度很好,但由于某些原因,当它在屏幕上绘制时,它总是错误的值。
Added/changed代码:
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
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。我认为您的代码只是有一个错误,因为它看起来像是打算做 MonoGame.Extended 无论如何都会做的事情。
据我所知,您的代码在 DrawText
方法中计算文本的宽度,并在 GetTextLength
方法中 return 计算它。这种方法的问题在于,如果您在 DrawText
之前调用 GetTextLength
,您将得到错误的值。
我假设你正在做这样的事情:
Dim y = buttonPos.Y
Dim x = buttonPos.X - buttonWidth / 2F - GetTextLength() / 2F
DrawText(_spriteBatch, x, y, text)
不幸的是,这 不会 起作用,因为 GetTextLength
在 之前不会 return 正确的值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
有没有办法在使用 BmFont 绘图时使文本居中?我正在使用此处的代码:
我所做的唯一代码更改是我向 DrawText
添加了一个 _TextWidth
int,它使用 DX - X
获取文本长度,然后使用函数 GetTextLength
来return 它到按钮 class,然后它使用 ((button width - text width) / 2)
获取文本的起点,并将其居中。但是,似乎存在一些问题,文本不会使用自己的文本宽度居中,而是使用下一个按钮的文本宽度。返回文本宽度很好,但由于某些原因,当它在屏幕上绘制时,它总是错误的值。
Added/changed代码:
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
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。我认为您的代码只是有一个错误,因为它看起来像是打算做 MonoGame.Extended 无论如何都会做的事情。
据我所知,您的代码在 DrawText
方法中计算文本的宽度,并在 GetTextLength
方法中 return 计算它。这种方法的问题在于,如果您在 DrawText
之前调用 GetTextLength
,您将得到错误的值。
我假设你正在做这样的事情:
Dim y = buttonPos.Y
Dim x = buttonPos.X - buttonWidth / 2F - GetTextLength() / 2F
DrawText(_spriteBatch, x, y, text)
不幸的是,这 不会 起作用,因为 GetTextLength
在 之前不会 return 正确的值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