Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: What is the best way to manage a tilemap?  (Read 7530 times)

0 Members and 1 Guest are viewing this topic.

marco_palestro

  • Newbie
  • *
  • Posts: 3
    • View Profile
What is the best way to manage a tilemap?
« on: January 17, 2012, 04:49:22 pm »
Hi everybody,
    I'm learning SFML and trying to build a small application which uses a 2d tile map; I looked around about some question but couldn't be able to find a complete response, so I decided to ask directly on the forum.
Thanx in advance to everybody who will answer!

Let's say I have a big matrix representing a map, e.g. 1000 * 1000 tiles,
and want to implement a scrolling view over this map.
The scrolling of the view goes one tile at a time, and doesn't have to be realtime, I don't need smooth scrolling pixel by pixel, since the application is turn based (but smooth scrolling is not forbidden...).

Every element of the matrix contains the tile code, so I will build a table mapping every tile code to the corresponding graphic element.

I could load a single image for every tile code (every type of tile), or could load a big image containing all the types of tiles and then addressing to its subrectangles for every code I need.

So far, it seems to me the right "graphic element " is the sprite, but I guess I have two different solutions

- should I build a matrix of sprites just as big as the viewport (let's say 25 * 25) and recalculate the sprites every time I change the coordinates? I'm trying this solution, but it seems to me that continuosly changing the image linked to the sprites is not really good.

- should I build a sprite for every tile, and then use a view? View seem the obvious solution, but I'm wandering if it's good to build a 1000*1000 matrix of sprites.

Regards
Marco

mateandmetal

  • Full Member
  • ***
  • Posts: 171
  • The bird is the word
    • View Profile
    • my blog
What is the best way to manage a tilemap?
« Reply #1 on: January 17, 2012, 08:26:21 pm »
Use a big image containing all your tiles.

You donĀ“t need a sprite for every tile.. I use 1 sprite for the sf::Texture (the tilesheet), then subrect and draw the tile..
- Mate (beverage) addict
- Heavy metal addict _lml
- SFML 2 addict
- My first (and free) game: BichingISH!

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Interesting question about the viewport
« Reply #2 on: January 18, 2012, 06:41:12 pm »
I second that one big image and use SetSubRect to get the tiles.
About the scrolling out of the viewport.  I am curious to see
what answers come up because I am using one in my next project

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
What is the best way to manage a tilemap?
« Reply #3 on: January 19, 2012, 09:39:00 pm »
I would first try to get along with as few as possible data per tile, namely only the logical stuff (like type of tile). Even position needn't be stored, it is given by the index in the matrix. Use containers like std::vector, std::array or boost::multi_array for the tilemap, beware of raw arrays.

Then you use sf::View for the current view, and find out which tiles are visible. In two for loops, you draw only them by creating new sprites on the fly. Performance shouldn't be a problem -- otherwise you could also consider using the new Graphics API with sf::VertexArray.

And for scrolling, just move the sf::View ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

marco_palestro

  • Newbie
  • *
  • Posts: 3
    • View Profile
What is the best way to manage a tilemap?
« Reply #4 on: January 20, 2012, 12:20:36 am »
Hi everybody and thanx for the answers!

Experimenting with the library I've come to a working solution, but I must say I'm a bit disappointed!

Actually I have a sprite for every tile, but draw all the tiles in the viewport calling SetPosition() for the sprite to show.  So for a map of 1000x1000 and a viewport of 20x30 I keep 10E6 sprites just to show 600. It's not too good.

So at this point I don't need a sprite for every tile, but just a matrix of sprites for the tiles to show in the viewport (in this case 20x30), so I'm going to remove all that unused memory.

I would have liked to use a view, but it seems to not repay for the amount of memory I must keep for all the sprites; also I can't apply a view only to part of a window: I'd like to keep a portion of the window for the map (which could use the view to move and resize), and use the rest for messages and so on. Actually, I can't move/resize only the viewport.

Does anybody knows if it possible to bind a view to only part of a window?

mateandmetal: using a big image? Is it not too much? I'm afraid that with a map of 1000x1000 and 32x32 tiles it would be too big

Nexus: I keep a matrix with all the logical data; I'll remove the sprite for tile and just keep the ones used in the viewport, so I don't need to create them on the fly, even if I think the difference is minimum; I loop over height and width of the viewport (let's say 20x30) and Draw() the 600 sprites to show. But at this point, what is the view() for? Scrolling is automatically performed by changing the coordinates of the viewport, since I redraw every tile I must show. I'd like to use the view for zooming, but it seems always affect all the window, and I don't want!
Otherwise I could resize every tile and recalculate coordinates during redraw. Do you think is fine?
Any suggestion about the view?

Thanx again everybody!
Marco

tobybear

  • Newbie
  • *
  • Posts: 27
    • View Profile
What is the best way to manage a tilemap?
« Reply #5 on: January 20, 2012, 12:34:36 am »
Quote from: "marco_palestro"

also I can't apply a view only to part of a window: I'd like to keep a portion of the window for the map (which could use the view to move and resize), and use the rest for messages and so on. Actually, I can't move/resize only the viewport. Does anybody knows if it possible to bind a view to only part of a window?


Yes, this is possible using the SetViewport() function:
    /// The viewport is the rectangle into which the contents of the
    /// view are displayed, expressed as a factor (between 0 and 1)
    /// of the size of the RenderTarget to which the view is applied.
    /// For example, a view which takes the left side of the target would
    /// be defined with View.SetViewport(sf::FloatRect(0, 0, 0.5, 1)).
    /// By default, a view has a viewport which covers the entire target.

BlueMagic

  • Newbie
  • *
  • Posts: 49
    • View Profile
What is the best way to manage a tilemap?
« Reply #6 on: January 20, 2012, 05:39:28 am »
Quote from: "Nexus"
I would first try to get along with as few as possible data per tile, namely only the logical stuff (like type of tile). Even position needn't be stored, it is given by the index in the matrix. Use containers like std::vector, std::array or boost::multi_array for the tilemap, beware of raw arrays.


Why is this? Shouldn't performance of raw arrays be (at least) as good as std::array?

marco_palestro

  • Newbie
  • *
  • Posts: 3
    • View Profile
What is the best way to manage a tilemap?
« Reply #7 on: January 20, 2012, 09:12:29 am »
Quote from: "tobybear"
Quote from: "marco_palestro"

also I can't apply a view only to part of a window: I'd like to keep a portion of the window for the map (which could use the view to move and resize), and use the rest for messages and so on. Actually, I can't move/resize only the viewport. Does anybody knows if it possible to bind a view to only part of a window?


Yes, this is possible using the SetViewport() function:
    /// The viewport is the rectangle into which the contents of the
    /// view are displayed, expressed as a factor (between 0 and 1)
    /// of the size of the RenderTarget to which the view is applied.
    /// For example, a view which takes the left side of the target would
    /// be defined with View.SetViewport(sf::FloatRect(0, 0, 0.5, 1)).
    /// By default, a view has a viewport which covers the entire target.


This makes another question: should I use version 2.0? I assumed to use 1.6 because it's the current version, so I though 2.0 is sort of beta, but this viewport thing seem not to be in version 1.6.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
What is the best way to manage a tilemap?
« Reply #8 on: January 20, 2012, 08:00:30 pm »
Quote from: "marco_palestro"
Does anybody knows if it possible to bind a view to only part of a window?
Yes, set the viewport accordingly (I think this requires SFML 2).

Quote from: "marco_palestro"
I'd like to use the view for zooming, but it seems always affect all the window, and I don't want!
It only affects the current viewport in one window.

Quote from: "BlueMagic"
Why is this? Shouldn't performance of raw arrays be (at least) as good as std::array?
Yes, std::array has the same performance in release mode. But raw arrays have several drawbacks:
  • No value semantics. You can neither pass arrays to functions, nor return them from functions, nor assign nor copy them.
  • Implicit conversion to pointer to the first element, is sometimes unwanted
  • No bound checks in debug mode, leads to hard-to-track bugs
  • No STL-like interface with begin(), end(), size()
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
What is the best way to manage a tilemap?
« Reply #9 on: January 20, 2012, 08:04:57 pm »
Quote from: "marco_palestro"
This makes another question: should I use version 2.0?
Yes. It contains far more features, less bugs and is still being developed ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

mateandmetal

  • Full Member
  • ***
  • Posts: 171
  • The bird is the word
    • View Profile
    • my blog
What is the best way to manage a tilemap?
« Reply #10 on: January 22, 2012, 07:24:23 am »
Quote from: "marco_palestro"
mateandmetal: using a big image? Is it not too much? I'm afraid that with a map of 1000x1000 and 32x32 tiles it would be too big


sorry .. I mean 1 image containing all the tiles in your tilesheet, like this:

- Mate (beverage) addict
- Heavy metal addict _lml
- SFML 2 addict
- My first (and free) game: BichingISH!