使用 SFML 使文本在屏幕上居中
Centering text on the screen with SFML
我在 Ubuntu 12.10 上使用 SFML 2.0 库,使用
sudo apt-get install libsfml-dev
得到他们。现在我正在尝试在 sreen 中获取一个 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::RectangleShape,以及sf::Text。
https://i.stack.imgur.com/LvDJc.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;
}
如何让它居中并位于边界框内,因为它应该是?
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));
我认为这是SFML文本渲染的一个已知问题。前往他们的问题跟踪器并查看此问题。
您也可以在他们的开发论坛上提问。那里的开发人员总是非常友好和乐于助人。
除了 Emile 的答案之外,您应该使用以下代码中的maxHeight
,而不是使用 textRect.height
:
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 中减去此字符大小,然后从边界矩形的高度中减去结果。
另一个非常重要的注意事项:如果在非整数位置绘制文本,可能会破坏文本的外观。这似乎也包括起源...(所以把你的原点+位置四舍五入到最接近的整数!
- SFML纹理像播放器
- 如何使用AngelScript注册SFML Vector2运算符
- 如何修复sfml c++代码编译错误
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- SFML library: http request
- 落砂模拟碰撞检测C++和SFML
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 使用 SFML 和 C++ 将 Pixel 打印到屏幕上
- SFML 向下移动时如何围绕屏幕中心旋转?
- SFML 中的字体.信息不显示在屏幕上.显示的不是信息,而是点
- SFML 在屏幕上移动矩形时滞后/小卡顿
- SFML C 为什么在屏幕上没有绘制?(简单代码)
- SFML 将形状绘制到屏幕上的多个位置
- 用SFML在屏幕顶部(Windows)绘制
- SFML屏幕运动很慢
- C / SFML:使用两个递归调用在屏幕上打印凸形形状仅显示第一个递归调用中的形状,而不是第二个
- SFML 渲染窗口不会在初始屏幕中打开
- SFML window.clear()未清除屏幕
- SFML - 流体屏幕更新
- 使用 SFML 使文本在屏幕上居中