September 23rd, 2008
Creating your WorldBeginner Game Tutorials, by nazeeh.
Today I want to talk to you about one of the important subjects of game development. Creating your world. Your game lives in some world (usually), how you design and build that world is something you want to think about early on regardless if it’s a 2D or 3D game. Since we’re still learning, let’s focus on 2D first. This will be a mini series of posts that will walk you through creating a 2D world, the tools you can use and how we can code it up in our game. We’ll even touch on some semi-advanced features of XNA Game Studio such as custom content pipeline extensions. Don’t be scared now! It really sounds way scarier than it actually is. So let’s get started!
So what is a 2D world?
In a 2D game, a world is really the map you’re playing on. Let’s have a look at some examples:
Here’s a classical screenshot of Super Mario Bros. You can see that the world is the sky, pipes, clouds, bricks, etc that Mario is running around in.
Here’s another one. This is from Zelda, a game that is so popular that people think I am wasting their oxygen because I never played it or got into it :/
How are such worlds created? Well… that’s the easy part :)
Creating a 2D world
These worlds are created using a technique a lot of us learned at childhood: Tiles! Yep… that’s all they are. The world is composed of a set of tiles that are arranged on a grid to give the final look. So to create a world like the one in the Mario screenshot above, you need a tile that is totally blue in color for the sky, one that looks like bricks for the ground, etc. You then just lay them next to each other to create the world you want. Load that up in the game and there you go! You got a world! Easy eh?
I’ll explain a bit more! I’ll create two tiles now, one for a sky and another for green ground:
Simple and so not pretty, but will have to do. To create a world that has a sky and a green ground, I can just tile the green ones next to each other to form the ground, then the blue ones to form the sky:
See? A perfectly ugly world but a world nonetheless! All by having only two tiles and just placing them on a grid (this one is a 10×10 grid by the way). So to create such a world in code, you would load up those two textures and then using a loop, position them next to each other in the order required to show your world. We’ll get to the code later though.
So how do you design such a world anyway? Surely you didn’t think I would suggest that you would do it via code! You need a designer! I’ve done some research and found a really cool tool that you can use to create such worlds very easily! The tool is called Tile Studio. It’s open source and free and works really well.
Let’s dive right in and see how we can use it to create my ugly world above, shall we?
Launch up the app! You should be presented with this window:
The first thing you want to do is create a couple of tiles that you can use to draw your world with. Right off the bat, the application will be in tile edit mode and you have a new tile ready to be created right there. So I’ll create a blue tile first:
Pick the Flood Fill tool
then pick the color you want to use from the color picker on the right. Then click on the gray tile in the middle of the editor to fill it with that color. Mine looks like this:
Now we do the same thing but for a ground tile which will be green. But first we add a new tile by hitting Ctrl+N (or via the menu Tile->Add New Tile). You’ll get another Gray blank tile to work with. Pick the green color and fill it in.
If you look at the bottom left corner of the editor, you should see all the tiles you have created at the moment lined up next to each other in a horizontal strip:
Cool! We got ourselves two tiles to work with. Now let’s create a world! To do that, you need to create a new map. Click on the New Map button on the toolbar:
When you click on it, you’ll get the New Map window asking you what size should the map be in tiles:
I gave it a name, Level1, and set it to be 10 by 10 tiles large. I wouldn’t worry too much about the size now, you can add rows/columns later easily. This is what the map editor looks like:
A nice blank map for us to use! To draw on it, you just click on one of the tiles at the bottom left corner of the editor and click anywhere on the map to place that tile there. I started with the ground:
and then did the same with the sky to get to the final world:
Awesome! We created a world!! Take a few moments to enjoy that fact before you realize “oh…now what?! how do I get this in my game!”. Don’t sweat it… I got you covered!
Exporting the Map
Up to this point, figuring out how to use this editor was a piece of cake! Getting to know how to export the world though, that took some time. But I am here to save you the hassle. Usually the way tile maps are exported is in the form of a number array. Let me explain.
First thing you would do is give indices to the tiles in your tile strip. The tile strip that will be generated by our example looks like this:
So the first tile would be index 0 and the next one index 1.
Then the map itself is just an 10×10 array of integers that shows where each tile is placed. Would look roughly like this:
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
This makes it easy to use code to loop through the array, and draw the correct tile by referencing the index. So how do we generate something like this for our map?
I expected tile studio to generate something like this automatically, but turns out that they wanted to be very flexible so instead, they gave you a Tile Definition Language (TSD) that you can use to tell Tile Studio how to format the output. Long story short, I wrote a small script in TSD to output a map in XML for easy parsing :)
Download the script from here (xml.tsd).
Take the file you just downloaded and copy it in the folder that contains the TS.exe (Tile studio application’s folder).
Now go back to Tile studio and let’s export the map:
- First we save the project by clicking File->Save. Save it in a folder of its own.
- Click on Code-Code Generation Settings
- Pick the xml option for the list as shown (that’s the TSD file we just copied there). Then hit Ok.
- Make sure that the output is going to be generated in the project’s folder:
- Now you’re ready to generate the code! Hit F10 or do it through the above menu.
Tada! Map data generated! Go look in your project’s folder, mine looks like this:
As you can see, we have a file called Tiles1.xml and a folder called Content which has one image in it called Tiles1.bmp which is a vertical image strip of all the tiles you have.
Let’s take a quick look at the Tiles1.xml file that was created:
See what it looks like? Just some simple XML that defines every tile on the map by it’s X and Y positions and which tile it uses. First <MapTile> node for instance has the first tile at position X=0 and Y=0 and uses TileNumber=1.
Note: TileNumber is not Zero based! That means tile number 1 is TileNumber 1. So in my code, when I load this data, I subtract 1 from the value of TileNumber so that it’s zero based which makes life easier. There was no way to have it export this data in Zero based format I am afraid.
Also note that the root element of the map (<map>) includes all the data you need to properly render this map. You have the Width and Height of the grid in tiles, the width and height in pixels of the tiles and the name of the tilestrip file in the Content folder.
Ignore the MapCode attribute for the moment, we’ll get to that later :)
There! We now have a map all drawn up and ready to be consumed by our code! That… will be the topic of my next post! This one was long enough as it is. In the meantime, go mess around with the editor!Thanks for reading! I'd love to hear your thoughts, feel free to leave a comment below. Don't forget to subscribe to my RSS Feed!