Tile Engine question

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Tile Engine question

Post by short »

It's still worth your time to learn about pointers if you plan to continue programming
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Tile Engine question

Post by Falco Girgis »

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?

Code: Select all

class Area {
    unsigned short int mapLayer1[WIDTH][HEIGHT]
    unsigned short int mapLayer2[WIDTH][HEIGHT]

    Tile tileset[TILE_AMOUNT];
};
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

tile[mapLayer1[x][y]].solid
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.
K-Bal
ES Beta Backer
ES Beta Backer
Posts: 701
Joined: Sun Mar 15, 2009 3:21 pm
Location: Germany, Aachen
Contact:

Re: Tile Engine question

Post by K-Bal »

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.

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 ;)
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Tile Engine question

Post by Falco Girgis »

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.
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: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 ;)
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.

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
ES Beta Backer
ES Beta Backer
Posts: 701
Joined: Sun Mar 15, 2009 3:21 pm
Location: Germany, Aachen
Contact:

Re: Tile Engine question

Post by K-Bal »

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.
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:As a matter of fact is that even considered a tile engine if you handle it like that? I'm not even sure...
You are still building the map from equal sized parts ;)
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Tile Engine question

Post by avansc »

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.
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 ;)
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.

As a matter of fact is that even considered a tile engine if you handle it like that? I'm not even sure...

for the first part, im sure thats just a simple mistake, but short is usually half of what a word is on any given target architecture, not im not sure on DC or PSP, but on most systems today unsigned short int will give you values from 0 to 2^16 -1, character (char) would be right, but only if its unsigned char. anyways, im sure just a honest mistake.

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.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Tile Engine question

Post by Falco Girgis »

Yeah, I meant unsigned character. I do believe that the size of a short on the Dreamcast is the same as a character, though.
K-Bal wrote:There is also the option to handle each tile as an object with x, y, z coordinate and size.
K-Bal wrote:You are still building the map from equal sized parts ;)
Did I miss something?
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 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.
User avatar
MrDeathNote
ES Beta Backer
ES Beta Backer
Posts: 594
Joined: Sun Oct 11, 2009 9:57 am
Current Project: cocos2d-x project
Favorite Gaming Platforms: SNES, Sega Megadrive, XBox 360
Programming Language of Choice: C/++
Location: Belfast, Ireland
Contact:

Re: Tile Engine question

Post by MrDeathNote »

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?

Code: Select all

class Area {
    unsigned short int mapLayer1[WIDTH][HEIGHT]
    unsigned short int mapLayer2[WIDTH][HEIGHT]

    Tile tileset[TILE_AMOUNT];
};
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

tile[mapLayer1[x][y]].solid
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.
I have the same map layout as this and i think its a better and easier option than pointers to pointers to pointers...............
http://www.youtube.com/user/MrDeathNote1988

Image
Image

"C makes it easy to shoot yourself in the foot. C++ makes it
harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Tile Engine question

Post by avansc »

GyroVorbis wrote:
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 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.

okay, lets assume i have a map that is 100*100 tiles, (just arbitrary numbers), and that on screen space at any given time i only take up 10*10 tiles

so yeah, right its pretty easy to find out exactly what tiles are presently in view space. but lets assume my collision layer, to save space, is just a bunch of coordinates that form a polygon for example, and lest assume that there is a line/edge that crosses view space, but the vertices don't lie with in it. how do i efficiently calculate if a edge lies within screen space?
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Tile Engine question

Post by avansc »

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.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
K-Bal
ES Beta Backer
ES Beta Backer
Posts: 701
Joined: Sun Mar 15, 2009 3:21 pm
Location: Germany, Aachen
Contact:

Re: Tile Engine question

Post by K-Bal »

GyroVorbis wrote: Did I miss something?
I should have said, that you are still able to create a map from tiles in a graphical sense ;)
mattheweston
Chaos Rift Junior
Chaos Rift Junior
Posts: 200
Joined: Mon Feb 22, 2010 12:32 am
Current Project: Breakout clone, Unnamed 2D RPG
Favorite Gaming Platforms: PC, XBOX360
Programming Language of Choice: C#
Location: San Antonio,Texas
Contact:

Re: Tile Engine question

Post by mattheweston »

short wrote:It's still worth your time to learn about pointers if you plan to continue programming
I learned plenty about pointers when was earning my CS Degree. =)
Image
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Tile Engine question

Post by Falco Girgis »

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.
Seriously, dude? Seriously?

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. :)
User avatar
eatcomics
ES Beta Backer
ES Beta Backer
Posts: 2528
Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois

Re: Tile Engine question

Post by eatcomics »

GyroVorbis wrote:
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.
Seriously, dude? Seriously?

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. :)
Oh, a nice comeback by Gyro. Let's see what Avan has to counter... What do you think Eatcomics?
Well I'd have to say that Gyro has this one wrapped up, and I think Avan's offense is lacking this season, but we'll just have to see... oh and the shot is up....
Image
User avatar
LeonBlade
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1314
Joined: Thu Jan 22, 2009 12:22 am
Current Project: Trying to make my first engine in C++ using OGL
Favorite Gaming Platforms: PS3
Programming Language of Choice: C++
Location: Blossvale, NY

Re: Tile Engine question

Post by LeonBlade »

What do you guys think about the way I load my tiles?
Here's the documentation.
There's no place like ~/
Post Reply