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

Author Topic: Rendering a map (effectively)  (Read 1654 times)

0 Members and 1 Guest are viewing this topic.

Mrremrem

  • Newbie
  • *
  • Posts: 5
  • Working my way to making a game engine!
    • View Profile
    • Github profile :)
Rendering a map (effectively)
« on: May 30, 2023, 01:33:22 am »
Howdy!

Apologies if this isn't the right place to ask (I was debating with either General or Graphics but chose this :P). Anyway, at first I was rendering my map with a simple vector but I wanted to extend this further. I wanted to have layers that can be rendered in the order they are in (floor first, player next, anything above player goes after etc.) so I extended this with a 2D vector of layers with tiles. No problem. Most of the time (at least in my vision) there's going to be less tiles for every layer added. So the worst case being every layer filled with tiles is unlikely. However, I want to extend this with an unordered_map. The reason for this is because I have an entity base class that every tile and player derives. If I were to keep a 2D vector then finding a certain entity would take O(N) (let's say, Player 3). However, using a map I can find "Player" and find the second player in however many players there are (in this case 3). But, if I were to render everything, I would get something like this:

Code: [Select]
// The container:
// std::vector<std::unordered_map<std::string, std::vector<Entity*> > > entityLayerList;

for (auto& layerIndex : entityLayerList) {
        for (auto& entityList : layerIndex) {
            for (Entity* entityIndex : entityList.second) {
               
            }
        }
    }

Which scares me because this is way too many loops. Is there a better way to deal this? Should I go back to a 2D array and figure out ways to properly cast from entities to their own objects? Any feedback would be appreciated!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Rendering a map (effectively)
« Reply #1 on: May 31, 2023, 05:42:54 pm »
A vector of maps of vectors seems a bit crazy but if it's working fine, the method should be fine.

One thing you can do to reduce "layers of grids" is to store them all in one place and then sort them to draw them in the correct order.
To do this, you'd first need to add a z (or depth) value to each tile. Then, to avoid sorting the actual vector, create a duplicate vector of pointers to each member of the original vector and sort those pointers based on the z value of what they are pointing to. You can also do this with a vector of indices instead of pointers. Remember to fill the 'sortable vector' with initial values. For a pointer vector, a pointer to each tile. For an index vector, a index to each tile (basically an increasing value from 0).

Co-incidentally, I've just applied one of these methods (the index version) to something to sort 3D shapes in one vector.
See it here (but this branch might not last forever):
https://github.com/Hapaxia/SelbaWard/blob/starfield3d/src/SelbaWard/Starfield3d.cpp#L253-L257
(click to show/hide)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Mrremrem

  • Newbie
  • *
  • Posts: 5
  • Working my way to making a game engine!
    • View Profile
    • Github profile :)
Re: Rendering a map (effectively)
« Reply #2 on: May 31, 2023, 08:47:06 pm »
A vector of maps of vectors seems a bit crazy but if it's working fine, the method should be fine.

One thing you can do to reduce "layers of grids" is to store them all in one place and then sort them to draw them in the correct order.
To do this, you'd first need to add a z (or depth) value to each tile. Then, to avoid sorting the actual vector, create a duplicate vector of pointers to each member of the original vector and sort those pointers based on the z value of what they are pointing to. You can also do this with a vector of indices instead of pointers. Remember to fill the 'sortable vector' with initial values. For a pointer vector, a pointer to each tile. For an index vector, a index to each tile (basically an increasing value from 0).

Co-incidentally, I've just applied one of these methods (the index version) to something to sort 3D shapes in one vector.
See it here (but this branch might not last forever):
https://github.com/Hapaxia/SelbaWard/blob/starfield3d/src/SelbaWard/Starfield3d.cpp#L253-L257
(click to show/hide)

Thanks for the response.

I see what you're saying. So essentially I have to add in some value that represents a layer (like Z axis) and sort them accordingly with another vector (of pointers/ints), which is similar to a priority queue! And if I'm imagining correctly, I only need one loop to render each tile!

Thank you!!!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Rendering a map (effectively)
« Reply #3 on: May 31, 2023, 09:23:46 pm »
Yes, that does sound like what I was saying. You could just consider "z axis" to be "layer number" and sort using those values.

You're welcome! Glad it helps.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything