SFML community forums

Help => General => Topic started by: fakepotato on November 15, 2014, 02:02:19 pm

Title: [SOLVED]How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 15, 2014, 02:02:19 pm
For example, i have 180x40 map, each tile is 32x32 pixels.
Is it efficiently to hold em in the two-dimensional matrix? Is this bad way? I am new to gamedev, so i have some troubles with this question.
Another idea is to hold game objects in vector of pointers, is this better one?
Thanks for answers.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Jesper Juhl on November 15, 2014, 05:32:57 pm
For such a small map I'd say "it doesn't matter".
Just stick it in a std::vector and move on.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Ixrec on November 15, 2014, 05:40:15 pm
As with any design question like this, the answer is: It depends on a lot of details and you'll have to just try something and see how it works.

Since you haven't even told us what you mean by "tile", we can't even give you a general best practices answer.  It is very bad to have 32x32 textures, but 32x32 sprites sharing one texture is fine, and even that can be optimized to a single draw() call with a vertex array if you feel the need.

You also don't say what "game objects" are or what it means to hold one "in a vector of pointers" . Is the game object just a bunch of numbers or does it contain a heavy resource like a texture?  Are you after polymorphism? Any shared ownership? etc.  But it is safe to say that you should avoid using pointers (smart or raw) except when you know you have a good reason.

What Jesper said is correct though: When you need a container of anything, std::vector is almost always a safe choice and often the best choice.

A lot of this is general C++ stuff not specific to SFML that should be part of learning C++ itself.  So you may have to go do that first.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 15, 2014, 11:11:50 pm
Okay, for example i have a game without any tiles no more.
Let's imagine we have a basic class mapObject, or sth like that. We have an std::vector<mapObject*>,where we can hold objects of inherited objects like tree, bush, house or stone etc. Each object holds it's coordinates and size, key of texture and so on. Is it efficient solution? I mean, we can draw these objects on map using for cycle, check collisions with player etc..

Sorry for my bad English, sure you got what I mean.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 15, 2014, 11:13:06 pm
For such a small map I'd say "it doesn't matter".
Just stick it in a std::vector and move on.
What's a big map then? I thought such matrix will use lots of CPU resourses
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Ixrec on November 15, 2014, 11:42:30 pm
Since you said "key of texture", rather than an actual texture, you can probably draw tons and tons of them without any serious difficulty.

However, it's not clear that you actually need polymorphism, since tree/bush/house/stone would presumably just be mapObjects with different sizes and texture keys.  Sticking to one mapObject type and using std::vector<mapObject> instead of std::vector<mapObject*> would be a lot easier to work with (and also more efficient, but being simpler and thus harder to screw up is more important at this stage).

It's hard to say exactly what a "big" map is since again it depends a lot on what the map consists of, but 32x32 tiles is definitely not a lot.  Just think about how many polygons your typical AAA game is drawing every frame, and remember a tile is only two triangles.



For now, just make a vector of objects and don't sweat the details.  If you write decent C++, it'll be easy to come back and try other approaches later without breaking the rest of your code.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 15, 2014, 11:45:54 pm
I meant 180x40 tiles and each is 32 pixels * 32 pixels :)
That means 7200 boxes, 180 in width and 40 in height.. My game uses view scrolling
I think it's a way bigger than 32x32  :)
But i got what u mean. I ll better use the std::vector in this case. I have no necessarity for big matrix if i have 30-40 objects on map, 6-8 of each type.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Ixrec on November 15, 2014, 11:47:57 pm
That's still not much.  Don't worry about your map size for now and start working on the rest of your game.  You can always do performance tests once you have something functional.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 20, 2014, 01:30:51 am
That's still not much.  Don't worry about your map size for now and start working on the rest of your game.  You can always do performance tests once you have something functional.

So if my tile keys are represented with int, i can use int mapMatrix[180][40] ? or nah?
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Hapax on November 20, 2014, 01:53:41 am
I don't see why not. Assuming that the int you use end up being 4 bytes, your map of indices/keys becomes 180 x 40 x 4 = 28,800; that's well under 30k.

That said, it's often recommended that you store it as a one-dimensional map (i.e. mapMatrix[7200]) instead of a two-dimensional map. There are advantages and disadvantages to both methods, however.

Also, don't use a standard array. It's much "better" to use a std::vector instead. You can even use a two-dimensional vector if required. If you must use an array, consider, at least, using std::array.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 24, 2014, 01:59:12 am
So i have 2d std::vector, and i am holding every cell(even empty) in MxN space?
p.S. I am gonna hold a simple int, but is it good manner? If i have a cell with value 34, i wouldn't have idea what's that stuff. Or enum solves my question?
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Nexus on November 24, 2014, 02:25:39 am
Use enum whenever you have a finite set of states that are associated with something you can name. Tile types are a prime example for this. In C++11, I recommend using typesafe enums (i.e. enum struct/class).

To reduce the required size, you can specify the underlying type. For example, for 256 distinct types or less, you could use unsigned char, which only takes one byte per value.
enum struct TileType : unsigned char
{
    Empty,
    Block,
    Grass,
    ...
};

And I would use a 1D std::vector and compute 1D indices from 2D indices, it's easier to manage.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 24, 2014, 02:33:36 pm
Thanks very much for explaining.

Quote
And I would use a 1D std::vector and compute 1D indices from 2D indices, it's easier to manage.

So if i have 180*40 space(1d vector 7200) and need to get info about cell 45*20(for example), i should get access to vector[45*40+20]? I understand correctly?
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Nexus on November 24, 2014, 02:40:52 pm
Yes.
Title: Re: How to hold the game map in tile-based 2d game?
Post by: fakepotato on November 24, 2014, 02:48:26 pm
Thanks again.
I can't find how to mark the topic as solved ???
Title: Re: How to hold the game map in tile-based 2d game?
Post by: Nexus on November 24, 2014, 02:50:40 pm
There's no official way to do that. If you want, you can edit the first post and change the thread title to "[Solved] ...", but it's not required. Over time the thread will get lost in the depths of the forum ;)