I have this sprite of a car that moves with varied speed.
It is inside a view and the view is moved to the left to keep the car always in the center of the window.
The view accompanies the displacement of the car, ie it is shifted to the left as the car accelerates or brakes. This way the car will always appear in the center.
But if for example it is overtaken by another car, it will be left behind. For it not to disappear from the window, I have to zoom in the view so that all the cars appear.
But for this, I need to know the position of the car in relation to the window (not in relation to the view).
getGlobalBounds().left
or getPosition().x
show the same value, which is the position relative to the view, not relative to the window, as shown in the image.
How to know a sprite position inside a view, relative to window?
After several hours of research, I finally find the easy way of achieve this. And yes, it was ridiculously easy.
But first, I would like to clear up some misconceptions.
getGlobalBounds().left
orgetPosition().x
show the same value, which is the position relative to the view, not relative to the window, as shown in the image.
In fact, those methods return the position in the world, not in the view nor in the window.
You can have, for instance, a 500x500
window, with a 400x400
view, in a 10000x10000
world. You can place things in the world, outside of the view or the window. When the world is rendered, then the transformations of the view (translations, rotations, zoom, ...) are applied to the world and things are finally shown in the window.
To know where a coordinate in the world is represented in the window (or any other RenderTarget) and vice versa, SFML actually have a couple of functions:
RenderTarget.mapCoordsToPixel(Vector2f point)
Given a point in the world gives you the corresponding point in the RenderTarget.
RenderTarget.mapPixelToCoords(Vector2f point)
Given a point in the RenderTarget gives you the corresponding point in the world. (this is useful to map mouse clicks to corresponding points in your world)
int main()
{
RenderWindow window({ 500, 500 }, "SFML Views", Style::Close);
sf::View camera(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
sf::Vector2f orig(window.getSize().x / 2, window.getSize().y / 2);
camera.setCenter(orig);
sf::Font f;
f.loadFromFile("C:/Windows/Fonts/Arial.ttf");
sf::Text t;
t.setFont(f);
sf::RectangleShape r;
r.setPosition(10, 10);
r.setSize(sf::Vector2f(20, 20));
r.setOutlineColor(sf::Color::Blue);
r.setFillColor(sf::Color::Blue);
t.setPosition(10, 40);
while (window.isOpen())
{
for (Event event; window.pollEvent(event);)
if (event.type == Event::Closed)
window.close();
else if (event.type == Event::KeyPressed){
camera.move(-3, 0);
camera.rotate(5.0);
camera.zoom(1.1);
}
auto realPos = window.mapCoordsToPixel(r.getPosition());
std::string str = "Pos: (" + std::to_string(realPos.x) +","+ std::to_string(realPos.y) + ")";
t.setString(str);
window.clear();
window.setView(camera);
window.draw(r);
window.draw(t);
window.display();
}
return EXIT_SUCCESS;
}