Hello, I'm still working on my 2D platformer game using SFML. I would like to ask, should I have a sprite for every tile I draw on the screen, or should I use one sprite for all similar tiles?
I'm trying to implement a collision detection system, using the former, I couldn't build a collision detection system. Using the latter, it works, but the game becomes so slow. What should I do ?
How can I implement a collision detection system when I'm using one sprite for all tiles ?
What I'm doing is that I'm setting the position of the sprite, drawing it, then changing its position again, and so on...
The collision detection code I have works by getting positions of two sprites then detecting if they overlap each other, so it doesn't work with the first way.
sf::Sprites are a graphical unit and should have absolutely nothing to do with your collision detection. Graphics and physics are two different things and should be handled seperately.
The traditional approach with a tile based map system is something like this:
Have a "player" object which consists of a few things
- sprite (for graphical representation)
- position
- size
The position and size can be used when determining collision detection. You might want to give it other properties, like speed, health, etc -- whatever else you need to define your player.
Maps are generally some kind of 2D array of tiles (although I hate using 2D arrays directly, I would simulate one with a 1D vector). Each tile has several properties:
- sprite or other graphical information
- flag to indicate if it's solid or not
When moving the player, you just take their position and find out which tile(s) they are passing through. If any of those tiles are solid (as indicated by that tile's flag on the map), you forbid movement.
There are many variations of this, but this is generally the easiest to understand and the most simplistic to impliment.
Just to remind you, the "first way" was using one sprite for each tile.
How can I implement a collision detection system when I'm using one sprite for all tiles ?
If you use the same sprite for each objects, you need to store the position of each tile somewhere.
And that's where the collision detection routines get their info from.
However, using one sprite for each tile shouldn't be slow, even if you have ten-thousands of tiles.
You might need to check whether the tile is actually visible before rendering, however I'd expect a library like SFML to do that for you.
If it's the collision detection that's slowing you down, you might want to split your world into logical areas of fixed sizes, so that you only have to check the surrounding areas for colliding objects.
You might need to check whether the tile is actually visible before rendering, however I'd expect a library like SFML to do that for you.
I wouldn't. And I'm sure SFML doesn't do that. There are far too many factors that would make it impractical. SFML allows the view to be scaled, rotated, skew'd, etc. Any of those things make it difficult to tell whether or not a sprite is 'on screen'.
Furthermore sprites and views are independent entities so the Sprite class has no way to know whether or not the view is skewed or not.
Nevermind other complexities introduced by shaders (which SFML also supports), which pretty much make it impossible.
The work involved in predicting whether or not a sprite is visible would be just about as much work as actually drawing it (except it would have to be done in software, so it would actually end up being slower than just drawing it). So it doesn't make sense for SFML to check for that.