In this tutorial, you'll learn how to use SFML 2D views. Views are like 2D cameras, which allow you to move, zoom or scroll without having to move or resize the whole scene.
Views are defined by the
sf::View class, which is basically a 2D rectangle nicely wrapped in a
A view can be created either with a center point and a half-size, or directly from a bounding rectangle :
sf::Vector2f Center(1000, 1000); sf::Vector2f HalfSize(400, 300); sf::View View1(Center, HalfSize); // Or sf::View View2(sf::FloatRect(600, 700, 1400, 1300));
All these parameters can be set and get at any time using the accessors :
View.SetCenter(500, 300); View.SetHalfSize(200, 100); // Or View.SetFromRect(sf::FloatRect(300, 200, 700, 400));
sf::Vector2f Center = View.GetCenter(); sf::Vector2f HalfSize = View.GetHalfSize(); sf::FloatRect Rectangle = View.GetRect();
There are also two helper functions to move or zoom (resize) the view :
View.Move(10, -5); // Move the view of (10, -5) units View.Zoom(0.5f); // Zoom by a factor of 1/2 (ie. unzoom to make the view twice larger)
As you can see there's nothing complicated here, only a few functions to control the view's position and size.
To use a view, you need to call the
SetView function of the
sf::RenderWindow class :
// Use our custom view App.SetView(View);
Any object drawn after the call to
SetView (and before the next one) will be affected by the view.
Once set, the render window keeps a link to the view so you can update it without calling
all your modifications will be automatically taken in account.
Every render window has a default view, which always matches the initial size of the window. You can access this view,
and even modify it if needed, with the
GetDefaultView function :
sf::View& DefaultView = App.GetDefaultView();
The default view is not updated when its window is resized : as a consequence, what's visible in your
window will never be affected by its size (ie. you won't see more if you maximize the window), which is exactly
what happens with a 3D camera.
However, you can easily setup a view which always keeps the same dimension as the window, by catching the
sf::Event::Resized event and updating the view accordingly.
Accessing the default view is also convenient to go back to the initial view. For example, it can be useful if you want to draw a user interface on top of the game, which usually doesn't follow the camera.
App.SetView(View); // Draw the game... App.SetView(App.GetDefaultView()); // Draw the interface...
When a custom view is set, or when your window has been resized, don't forget that objects coordinates no longer match the window pixels, be careful to handle conversions if needed (for example, when you test the mouse position with the sprites' rectangles). Always remember that what you actually see is the view rectangle, not the window one.
If you want to convert window coordinates to view coordinates, probably after a mouse clic, you can use the
RenderWindow::ConvertCoords function :
// Get the cursor position in view coordinates sf::Vector2f MousePos = App.ConvertCoords(App.GetInput().GetMouseX(), App.GetInput().GetMouseY());
By default, this function uses the view currently set in the window to perform the conversion. However, you can use
any other view by passing its address as the third parameter (which is
NULL by default).
2D views provide an easy and convenient way to deal with effects such as scrolling and zooming, with no performances penalty. The only thing to take care of when using views, is the possible conversions that could be needed if you try to map pixels to coordinates.