{"id":821,"date":"2017-11-30T20:45:56","date_gmt":"2017-11-30T19:45:56","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=821"},"modified":"2017-11-30T20:45:56","modified_gmt":"2017-11-30T19:45:56","slug":"how-to-use-libgdx-tiled-several-layers","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-use-libgdx-tiled-several-layers\/","title":{"rendered":"How to use libGDX + Tiled: several layers"},"content":{"rendered":"<p>I will explain in this post why and how to use several layers on our maps. It&#8217;s a bit long post, so I will try to organize concepts in a clear way. If you have any doubt or suggestion, use the comments please and I will try to help you.<\/p>\n<h3>Introduction<\/h3>\n<p>On the previous article we see <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-use-libgdx-tiled-drawing-with-libgdx\/\">how to draw our map with <em>libGDX<\/em><\/a>. That case is very simple: a map with a single layer and a single tileset. It has a problem in order to work with it. See the image again to explain what the problem consists of:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-751\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-22-a-las-23.20.38-1024x612.png\" alt=\"\" width=\"530\" height=\"317\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-22-a-las-23.20.38-1024x612.png 1024w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-22-a-las-23.20.38-300x179.png 300w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-22-a-las-23.20.38-768x459.png 768w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-22-a-las-23.20.38.png 1288w\" sizes=\"(max-width: 530px) 100vw, 530px\" \/><\/p>\n<p>Now supose the main character is walking on the scene. One of the things we have to do is to detect collides with the scene. A simple approach to do it could be to check whether the position the character is occupied by a tile or it&#8217;s empty. The problem of doing it with our example is that we have in the same layer the elements which the character would collide with (ground, water), and other decoration elements which wouldn&#8217;t collide with character (bush, house). So if we use this approach to detect collisions, the character will also collide with the decoration elements.<\/p>\n<p>A solution to the posed issue is to split our scene in several layers: a main layer with the colliding elements, and as much layers as needed to decorate the scene.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-811 size-full\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/map_layers.png\" alt=\"\" width=\"482\" height=\"322\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/map_layers.png 482w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/map_layers-300x200.png 300w\" sizes=\"(max-width: 482px) 100vw, 482px\" \/><\/p>\n<h4>Furthermore&#8230;<\/h4>\n<p>I have pointed the collision detection as the problem of using a single layer, but this has not be like this, because we can use another collision system (hardness map, physics engine, &#8230;). Nevertheless, other advantage we get using several layers better organization of our project resources or <em>assets<\/em>. We can have decoration tileset that we can use on several maps, although the main tileset of the scene changes, for example.<\/p>\n<p>Next we will see how to use several layers and tilesets in our game scene maps.<\/p>\n<p>&nbsp;<\/p>\n<h3>Several tilesets<\/h3>\n<p>To continue with the example, I will create a second tileset, with tiles of 16&#215;16 pixels, where I will draw som aditional decoration elements. This file is called <strong><em>decoration.png<\/em><\/strong>, and it&#8217;s stored on the same path of the map. This is the <em>decoration.png<\/em> tileset:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-786\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/background.png\" alt=\"\" width=\"128\" height=\"128\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Modifying map<\/h3>\n<p>Next, we make the following changes on the map <em>level.tmx<\/em>:<\/p>\n<ul>\n<li>We have a first layer, called \u00ab<em>terrain<\/em>\u00ab, where are only the part of scenes which the characters collide with: ground and water. This layer uses the tileset <strong><em>tileset.png<\/em><\/strong>.<\/li>\n<li>In a second layer, called \u00ab<em>background<\/em>\u00ab, we set the house and bushes. This layer also uses the tileset <strong><em>tileset.png<\/em><\/strong>.<\/li>\n<li>At last, a third layer, called \u00ab<em>decoration<\/em>\u00ab, where we use the tileset <strong><em>decoration.png<\/em><\/strong>, and which contains some clouds and trees to decorate the scene.<\/li>\n<\/ul>\n<p>This is the result after modifications:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-791\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-26-a-las-22.14.15-1024x531.png\" alt=\"\" width=\"530\" height=\"275\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-26-a-las-22.14.15-1024x531.png 1024w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-26-a-las-22.14.15-300x156.png 300w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-26-a-las-22.14.15-768x398.png 768w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/Captura-de-pantalla-2017-11-26-a-las-22.14.15.png 1596w\" sizes=\"(max-width: 530px) 100vw, 530px\" \/><\/p>\n<h4>Keep in mind<\/h4>\n<p>All used layers are \u00ab<em>Tile layers<\/em>\u00ab, that allows us to draw the scene from the tilesets.<\/p>\n<p>As <em>libGDX<\/em> official doc says, we can use many layers as we need, but <strong>on each layer we only use one tileset<\/strong>. If not, the drawing performance will decrease a lot.<\/p>\n<p>&nbsp;<\/p>\n<h3>Crate a new project<\/h3>\n<p>To follow with the example, you can use the project we create on <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-use-libgdx-tiled-drawing-with-libgdx\/\">the previous article<\/a> or you can create a new project. In my caso, I will clone the project using <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/gdx-project-utils-0-0-1-en\/\">my cloning tool<\/a>:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-793\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/clonar-proyecto-1024x465.png\" alt=\"\" width=\"530\" height=\"241\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/clonar-proyecto-1024x465.png 1024w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/clonar-proyecto-300x136.png 300w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/clonar-proyecto-768x348.png 768w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2017\/11\/clonar-proyecto.png 1252w\" sizes=\"(max-width: 530px) 100vw, 530px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Handling layers in libGDX<\/h3>\n<p><em>libGDX<\/em> give us functions to handle and draw whole maps, and also to do it for one or more isolated layers.<\/p>\n<h4>Getting layers<\/h4>\n<p>To get the layers of a map, we can use its name or its index of the layers list (first index is 0). The class that represents a layer created with <em>Tiled Map Editor<\/em> is <code>TiledMapTileLayer<\/code>. In this example we will use these two methods.<\/p>\n<p>The layer which contains the ground (\u00ab<em>terrain<\/em>\u00ab) will be stored in an <code>TiledMapTileLayer<\/code> object, because this will be usefull to work with it in the future. On the other hand, for the rest of layers we use an array of integers called <code>decorationLayersIndices<\/code>, where we set the indices of the layers \u00ab<em>decoration<\/em>\u00bb and \u00ab<em>background<\/em>\u00ab.<\/p>\n<pre lang=\"Java\">...\r\npublic class MyGdxTiledGame extends ApplicationAdapter {\r\n    ...\r\n    private TiledMap map;\r\n    private TiledMapTileLayer terrainLayer;\r\n    private int[] decorationLayersIndices;\r\n    ...\r\n    @Override\r\n    public void create () {\r\n        ...\r\n        \/\/ Reading map layers\r\n        MapLayers mapLayers = map.getLayers();\r\n        terrainLayer = (TiledMapTileLayer) mapLayers.get(\"terrain\");\r\n        decorationLayersIndices = new int[] {\r\n                mapLayers.getIndex(\"decoration\"),\r\n                mapLayers.getIndex(\"background\")\r\n        };\r\n        ...\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>When working with layer&#8217;s indices, the order of the elements in the array matters. This is, <em>the order in the array establishes the drawing order of the layers<\/em>. In this caso, when the array <code>decorationLayersIndices<\/code> is drawed, first is drawed the \u00ab<em>decoration<\/em>\u00bb layer and then the \u00ab<em>background<\/em>\u00bb layer over the first one.<\/p>\n<h4>Drawing layers<\/h4>\n<p>Layers drawing, same to map drawing, is made with an object of the class <code>OrthogonalTiledMapRenderer<\/code>. See how to do it<\/p>\n<pre lang=\"Java\">public class MyGdxTiledGame extends ApplicationAdapter {\r\n    ...\r\n    private OrthogonalTiledMapRenderer renderer;\r\n    ...\r\n    @Override\r\n    public void create () {\r\n        ...\r\n        \/\/ Instantiation of the render for the map object\r\n        renderer = new OrthogonalTiledMapRenderer(map);\r\n    }\r\n\r\n    @Override\r\n    public void render () {\r\n        \/\/ Clear screen\r\n        Gdx.gl.glClearColor(.5f, .7f, .9f, 1);\r\n        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);\r\n\r\n        \/\/ Update the camera\r\n        camera.update();\r\n        renderer.setView(camera);\r\n        \r\n        \/\/ Rendering\r\n        renderer.render(decorationLayersIndices);\r\n        renderer.getBatch().begin();\r\n        renderer.renderTileLayer(terrainLayer);\r\n        renderer.getBatch().end();\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<h4>Important<\/h4>\n<p>Seeing the method <code>render()<\/code> of the example, we can see differences between draw a <code>TiledMapTileLayer<\/code> object and draw layer using its indices. In case of the <code>TiledMapTileLayer<\/code> object its needed to start the drawing batch before to draw, and end the batch at finish drawing.<\/p>\n<p>At last, say that decoration layers are drawed before terrain layer so that the terrain layer is over the decoration.<\/p>\n<p>&nbsp;<\/p>\n<h3>Source code<\/h3>\n<p>You can get the example project from <a href=\"https:\/\/github.com\/angelnavarro\/Gdx-MyExamples\/tree\/master\/gdx-tiled-map-layers\" target=\"_blank\" rel=\"noopener\">my <em>GitHub<\/em> repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I will explain in this post why and how to use several layers on our maps. It&#8217;s a bit long post, so I will try to organize concepts in a clear way. If you have any doubt or suggestion, use <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-use-libgdx-tiled-several-layers\/\">Seguir leyendo <span class=\"screen-reader-text\">  How to use libGDX + Tiled: several layers<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":811,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[15,55],"language":[4],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/821"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=821"}],"version-history":[{"count":3,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/821\/revisions"}],"predecessor-version":[{"id":824,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/821\/revisions\/824"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media\/811"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=821"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}