SFML C++ Почему позиция текста ниже, чем предполагалось?

Вопрос или проблема

И точка, и текст расположены на координатах 100, 100, но текст по оси y находится ниже точки.

вставьте описание изображения здесь

вставьте описание изображения здесь

Расстояние варьируется в зависимости от шрифтов.

Стандартный масштаб и начало координат.

getLocalBounds указывает правильный размер.

`int main()
{
sf::RenderWindow window(sf::VideoMode(800U, 600U), “Заголовок”, sf::Style::Close);

sf::RectangleShape bot(sf::Vector2f(1.0f, 1.0f));

sf::Text text;

sf::Font font;

font.loadFromFile("Data/Textures/Font/Retron2000.ttf");

bot.setFillColor(sf::Color::Black);
bot.setPosition(100.0f, 100.0f);

text.setFont(font);
text.setString("Привет");
text.setPosition(100.0f, 100.0f);

text.setFillColor(sf::Color::Black);

while (window.isOpen())
{
    window.clear(sf::Color::White);

    window.draw(bot);
    window.draw(text);

    window.display();

    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            window.close();
    }
}

}`

На самом деле, позиция текста обычно выравнивается по основанию, а не по верхнему левому углу ограничивающей рамки символа.

Вот возможное решение, очищенное и задокументированное с помощью ИИ:

#include <SFML/Graphics.hpp>

int main() {
    sf::RenderWindow window(sf::VideoMode(800U, 600U), "Заголовок", sf::Style::Close);

    // Создаем прямоугольник 1x1 (по сути, точка)
    sf::RectangleShape bot(sf::Vector2f(1.0f, 1.0f));
    bot.setFillColor(sf::Color::Black);
    bot.setPosition(100.0f, 100.0f); // Задаем позицию точки

    // Загружаем шрифт и создаем текст
    sf::Text text;
    sf::Font font;
    if (!font.loadFromFile("Data/Textures/Font/Retron2000.ttf")) {
        return -1; // Если загрузка шрифта не удалась, выходим из программы
    }

    text.setFont(font);
    text.setString("Привет");
    text.setFillColor(sf::Color::Black);

    // Корректируем позицию текста, чтобы она совпадала с верхним левым углом ограничивающей рамки
    sf::FloatRect textBounds = text.getLocalBounds();
    text.setPosition(100.0f, 100.0f - textBounds.top);

    // Основной цикл
    while (window.isOpen()) {
        window.clear(sf::Color::White);

        // Рисуем точку и текст
        window.draw(bot);
        window.draw(text);

        window.display();

        // Обработка событий
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }
    }

    return 0;
}

Надеюсь, это сработает.

Ответ или решение

Проблема, с которой вы столкнулись, связана с тем, как SFML обрабатывает позиционирование текста. При установке позиции текста в SFML координаты относятся к базовой линии текста, а не к верхнему левому углу ограничивающего прямоугольника текста. Это означает, что даже если вы устанавливаете позицию текста в (100, 100), текст фактически начинается ниже этой точки, так как базовая линия текста находится выше.

Вот подробный анализ и решение вашей проблемы:

  1. Понимание расположения текста: в SFML координаты текста устанавливаются относительно его базовой линии. Это приводит к тому, что текст может быть визуально смещен от ожидаемой позиции. Ваша точка (100, 100) может совпадать с базовой линией текста, что и приводит к визуальному смещению.

  2. Коррекция позиции текста: Чтобы выровнять текст так, чтобы его верхний левый угол был на заданной позиции, необходимо сдвинуть его немного вверх. Для этого мы можем воспользоваться методом getLocalBounds(), чтобы получить размер текста и скорректировать его положение.

Вот исправленный и окончательный код с комментариями:

#include <SFML/Graphics.hpp>

int main() {
    // Создаем окно
    sf::RenderWindow window(sf::VideoMode(800U, 600U), "Title", sf::Style::Close);

    // Создаем точку (1x1 прямоугольник)
    sf::RectangleShape bot(sf::Vector2f(1.0f, 1.0f));
    bot.setFillColor(sf::Color::Black);
    bot.setPosition(100.0f, 100.0f); // Устанавливаем позицию точки

    // Загружаем шрифт и создаем текст
    sf::Text text;
    sf::Font font;
    if (!font.loadFromFile("Data/Textures/Font/Retron2000.ttf")) {
        return -1; // Если не удалось загрузить шрифт, выходим из программы
    }

    // Настраиваем текст
    text.setFont(font);
    text.setString("Hello");
    text.setFillColor(sf::Color::Black);

    // Корректируем позицию текста
    sf::FloatRect textBounds = text.getLocalBounds();
    text.setPosition(100.0f, 100.0f - textBounds.top);

    // Основной цикл программы
    while (window.isOpen()) {
        window.clear(sf::Color::White);

        // Рисуем точку и текст
        window.draw(bot);
        window.draw(text);

        window.display();

        // Обработка событий
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed)
                window.close();
        }
    }

    return 0;
}

Объяснение кода:

  • Мы загружаем шрифт и создаем текстовое сообщение.
  • Используем getLocalBounds(), чтобы получить размеры текста. Это позволяет нам установить текст на желаемую позицию (100, 100) таким образом, чтобы верхний левый угол текста был выставлен на эти координаты, а не его базовая линия.
  • В основной игровой цикл мы очищаем окно, рисуем точку и текст, а затем отображаем обновленный кадр.

Таким образом, приведенные изменения обеспечат правильное визуальное выравнивание текста относительно точки, как вы и ожидали.

Оцените материал
Добавить комментарий

Капча загружается...