SFML community forums

Help => Graphics => Topic started by: burningprodigy on July 10, 2012, 06:46:07 am

Title: How to detect OnScreen Sprites when using views?
Post by: burningprodigy on July 10, 2012, 06:46:07 am
I'm using a custom sf::View for my RenderWindow in my tile-based RPG. Now I use sf::View's Move() method to scroll around the map. Now the problem is, how do I detect the sprites that are currently on the screen? I tried this:

/** pro::Tile is derived from sf::Sprite **/
bool LevelRenderer::OnScreen(pro::Tile& tile, sf::RenderWindow& app)
{
    return (tile.GetPosition().x > 0 && tile.GetPosition().x < app.GetWidth()
            && tile.GetPosition().y > 0 && tile.GetPosition().y < app.GetHeight());
}

However, although it initially works fine, after I Move() the view, the sprite's positions aren't updated and new sprites that appear on the screen are not drawn. What should I do?
Title: Re: How to detect OnScreen Sprites when using views?
Post by: Xenir on July 10, 2012, 10:52:32 am
It works bad, because you are checking sprite's position depending on starting view, when left upper corner is (0, 0). You should check position depending on the current view, not starting. I think you should use sf::RenderWindow::convertCoords(...) to convert sprite's position to local, depending on current view and then check if the sprite is currently on the screen. I'm not sure, because I didn't use sf::View yet, but I think here's your problem. Read the tutorial about sf::View (https://github.com/SFML/SFML/wiki/TutorialUsingView) to make sure or search the documentation.

Edit: Oops... It was small fault in bbcode... Sorry for that
Title: Re: How to detect OnScreen Sprites when using views?
Post by: eXpl0it3r on July 11, 2012, 04:42:30 pm
However, although it initially works fine, after I Move() the view, the sprite's positions aren't updated ...
Ehrm that's the sense of a sf::View...  ???

When you move the view around the view coordinates won't fit the window coordinates but the sprite position doesn't not change. A transformation on a view affects all objects drawn with that view but doesn't change anything internal on any object.

I strongly advice you to use SFML 2.0rc since the 1.6 version is updated and contains many bugs...

And my tutorial on sf::View (https://github.com/SFML/SFML/wiki/TutorialUsingView), that Xenir already linked (with a bad link :-[ ), is I think a good source to understand the view, although you won't be able to use everything described there with SFML 1.6.

As for your problem; it would be easy to implement with convertCoords() unfortunatly that doesn't exist in SFML 1.6 and I'm not quite sure if sf::Sprite::TransformToGlobal() will do the trick...
You basically have to take in account the moved view when checking against the sprites position.
Title: Re: How to detect OnScreen Sprites when using views?
Post by: Laurent on July 11, 2012, 04:47:12 pm
Quote
it would be easy to implement with convertCoords() unfortunatly that doesn't exist in SFML 1.6
It does ;)
Title: Re: How to detect OnScreen Sprites when using views?
Post by: eXpl0it3r on July 11, 2012, 04:54:59 pm
Quote
it would be easy to implement with convertCoords() unfortunatly that doesn't exist in SFML 1.6
It does ;)

Oh I see, it's not part of the sf::RenderTarget (as in SFML 2.0) where I was looking for it, but it's part of the RenderWindow  (http://www.sfml-dev.org/documentation/1.6/classsf_1_1RenderWindow.php#a05c614a2cdc2c2c4e3b473e39b3b9a17)itself.

So to get the rectangle that gets actually displayed, you just have to call the function four times, for the coordinates (0/0), (0/window height), (window width, 0) amd (window width, window height).
With that rect you can now use the function intersect() (http://www.sfml-dev.org/documentation/1.6/classsf_1_1Rect.php#a703256dda71eb3a5e748f5b0265e9272) to find out if the sprite in some way touches the currently shown part of the view.
Title: Re: How to detect OnScreen Sprites when using views?
Post by: Laurent on July 11, 2012, 05:00:14 pm
Quote
So to get the rectangle that gets actually displayed, you just have to call the function four times, for the coordinates (0/0), (0/window height), (window width, 0) amd (window width, window height).
sf::View has functions to retrieve its rectangle in a more direct way ;)