Saturday, April 30, 2016

Whole map design vs. tiles array design


I am working on a 2D RPG, which will feature the usual dungeon/town maps (pre-generated).


I am using tiles, that I will then combine to make the maps. My original plan was to assemble the tiles using Photoshop, or some other graphic program, in order to have one bigger picture that I could then use as a map.


However, I have read on several places people talking about how they used arrays to build their map in the engine (so you give an array of x tiles to your engine, and it assemble them as a map). I can understand how it's done, but it seems a lot more complicated to implement, and I can't see obvious avantages.


What is the most common method, and what are advantages/disadvantages of each?



Answer




First off, let me say that 2D RPGs are near and dear to my heart and working with old DX7 VB6 MORPG engines (don't laugh, it was 8 years ago, now :-) ) is what first got me interested in game development. More recently, I started converting a game I worked on in one of those engines to use XNA.


That said, my recommendation is that you use a tile-based structure with layering for your map. With any graphics API you use, you're going to have a limit on the size of textures you can load. Not to mention the graphics card texture memory limits. So, considering this, if you want to maximize the size of your maps while not only minimizing the amount and size of textures you load into memory but also decreasing the size of your assets on the user's hard drive AND the load times, you're definitely going to want to go with tiles.


As far as implementation goes, I've gone into detail on how I handled it on a few questions here on GameDev.SE and on my blog (both linked below), and that's not exactly what you're asking so I'll just go into the basics here. I'll also make note of the features of tiles that make them beneficial over loading several large pre-rendered images. If anything is not clear, let me know.



  1. The first thing you need to do is create a tilesheet. This is just a big image that contains all your tiles aligned in a grid. This (and maybe an extra one depending on the number of tiles) will be the only thing you need to load. Just 1 image! You could load 1 per map or one with every tile in the game; whatever organization works for you.

  2. Next, you need to understand how you can take that "sheet" and translate each tile into a number. This is pretty straightforward with some simple math. Note that the division here is integer division, so the decimal places are dropped (or rounded down, if you prefer). How to convert cells to coordinates and back.


  3. OK, now that you've broken the tilesheet into a series of cells (numbers), you can take those numbers and plug them into whatever container you like. For the sake of simplicity, you can just use a 2D array.


    int[,] mapTiles = new int[100,100]; //Map is 100x100 tiles without much overhead



  4. Next, you want to draw them. One of the ways you can make this a LOT more efficient (depending on map size) is to calculate only the cells that the camera is currently viewing and loop through those. You can do this by fetching the map tile array coordinates of the camera's top-left (tl) and bottom-right (br) corners. Then loop from tl.X to br.X and, in a nested loop, from tl.Y to br.Y to draw them. Example code below:


    for (int x = tl.X; x <= br.X;x++) {
    for (int y = tl.Y; y <= br.Y;y++) {
    //Assuming tileset setup from image
    Vector2 tilesetCoordinate = new Vector2((mapTiles[x,y] % 8) * 32,(mapTiles[x,y] / 8) * 32);
    //Draw 32x32 tile using tilesetCoordinate as the source x,y
    }
    }


  5. Jackpot! That's the basics of the tile engine. You can see that it's easy to have even a 1000x1000 map with not much overhead. Also, if you have less than 255 tiles, you could use a byte array cutting down the memory by 3 bytes per cell. If a byte is too small, a ushort would probably suffice for your needs.


Note: I left out the concept of world coordinates (which is what your camera's position will be based on) since that, I think, is outside the scope of this answer. You can read up on that here on GameDev.SE.


My Tile-Engine Resources
Note: All of these are targeted at XNA, but it pretty much applies to anything – you just need to change the draw calls.



  • My answer to this question outlines how I handle the map cells and layering in my game. (See third link.)

  • My answer to this question explains how I store the data in a binary format.

  • This is the first (well, technically second, but first "technical") blog post about the development of the game I was working on. The whole series contains information about things like pixel shaders, lighting, tile behaviours, movement and all that fun stuff. I actually updated the post to include the content of the my answer to the first link I posted above, so you may want to read it instead (I may have added things). If you have any questions, you can drop a comment there or here and I'd be happy to help.



Other Tile-Engine Resources



  • The tile engine tutorial from this site gave me the basis I used for creating my maps.

  • I haven't actually watched these video tutorials yet because I haven't had the time, but they're probably helpful. :) They may be outdated though, if you're using XNA.

  • This site has some more tutorials that (I think) are based on the above videos. It may be worth checking out.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...