{"id":775,"date":"2017-11-27T20:24:21","date_gmt":"2017-11-27T19:24:21","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=775"},"modified":"2017-11-27T20:24:21","modified_gmt":"2017-11-27T19:24:21","slug":"como-usa-libgdx-tiled-usando-con-varias-capas","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/como-usa-libgdx-tiled-usando-con-varias-capas\/","title":{"rendered":"C\u00f3mo usa libGDX + Tiled: usando con varias capas"},"content":{"rendered":"<p>En este art\u00edculo, tratar\u00e9 por qu\u00e9 y c\u00f3mo usar varias capas en nuestros dise\u00f1os de escenarios. Es un art\u00edculo un poco largo, as\u00ed que intentar\u00e9 explicarlo de forma ordenada para que queden claros los conceptos que quiero tratar. Para cualquier duda o sugerencia, pueden usar los comentarios e intentar\u00e9 ayudarles.<\/p>\n<h3>Introducci\u00f3n<\/h3>\n<p>En el ejemplo anterior vimos <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/como-usar-libgdx-tiled-dibujando-con-libgdx\/\">c\u00f3mo dibujar nuestro mapa con libGDX<\/a>. Lo cierto es que el escenario dibujado era simple; un mapa con una sola capa y un \u00fanico tileset. El ejemplo presenta un problema de cara a trabajar con el mapa. Veamos de nuevo la imagen para explicar en qu\u00e9 consiste:<\/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>Supongamos ahora que tenemos nuestro personaje principal caminando por la escena. Una de las cosas que habr\u00e1 que detectar son las colisiones con el escenario. Una aproximaci\u00f3n muy b\u00e1sica puede ser comprobar si la posici\u00f3n donde se encuentra el personaje est\u00e1 ocupada por un tile o est\u00e1 vac\u00eda. El problema es que en nuestro ejemplo, dibujamos en la misma capa elementos con los que s\u00ed se colisiona (suelo, agua) y otros elementos de decoraci\u00f3n con los que en principio no debe haber colisi\u00f3n (casa, arbustos). Por lo tanto si usamos este sistema para detectar colisiones, nuestro personaje colisionar\u00e1 tambi\u00e9n con los elementos de decoraci\u00f3n.<\/p>\n<p>Una soluci\u00f3n a este problema es separar los elementos de nuestro escenario en varias capas: tendremos una principal por donde se muevan nuestros personajes, y tantas como necesitemos para decorar y ambientar la escena.<\/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>Adem\u00e1s&#8230;<\/h4>\n<p>Hemos se\u00f1alado el problema de utilizar una sola capa a la hora de detectar las colisiones, pero esto no tiene por qu\u00e9 ser as\u00ed ya que podemos utilizar otros sistemas de detecci\u00f3n de colisiones que no dependan directamente del mapa del escenario (mapas de durezas, motor de f\u00edsicas, etc.). Sin embargo, otra ventaja que nos aporta el uso de varias capas es poder organizar mejor nuestros recursos o <em>assets<\/em>; ya que podemos tener tilesets de decoraci\u00f3n que podremos reutilizar en distintos mapas de nuestro juego, aunque el tileset principal del escenario cambie.<\/p>\n<p>A continuaci\u00f3n veremos c\u00f3mo usar varios tilesets y varias capas en un mapa de nuestro juego.<\/p>\n<p>&nbsp;<\/p>\n<h3>Usar varios tilesets<\/h3>\n<p>Para seguir avanzando en nuestro ejemplo, crearemos un segundo tileset, con tiles de 16&#215;16 p\u00edxeles en el que usaremos elementos para decorar la escena. En mi caso, he llamado a este archivo <strong><em>decoration.png<\/em><\/strong>, est\u00e1 guardado en la misma ruta donde se encuentra nuestro mapa, y contiene los siguientes tiles:<\/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>Modificar el mapa<\/h3>\n<p>A continuaci\u00f3n, haremos las siguientes modificaciones a nuestro mapa:<\/p>\n<ul>\n<li>Tendremos una primera capa, a la que llamaremos \u00ab<em>terrain<\/em>\u00ab, donde dejaremos s\u00f3lo las partes del escenario que afectar\u00e1n al movimiento de los personajes del juego: tierra y agua. Esta capa utiliza los tiles de <strong><em>tileset.png<\/em><\/strong>.<\/li>\n<li>En una segunda capa, llamada \u00ab<em>background<\/em>\u00ab, colocaremos la casa y los arbustos. Aqu\u00ed tambi\u00e9n se utiliza el tileset <strong><em>tileset.png<\/em><\/strong>.<\/li>\n<li>Habr\u00e1 una tercera capa, llamada \u00ab<em>decoration<\/em>\u00ab, en la que usaremos el nuevo tileset <strong><em>decoration.png<\/em><\/strong>, y en la que crearemos nubes y \u00e1rboles para decorar la escena.<\/li>\n<\/ul>\n<p>Este es el resultado de los cambios:<\/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>A tener en cuenta<\/h4>\n<p>Todas las capas utilizadas son \u00ab<em>Capas de patrones<\/em>\u00ab, que son las utilizadas para dibujar el escenario a partir de nuestros tilesets.<\/p>\n<p>Seg\u00fan nos indica la documentaci\u00f3n oficial de libGDX, podemos usar las capas que necesitemos, pero es importante que <strong>en una capa s\u00f3lo usemos tiles de un tileset<\/strong>. Esto es as\u00ed porque al dibujar una capa con m\u00e1s de una textura, se ve afectado negativamente el rendimiento al dibujar en pantalla.<\/p>\n<p>&nbsp;<\/p>\n<h3>Crear un nuevo proyecto<\/h3>\n<p>Para continuar con el ejemplo, podemos seguir sobre el proyecto del <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/como-usar-libgdx-tiled-dibujando-con-libgdx\/\">art\u00edculo anterior<\/a> o crear un nuevo proyecto. En mi caso, har\u00e9 una copia del proyecto anterior utilizando <a href=\"http:\/\/www.pixnbgames.com\/blog\/libgdx\/gdx-project-utils-0-0-1-es\/\">mi herramienta de clonado<\/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>Tratando capas en libGDX<\/h3>\n<p><em>libGDX<\/em> nos da funciones para tratar y dibujar el mapa completo, o hacerlo por capas.<\/p>\n<h4>Obtener capas<\/h4>\n<p>Para tratar las capas de un mapa, podemos hacerlo usando su nombre o su \u00edndice dentro de la lista de capas existentes. La clase que representa una capa de un mapa creado con <em>Tiled Map Editor<\/em> es <code>TiledMapTileLayer<\/code>. En este ejemplo veremos c\u00f3mo usar los dos m\u00e9todos.<\/p>\n<p>La capa de terreno (\u00ab<em>terrain<\/em>\u00ab) nos interesa tenerla de forma aislada en un objeto de la clase <code>TiledMapTileLayer<\/code>, ya que nos facilitar\u00e1 el trabajo en el futuro. Por otro lado, para el resto de capas usaremos un array de enteros llamado <code>decorationLayersIndices<\/code>, donde colocamos los \u00edndices de las capas \u00ab<em>decoration<\/em>\u00bb y \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>Cuando trabajamos con varias capas usando un array de \u00edndices, es importante el orden en el que se colocan los elementos. Esto es, <em>el orden del array de \u00edndices determina el orden en el que se dibujan las capas<\/em>. En nuestro caso, cuando dibujemos el array <code>decorationLayersIndices<\/code>, primero se dibujar\u00e1 la capa \u00ab<em>decoration<\/em>\u00bb y luego la capa \u00ab<em>background<\/em>\u00bb por encima de la primera.<\/p>\n<h4>Dibujar capas<\/h4>\n<p>El dibujado de capas, al igual que si dibuj\u00e1ramos el mapa completo, se hace con un objeto de la clase <code>OrthogonalTiledMapRenderer<\/code>. Veamos como ser\u00eda:<\/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>Importante<\/h4>\n<p>Si observamos el m\u00e9todo <code>render()<\/code> del ejemplo, vemos que existen diferencias entre dibujar una capa directamente o dibujarla mediantes sus \u00edndices. En el primer caso, es neceseario iniciar el batch de dibujo antes de dibujar las capas y finalizarlo al terminar.<\/p>\n<p>Por \u00faltimo, indicar que primero se dibujan las capas de decoraci\u00f3n y luego se dibuja la capa de terreno para que \u00e9ste \u00faltima quede \u00abpor encima\u00bb del resto.<\/p>\n<p>&nbsp;<\/p>\n<h3>C\u00f3digo fuente<\/h3>\n<p>Pod\u00e9is consultar el proyecto de ejemplo desde <a href=\"https:\/\/github.com\/angelnavarro\/Gdx-MyExamples\/tree\/master\/gdx-tiled-map-layers\" target=\"_blank\" rel=\"noopener\">mi respositorio de <em>GitHub<\/em><\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este art\u00edculo, tratar\u00e9 por qu\u00e9 y c\u00f3mo usar varias capas en nuestros dise\u00f1os de escenarios. Es un art\u00edculo un poco largo, as\u00ed que intentar\u00e9 explicarlo de forma ordenada para que queden claros los conceptos que quiero tratar. Para cualquier <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/como-usa-libgdx-tiled-usando-con-varias-capas\/\">Seguir leyendo <span class=\"screen-reader-text\">  C\u00f3mo usa libGDX + Tiled: usando con varias capas<\/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":[5],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/775"}],"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=775"}],"version-history":[{"count":14,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/775\/revisions"}],"predecessor-version":[{"id":812,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/775\/revisions\/812"}],"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=775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=775"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}