How are maps done in SDL?

Started by
2 comments, last by foxcode 10 years, 8 months ago

I'm speaking mostly of maps made with tiles.

Is it ever done in map editors or such programs, then the image file of the map is loaded into the code just like how bitmaps and sprite bitmaps are?

If so, what format/file types is it usually done in? (I'm aware sdl by itself uses only bmp) (Mappy has MAP. and FMP. files is that used?)

Advertisement

SDL draws images. What you do with those images, and how you position them is up to you.

SDL can load PNG images using the SDL_image library (check out Lazy Foo's SDL tutorials - in this case, lesson 3).

Imagine you have several tile images - one (or more) for grass, and one for dirt and one for water.

Suppose you have the SDL_Surface pointers in an std::vector. We'll call this our image array.

Now, if you had another std::vector that was of size MAP_WIDTH * MAP_HEIGHT (we'll call this the map array), and had a bunch of ints in them, with each int representing the index in the image array, you can draw a map by iterating over the map array, getting the index of the tile image, and drawing the tile image at the correct cell of the map.


//Loop over every tile.
for( unsigned y = 0; y < MAP_WIDTH; ++y )
{
     for( unsigned y = 0; y < MAP_WIDTH; ++y )
     {
           //Convert a 2D index into a 1D index for lookups.
           unsigned mapIndex = (y * MAP_WIDTH) + x;
           
           //Get the index of the image to draw for this tile.
           unsigned imageIndex = mapArray[mapIndex];

           //Get the SDL_Surface to draw.
           SDL_Surface *tileImage = imageArray[imageIndex];

           //Calculate the location to draw this tile.
           int tileDrawX = (x * TILE_WIDTH);
           int tileDrawY = (y * TILE_HEIGHT);
           
           //Draw at the correct location, but offset by the camera.
           DrawImage(screen, tileImage, tileDrawX - cameraX, tileDrawY - cameraY);
     }
}

I'd strongly consider going through the tutorial I linked to (this is for the older version of SDL, not for SDL 2 - I don't know which you are using), I found it very helpful.

Maps are done any way you like. SDL isn't a game-engine, it's a low-level library.

You can make your map vector, tilemap, or something else. Whatever you want.

SDL is not a game engine and as such does not have any built in classes for managing tile maps like those found in Mario or Zelda.

I would suggest you do the following.

1. Create a class called Map, this should include some means of storing tile information. A very basic system is to initialise a dynamic 2D array of tile ints upon loading a map file. Each integer would represent a map tile, 0 for sky, 1 for grass etc.

2. You need to create a map file format. For now we are keeping things very simple, and whilst this approach is highly limited, you can modify it to suit your needs. Create a text file or any file, Personally I just remove the file extension as it is unimportant. An example map format could be the following...

width
height
tile x1,y1 x2,y1 xn,y1

tile x1,y2 x2,y2 xn,y2

tile x1,y3 x2,y3 xn,y3

4

3

0 0 0 0

0 0 0 0

1 1 0 1

.

using the '0' for sky '1' for grass approach, this represents a map that is mostly sky, with 2 small pieces of land at the bottom, similar to a side scrolling platformer.

3. Now that we have our map saved in a file, create a function that takes a string to the map directory as a parameter eg LoadMap(string _mapAddress) and load your map from file. Your class will need some getter functions so that other parts of your code, particularly your renderer can access tile information stored in your 2D array.

4. In your renderer, call the function in your map class to get the id of a tile. This will be called in a double for loop. Draw the tile in the correct position using the current indexes of the for loop multiplied by the width and height of the tile. If the value is 0, draw sky, if it is 1, draw land.

Happy coding :)

This topic is closed to new replies.

Advertisement