Blitz2D Newbies: Basic Map File Loading & Scrolling
by Krylar

UPDATE!

I have updated this article to include more dynamic tile/map loading. Also the Map_ShowMap function now can be called with more specific detail, including the specific map cells to begin drawing from. This means you can do scrolling and such. Look at the example file downloads to see it in action.

Introduction:

There've been a lot of people asking about how to go about loading a map from a file. The primary reason is because most all 2D side-scrollers or tile-games use some type of map to display the appropriate tiles at appropriate locations.

The method described here is just one of many, and it is a simple method. But it should be good enough to get you started. After seeing how this works, I would recommend that you expand upon this and make it much more robust.

Loading Tiles

Before doing anything with the map, we need to have something to display. Generally folks put a bunch of fixed-sized tiles (though they can be varied in size if your code permits) in a single image file. Sometimes all of the tiles run together, such as shown here:

Other times, the artist puts a block around each image to keep them visibly seperated, shown here:

This is an important distinction because you don't want to end up loading the blocks with the images, you just want the actual images. Because of this, you'll not only need to know how tall and wide each image is, but also how much space is between each of your images.

For example, let's say that you have images that are 32x32. That is they are 32 pixels wide by 32 pixels high. And let's say that you've put a 2x2 box around each image. When you go to use the GrabImage function in BB, you'll not want to grab from 0,0 (the top left of the image), rather you'll want to grab from the inside-top-left edge of the box at 2,2. See below for an example:

In an effort to make this entire process easier on the caller, I've set up a group of functions for a map loading/displaying library. I named it "maplib.bb". You can call it whatever you want.

At the very top of the map library, I have set a number of global variables and arrays. Here they are:


Next I put together a function that will call all of the loading functions, clear any old arrays/types, and re-dimension new ones based on map information. Here is the code:


We will have to load the actual image tiles each time a new map is loaded. There are a number of arguments that the caller must send to the Map_LoadTiles(...) function. They specify the following:

  • The Filename that the tiles are in (the image file), including the full path.
  • The Width, in pixels, of each tile
  • The Height, in pixels, of each tile
  • The offset (for boxes around the images) from the X, or horizontal, perspective...in pixels
  • The offset (for boxes around the images) from the Y, or verticle, perspective...in pixels
  • The total number of columns of tiles to be loaded in from each row
  • The total number of rows of tiles to be loaded in from the file

Now, the following source is fully commented so study it carefully!


There is a lot to that function, but if you go over it a few times it should become clear how it works.

Map File Format

There are many ways to layout a map file. Some folks use numbers seperated by spaces or commas, others use various methods of encryption, some just go straight across with the numbers and parse appropriately. Additionally, some map generators and files take into consideration Z-Ordering. That is, the level on which a tile sits when compared to other tiles. (For more information on Z-Ordering, please refer to the BlitzBasic Intermediates: Z-Ordering article.

For ease of understanding, I've decided to go with numbers seperated by commas.

The first line of my map file will have two numbers: The Width, or columns on the map, and the Height, or rows on the map. Immediately following that will be the appropriate number of rows of data mixed with the appropriate number of columns. Here is an example:


This map basically says that there are 3 columns and 2 rows. The first row contains 3 images and they are: Image 10, Image 1, and Image 5. The second row's images are: Image 4, Image 15, and Image 6. If you recall, when we loaded in the Tiles each tile was assigned a place in the array. So, when we go to call DrawImage we can pass the Tile(ImageNumber) and it will display the appropriate tile!

Loading Map Dimensions

In order to load this data in, we must first determine the number of elements we'll need to store within our MapData array. In order to make this easier on the caller, I have created two functions to handle reading in the map data. The first is called Map_ReadDimensions(...) and it's sole purpose is to open a map data file, read in the first line, and parse that line so it knows how many columns and rows are in the map.

Take a look at the function and study the comments closely:


Now you may consider this overkill for just determining the Cols,Rows...and, frankly, you may be right. But my goal is to make it brain-dead simple for the person calling these functions to use the map and the function, so I don't mind overkill in my code.

Loading the Map Data

The second function is called Map_ReadData(...) and it's job is to take the information it knows for the number of columns and rows (which it gets from Map_ReadDimensions(...)) and load in all of the image numbers into the MapData array. Again, study this carefully:


Showing a Loaded Map

After calling this function you should have all the data loaded into your MapData Array of Type. Now it's just a matter of calling the Map_ShowMap(...) function. This function simply runs through the MapData Array Type, grabs the image number to show, and then calls BB's DrawImage function with the TileList Array Type's image for that image number. Here's the code:


By changing the values in MapColumnStart and MapRowStart you can scroll the map.

Calling the Functions

From the caller's perspective, this library simple to use. Just call that Map_LoadMap function with the appropriate arguments and you're set for loading. Then call Map_ShowMap with the appropriate arguments to display. If you need to change maps, just call Map_LoadMap again and it will clear out the old images and map data and load in the new.

The caller just needs to create a map file in the format described above, draw up some tiles, setup the TileList and MapData Types, and then put the Map function callers in at some point where they want to show the map. Here's an idea of it:


Conclusion

Hopefully this tutorial will give you some insight on a very simple map file. I also hope that you'll expand on this method and go for a much more heavyweight version!

You can grab a lame little demo of this and all the source code: Click Here. Note that the tiles used are from Ari Feldman's SpriteLib. Ari no longer makes this available on the web, but he has a book out that has these tiles on the CD. His site is: http://www.arifeldman.com.

Until next time...cya!

-Krylar


For a printable copy of this article, please click HERE.


This site is Copyright© 2000-2004, BlitzCoder. All rights reserved.