Re: Tile Engine question
Posted: Wed Mar 24, 2010 3:55 am
It's still worth your time to learn about pointers if you plan to continue programming
The Next Generation of 2D Roleplaying Games
http://elysianshadows.com/phpBB3/
Code: Select all
class Area {
unsigned short int mapLayer1[WIDTH][HEIGHT]
unsigned short int mapLayer2[WIDTH][HEIGHT]
Tile tileset[TILE_AMOUNT];
};
Code: Select all
tile[mapLayer1[x][y]].solid
Yeah, I completely understand. We statically allocate our array of tiles (for our tileset) to be 256, because our sheets are 512x512 with each tile at 32x32. This allows us to have 256 unique tiles per sheet, which happens to be a character or unsigned short int. It's pretty nifty and easier on the hardware for us to handle it like that.K-Bal wrote:With the layer approach, I also went from having a Tile class to integers. However, I use std::vectors for storing them instead of arrays.
That's a pretty shitty option, imho. One of the greatest benefits from tile-based games is that you are able to determine which tile a point lies within with simple integer division: map[x/tileSize][y/tileSize]. Handling everything like an "object" in a quadtree (with unique sizes, positions, and nonuniform positions) kind of defeats the entire purpose of a tile-based engine. You're destroying the point/tile associativity which is the thing that makes tile-based engines so nifty.K-Bal wrote:There is also the option to handle each tile as an object with x, y, z coordinate and size. This way you can handle everything on the map, including tiles, objects and characters in the same fashion. However, you will probably need z-ordering and a quadtree
There are some advantages, but I prefer layers, too. A friend of mine made an isometric tile engine with this approach and it's pretty flexible. It helps you with pseudo 3d stuff, multiple floors in buildings etc. It's not that useful for rectangular tile maps, I have to admit.GyroVorbis wrote:That's a pretty shitty option, imho. One of the greatest benefits from tile-based games is that you are able to determine which tile a point lies within with simple integer division: map[x/tileSize][y/tileSize]. Handling everything like an "object" in a quadtree (with unique sizes, positions, and nonuniform positions) kind of defeats the entire purpose of a tile-based engine. You're destroying the point/tile associativity which is the thing that makes tile-based engines so nifty.
You are still building the map from equal sized partsGyroVorbis wrote:As a matter of fact is that even considered a tile engine if you handle it like that? I'm not even sure...
GyroVorbis wrote: which happens to be a character or unsigned short int. It's pretty nifty and easier on the hardware for us to handle it like that.
That's a pretty shitty option, imho. One of the greatest benefits from tile-based games is that you are able to determine which tile a point lies within with simple integer division: map[x/tileSize][y/tileSize]. Handling everything like an "object" in a quadtree (with unique sizes, positions, and nonuniform positions) kind of defeats the entire purpose of a tile-based engine. You're destroying the point/tile associativity which is the thing that makes tile-based engines so nifty.K-Bal wrote:There is also the option to handle each tile as an object with x, y, z coordinate and size. This way you can handle everything on the map, including tiles, objects and characters in the same fashion. However, you will probably need z-ordering and a quadtree
As a matter of fact is that even considered a tile engine if you handle it like that? I'm not even sure...
K-Bal wrote:There is also the option to handle each tile as an object with x, y, z coordinate and size.
Did I miss something?K-Bal wrote:You are still building the map from equal sized parts
I don't really get what you're trying to say here. If I understand correctly, you're saying that the collision region must be within a tile region? Even if it wasn't, you would still be better off handling it with a tile-based system. It's quicker to determine the few potentially colliding tiles surrounding the player with some simple integer division than it is to search through a quadtree (for broad-phase collision) to determine potentially colliding tiles.avansc wrote:while to some extent i agree with the quad tree statement, based on figuring out what tiles to draw and so on. AS LONG as all content/collision info and everything really, is contained in a tile unit.
I have the same map layout as this and i think its a better and easier option than pointers to pointers to pointers...............GyroVorbis wrote:Jesus, guys. Am I the only person whose map is simply a bunch of unsigned short integers rather than an array of pointers to tiles?
I think this way is by FAR the nicest way to do it. That way every map location is an index to your tileset like so:Code: Select all
class Area { unsigned short int mapLayer1[WIDTH][HEIGHT] unsigned short int mapLayer2[WIDTH][HEIGHT] Tile tileset[TILE_AMOUNT]; };
It's also easiest for your map editor to save out and read in. It also allows you to refer to tiles as specific numbers rather than locations on the map.Code: Select all
tile[mapLayer1[x][y]].solid
GyroVorbis wrote:I don't really get what you're trying to say here. If I understand correctly, you're saying that the collision region must be within a tile region? Even if it wasn't, you would still be better off handling it with a tile-based system. It's quicker to determine the few potentially colliding tiles surrounding the player with some simple integer division than it is to search through a quadtree (for broad-phase collision) to determine potentially colliding tiles.avansc wrote:while to some extent i agree with the quad tree statement, based on figuring out what tiles to draw and so on. AS LONG as all content/collision info and everything really, is contained in a tile unit.
I should have said, that you are still able to create a map from tiles in a graphical senseGyroVorbis wrote: Did I miss something?
I learned plenty about pointers when was earning my CS Degree. =)short wrote:It's still worth your time to learn about pointers if you plan to continue programming
Seriously, dude? Seriously?avansc wrote:while i agree that doing something like tile[layers][width][height]; is "prettier" than doing Tile ***tiles;
i prefer doing ***tiles. here is why.
i dont want to have to use sizeof(tile)*layers*width*height bytes if i only need a fraction of that.
if you so happen to have a map that is 20*20 and only use 3 layers. i think its lazy to just use 256*256*7 to it. lets assume at best your tile only needs 1 byte to be represented.
that be 1200 bytes, as apposed to 393216 bytes
thats an over exaggeration. but you get what im saying.
Oh, a nice comeback by Gyro. Let's see what Avan has to counter... What do you think Eatcomics?GyroVorbis wrote:Seriously, dude? Seriously?avansc wrote:while i agree that doing something like tile[layers][width][height]; is "prettier" than doing Tile ***tiles;
i prefer doing ***tiles. here is why.
i dont want to have to use sizeof(tile)*layers*width*height bytes if i only need a fraction of that.
if you so happen to have a map that is 20*20 and only use 3 layers. i think its lazy to just use 256*256*7 to it. lets assume at best your tile only needs 1 byte to be represented.
that be 1200 bytes, as apposed to 393216 bytes
thats an over exaggeration. but you get what im saying.
I think you're just looking for ways to disagree with me. You're WASTING SPACE by having a set map size? On a Dreamcast or PSP, where I have to manage memory sparingly, I would like to know how much space I have left with a map loaded. If I'm allocating a map to be fuck knows what size, it isn't exactly useful to me when I'm trying to determine how much space scripting, animations, and other assets are going to be taking up. So what if I have a few less bytes? Can I fill them up with other shit? Of course not. Because then you think you have more RAM left than you do, change areas to a place with a bigger map, and run out of RAM.
Not to MENTION you're literally thrashing the living shit out of your heap by dynamically allocating chunks that large.
You aren't gaining anything by doing it your way other than having to allocate on the heap EVERY map switch (which you just said in another post is "very slow"). So it's not "lazy" to have a block of memory allocated on the stack to hold your map. It's faster, smarter, and more meaningful when you're trying to manage memory.
And yes, I'm going to stoop to the level of byte comparison. You're bitching about "wasting" space. Consider the fact that your "pointer" is actually 4 bytes on a 32-bit machine and 8 bytes on a 64-bit machine while representing a tile as a single character is only a single byte. With your "method" a map the same size represented as pointers is actually WAY the fuck bigger (4x-8x) than the equivalent character representation.
Have a nice day.