20

我在 Ubuntu 12.10 上使用 SFML 2.0 库,使用

sudo apt-get install libsfml-dev

得到他们。现在我试图让一个 sf::Text 居中在屏幕上。为此,我将文本的原点(用于进行诸如设置位置、旋转等变换的位置)设置为 sf::Text 的边界框的中心,然后将位置设置为屏幕中心,如下所示:

//declare text
sf::Font font;
sf::Text text;
font.loadFromFile("helvetica.ttf");
text.setFont(font);
text.setString("RANDOMTEXT");
text.setCharacterSize(100);
text.setColor(sf::Color::White);
text.setStyle(sf::Text::Regular);

//center text
sf::FloatRect textRect = text.getLocalBounds();
text.setOrigin(textRect.width/2,textRect.height/2);
text.setPosition(sf::Vector2f(SCRWIDTH/2.0f,SCRHEIGHT/2.0f));

这不起作用,文本偏离了一定程度,例如 x 轴上的 3 和 y 轴上的 25。奇怪的是,如果您设置 sf::RectangleShape 来表示文本的边界框,那么该矩形将居中并正确调整大小以适合文本。但随后文本被从该框中绘制出来,并带有前面提到的偏移量。

在这张图片中,我标记了屏幕的中心,在文本边界框和 sf::Text 的位置绘制了一个 sf::RectangleShape。

http://i.imgur.com/4jzMouj.png

该图像是由以下代码生成的:

const int SCRWIDTH = 800; 
const int SCRHEIGHT = 600;

int main() {
sf::RenderWindow window;
window.create(sf::VideoMode(SCRWIDTH,SCRHEIGHT), "MYGAME" ,sf::Style::Default);
window.setMouseCursorVisible(false);
window.setVerticalSyncEnabled(true);

sf::Font font;
sf::Text text;
font.loadFromFile("helvetica.ttf");
text.setFont(font);
text.setString("RANDOMTEXT");
text.setCharacterSize(100);
text.setColor(sf::Color::White);
text.setStyle(sf::Text::Regular);

sf::FloatRect textRect = text.getLocalBounds();

text.setOrigin(textRect.width/2,textRect.height/2);
text.setPosition(sf::Vector2f(SCRWIDTH/2.0f,SCRHEIGHT/2.0f));

sf::RectangleShape rect(sf::Vector2f(textRect.width,textRect.height));
rect.setFillColor(sf::Color::Blue);
rect.setOrigin(rect.getSize().x/2,rect.getSize().y/2);
rect.setPosition(text.getPosition());

sf::RectangleShape RectW;
RectW.setSize(sf::Vector2f(SCRWIDTH, 0.0));
RectW.setOutlineColor(sf::Color::Red);
RectW.setOutlineThickness(1);
RectW.setPosition(0, SCRHEIGHT / 2);
sf::RectangleShape RectH;
RectH.setSize(sf::Vector2f(0.0, SCRHEIGHT));
RectH.setOutlineColor(sf::Color::Red);
RectH.setOutlineThickness(1);
RectH.setPosition(SCRWIDTH / 2, 0);

while(window.isOpen()) {
    window.clear();
    window.draw(rect);
    window.draw(text);
    window.draw(RectW);
    window.draw(RectH);
    window.display();
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
        window.close();
    }
}
return 1;
}

我怎样才能让它居中并在它的边界框内,因为它应该是?

4

3 回答 3

39

sf::Text::getLocalBounds()top和字段具有非零值left,因此在原点居中时不能忽略它们。

试试这个:

//center text
sf::FloatRect textRect = text.getLocalBounds();
text.setOrigin(textRect.left + textRect.width/2.0f,
               textRect.top  + textRect.height/2.0f);
text.setPosition(sf::Vector2f(SCRWIDTH/2.0f,SCRHEIGHT/2.0f));
于 2013-03-06T17:17:37.657 回答
5

我认为这是 SFML 文本渲染的一个已知问题。前往他们的问题跟踪器并查看此问题

您也可以在他们的开发论坛上提问。他们的开发人员总是非常友好和乐于助人。

于 2013-01-29T20:05:19.723 回答
0

除了Emile 的 answertextRect.height之外,您还应该使用maxHeight以下代码中的,而不是 using :

for (size_t characterIndex = 0; characterIndex < text.size(); ++characterIndex)
{
  currentHeight = font->getGlyph(text[characterIndex], 12, false).bounds.height;
  if (currentHeight > maxHeight)
  {
    maxHeight = currentHeight;
  }
}

这里的解释:

这是因为第一行在最高字符的高度上垂直对齐——即使它不在您的字符串中。这是为了保持字符串顶部稳定,即使您在第一行添加更高的字符。

确切的计算不是直截了当的:您必须遍历第一行的所有字符,计算最大字符大小,从 sf::Text 的 CharacterSize 中减去它,然后从高度减去结果边界矩形。


另一个非常重要的注意事项:如果在非整数位置绘制文本,可能会破坏文本的外观。这似乎也包括原点......(所以将您的原点+位置四舍五入到最接近的整数!)

于 2021-01-14T09:24:49.583 回答