SFML Views setCenter vs rotation

*爱你&永不变心* 提交于 2020-01-04 06:30:46

问题


I have a view with same dimensions of original window (500,300)

I apply view.zoom(2) to leave the view at half the size.

Now the view is centered. I want to move the view to the upper left corner of the original window. So I put view.setCenter(500,300);

The view is now correctly positioned in the upper corner of the original window. But now I want to rotate the view, making the center of the view its own top left corner, ie (0,0): view.setRotation(5);

As you can see, the center of the axis of rotation should be 0.0 but not respected. The problem is that if I do view.setCenter (0,0), the whole view returns to the middle of the original window.

How to solve this?


回答1:


Instead of using view.setCenter(500,300); move it via view.move(x_offset, y_offset);. Then applying setCenter(...) won't redefine the center and it won't get reset.

I recommend consulting the API reference of View for further reading.

You might also be interested in void sf::View::setViewport(const FloatRect& viewport) or void sf::View::reset(const FloatRect& rectangle).




回答2:


This code, kindly provided by Geheim, solves the problem and also teaches a more practical approach to SFML.

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window({500, 300}, "SFML Views", sf::Style::Close);
    window.setFramerateLimit(120);
    bool useViewPort {true};        // change this to false to see the other version

    sf::View camera {{0, 0}, static_cast<sf::Vector2f>(window.getSize())};
    if (useViewPort)
    {
        camera.setViewport({-0.5f, -0.5f, 1, 1});
        camera.rotate(5);
    }
    else
        camera.setCenter(camera.getSize());

    camera.zoom(2);
    window.setView(camera);

    sf::RectangleShape background {camera.getSize()};
    sf::RectangleShape square {{50, 50}};
    square.setFillColor(sf::Color::Red);

    sf::RenderTexture texture;
    texture.create(window.getSize().x, window.getSize().y);

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

        window.clear();

        if (useViewPort)
        {
            window.draw(background);
            window.draw(square);
        }
        else
        {
            texture.clear();
            texture.draw(background);
            texture.draw(square);
            texture.display();

            sf::Sprite content {texture.getTexture()};
            content.rotate(-5);     // you have to rotate in the other disquareion here, do you know why?
            window.draw(content);
        }

        window.display();
    }

    return EXIT_SUCCESS;
}



回答3:


I'm glad you got the result you wanted by applying viewports using Geheim's code.

However, if you don't want to be using viewports to clip areas of the window and such, you can still rotate a view around a specific point other than its centre. You just need a little bit of mathematics...

Take the different between the target point (in the view's co-ordinate system) and the view's centre and rotate that point by the amount you wish to rotate the view and around the view's centre. Then, calculate the difference between those points (the target point and the rotated point). Once you have this difference, simply rotate the view (around its centre as normal) but then move the view by that difference.

It might sound complicated so you might want to just use this free function that I made that does it all automatically; it's on the SFML Wiki: RotateViewAt



来源:https://stackoverflow.com/questions/50034864/sfml-views-setcenter-vs-rotation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!