Tile maps – mapping all over the world!

When platformers first started appearing, on the early game consoles, they took a tile approach to their levels. Levels were split up into cells, and then each cell would be assigned an ID that would correspond to a tile in perhaps a texture atlas—ooh, we know about them! This had the great benefit of reducing the memory footprint, because you could build an entire level from just a handful of tiles, and that is exactly what we are going to do.

Introducing Tiled

When we build our level out of tiles, we are going to need a tool to help us visualize the level as we go ahead. You could go and do it all by hand, drawing it on paper, noting IDs and cells, and then updating a text file somewhere; however, that will be slow and cumbersome—take it from someone who used to do that!

So what can we use? Well, I have always been fond of a free-to-use tool called Tiled (for more information, visit http://www.mapeditor.org/). It has an amazing feature set, multiple layers, and stamping collections of tiles to help with larger levels. We won't be using all these features. The aim here is to get you used to using a tool like this, and then you can spread your wings and dive deep into what it can do when it comes to your own game!

Once you have downloaded Tiled, open it up and we will begin!

Creating a new map

Go to the File drop-down menu and select New as an option. You will then be presented with a New Map dialog, such as follows:

Creating a new map

The first section talks about how our map is going to be saved and presented. We can keep the same settings as shown in the preceding screenshot. We want our orientation as Orthogonal as we are working on a 2D game. The format, while at this stage, isn't really that important, but having the map saved in a compressed format is fine. Finally, in this section, we need the render order to be Right Down, as this is how LibGDX will handle reading and rendering the map.

The next two sections cover the map properties. Our art work is 16x16px tiles and our world is 640x480, so we can set it up with the preceding settings.

Finally, save the project. I have called mine pete.tmx and I have saved it into our assets directory in our core project.

Hopefully, your screen should look like mine.

Creating a new map

Our next step is to add our tile texture atlas to the tile layer, so that we can start creating a level.

To do this, we need to go to the Map file option and select the New Tileset menu option. From here, we can import our texture atlas that represents our tile set.

Our texture we are using is called floor.png and here is how it looks.

Creating a new map

Essentially, we have 18 tiles at a size of 16x16 pixels.

If the tilesets windows don't appear after you import the asset, you can enable it by going to the View option, clicking on the Views and ToolBars option, and then selecting tilesets.

Finally, we can build our level. If you have a play around with Tiled, you will find it is quite straightforward to create a level. You select the tile you wish to use and then click where on the screen you want it.

In the following screenshot, you can see the level I created. Going forward, I will be using this in the game.

Creating a new map

Just save the tile map and we are ready.

Great! Now that we have our level, we just need to load it into LibGDX!

The LibGDX Tile Map API

Now that we have our lovely TMX file created by Tiled, we need to load it in LibGDX so that we can render it. We are going to do this using our AssetManager object, as it will do the heavy lifting for us. However, it doesn't support the TMX file out of the box, so we need to tell it how to load the TMX file.

To tell the AssetManager object how to load the TMX file, we assign a loader to class type. In this case, our class we want to have once loaded is TiledMap and the loader is the TmxMapLoader class. For those interested, visit the wiki page for Tile Maps in LibGDX, at https://github.com/libgdx/libgdx/wiki/Tile-maps.

Adding the loader is straightforward in the create() method of our PeteGame class. Update it so it looks like the following code:

public void create() {
  assetManager.setLoader(TiledMap.class, new TmxMapLoader(new InternalFileHandleResolver()));
  setScreen(new LoadingScreen(this));
}

Here we are just instructing the asset manager that if we want to load an object of type TiledMap, then use the TmxMapLoader class.

Next, we need to update our LoadingScreen class to load the tile map. Update the show() method as follows:

public void show() {
  //Code omitted for brevity
  peteGame.getAssetManager().load("pete.tmx", TiledMap.class);
}

The final step to loading our map is to grab it from the asset manager, so that it is ready to render. To do this, we need to create a reference to the TiledMap class in the GameScreen class as follows:

private TiledMap tiledMap;

Then, in our show() method, let's call the AssetManager object to get our object:

public void show() {
  //Code omitted for brevity
  tiledMap = peteGame.getAssetManager().get("pete.tmx");
}

Excellent. If you run the project now, you will still find we will have a blank screen; this is because we are not rendering the map yet! To do this, we need to use the OrthogonalTiledMapRenderer class.

So, in our GameScreen class, let's add our OrthogonalTiledMapRenderer class:

private OrthogonalTiledMapRenderer orthogonalTiledMapRenderer;
public void show() {
  camera = new OrthographicCamera();
  viewport = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, camera);
  viewport.apply(true);
  shapeRenderer = new ShapeRenderer();
  batch = new SpriteBatch();
  tiledMap = peteGame.getAssetManager().get("pete.tmx");
  orthogonalTiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, batch);
  orthogonalTiledMapRenderer.setView(camera);
}

So in the preceding code, we have added our renderer. We then construct it with the tile map that we loaded, and we pass in the SpriteBatch instance. Finally, we set up the view by passing in the camera. We have also changed how our camera is centered, by calling apply(true) on our viewport.

Finally, we just call the render() method in our draw() method as follows:

private void draw() {
  batch.setProjectionMatrix(camera.projection);
  batch.setTransformMatrix(camera.view);
  orthogonalTiledMapRenderer.render();
}

As you type out the preceding code, you will find that the renderer has a few different options for rendering the map. By default, we are telling it to render all the layers that exist in the map, currently one. However, when you start to do more complex maps, you might have many layers, and you might wish to render only certain layers or render them in specific order. You may, hopefully, have also noticed that we don't call begin() or end() on the SpriteBatch object. This is because it is done for us in the tile map renderer object! Pretty neat hey?

Excellent. If you run the project, you should get the level that you created appearing on the screen.

The LibGDX Tile Map API
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset