Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make use of TiledMapObjects' templates #5102

Open
andrejp88 opened this issue Feb 20, 2018 · 5 comments
Open

Make use of TiledMapObjects' templates #5102

andrejp88 opened this issue Feb 20, 2018 · 5 comments

Comments

@andrejp88
Copy link
Contributor

andrejp88 commented Feb 20, 2018

Tiled 1.1 adds support for object templates. A template is saved as an external file, and you can place templates in your tilemap similar to how you place tiles from a tileset.

In the saved XML, the path to the template file is stored as an attribute of the object element.

Suppose I placed a template object and renamed it. The corresponding XML would look like this:

<object id="6" template="../just/an/example.tx" name="Custom Name" x="168" y="483">

As you can see, many of the usual attributes (such as width, height, and type) are missing. In Tiled, I can still see these properties because it's reading them from the template file.

I think the libgdx implementation would involve BaseTmxMapLoader.loadObject() getting the template attribute, loading the .tx file it points to, and filling out the missing properties using that template.

As for the .tx file itself, its structure looks pretty simple:

<?xml version="1.0" encoding="UTF-8"?>
<template>
 <object name="Default name" type="Example" height="48">
  <properties>
   <property name="some custom property" value="test"/>
  </properties>
 </object>
</template>

So it's saved the same way objects are saved in .tmx files.

I can work around this limitation by detaching objects from their templates in my tile map, but it would be nice to be able to take full advantage of the Template functionality in Tiled.

@xGnoSiSx
Copy link

Agree but this falls under keeping the lib updated with the new versions of the tools that were already adopted.

@chertel
Copy link

chertel commented Nov 4, 2018

Any updates on this?

@thomasjahoda
Copy link

thomasjahoda commented Jul 9, 2019

As workaround, the Tiled map editor provides export options to detach objects from the templates.
This can be integrated in the project build life-cycle to generate the LibGDX-compatible maps automatically using the CLI.

Example command to export the map via the 'Tiled' editor CLI:
tiled --export-map --detach-templates src/main/tiledmaps/test1.tmx src/main/resources/maps/test1.tmx
The first map file is the source, the second one is the target.
The target file does not reference the template file anymore and has all properties from the template.

Example Gradle task to export all maps on-demand (written in Kotlin Gradle DSL):

task("exportMaps") {
    val inputDir = "$projectDir/src/main/tiledmaps"
    val outputDir = "$projectDir/src/main/resources/maps"
    inputs.dir(inputDir)
    outputs.dir(outputDir)
    doLast {
        logger.info("Exporting 'Tiled' maps from directory $inputDir to $outputDir")
        val tmxFiles = file(inputDir).listFiles { dir, name -> name.endsWith(".tmx") }
        @Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
        tmxFiles.forEach {
            logger.info("Exporting ${it.name}")
            exec {
                val outputFile = file(outputDir).absolutePath + "/" + it.name
                commandLine = listOf("tiled", "--export-map", "--detach-templates", it.absolutePath, outputFile)
            }
        }
    }
}
tasks.clean {
    delete(fileTree("$projectDir/src/main/resources/maps") {
        exclude(".gitignore")
    })
}
tasks.processResources {
    dependsOn("exportMaps")
}

For reference, read https://www.mapeditor.org/2018/09/18/tiled-1-2-0-released.html for Info on the detach-preferences. Search for:

For this reason several Export Options were added to the Preferences:

However... implementing actual object template support into the classes should not be much effort. I just didn't wanna fork it and use a custom libgdx version for my project while I wait for a pull request to be accepted and the next libgdx version to be released.

thomasjahoda added a commit to thomasjahoda/physics-puzzle-platformer that referenced this issue Jul 9, 2019
@perrauo
Copy link

perrauo commented Mar 4, 2020

Hi, I am making an educational resource using LibGDX, having the template functionality working without exporting with the template detached would help a lot.

@TrueFuFLeaderG
Copy link

I had the same issue and an easy workaround was to extend the TmxMapLoader like this


import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.maps.ImageResolver;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.utils.XmlReader;

public class TemplateTmxMapLoader extends TmxMapLoader {

    FileHandle tmxFile;
    @Override
    protected TiledMap loadTiledMap (FileHandle tmxFile, TmxMapLoader.Parameters parameter, ImageResolver imageResolver){
          this.tmxFile = tmxFile;
          return super.loadTiledMap(tmxFile,parameter,imageResolver);
    }
    @Override
    protected void loadObject (TiledMap map, MapObjects objects, XmlReader.Element element, float heightInPixels) {
        if (element.getName().equals("object")) {

            if(!element.hasAttribute("template"))
            {
                super.loadObject(map,objects,element,heightInPixels);
                return;
            }
            FileHandle template= getRelativeFileHandle(tmxFile,element.getAttribute("template"));
            XmlReader.Element el = xml.parse(template);
            for(XmlReader.Element obj:el.getChildrenByName("object"))
            {
                    obj.setAttribute("x",element.getAttribute("x"));
                    obj.setAttribute("y",element.getAttribute("y"));
                    obj.setAttribute("id",element.getAttribute("id"));
                    super.loadObject(map,objects,obj,heightInPixels);
                    return;
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants