go-tiled

repository·main·Indexed 42 days ago

https://github.com/lafriks/go-tiled

A Go library for parsing Tiled Map Editor (.tmx) files and rendering them into images. It is optimized for orthogonal finite maps and includes the tmx2img CLI tool for converting TMX files to PNG images. The library supports custom filesystems (such as embed.FS), TSX tileset loading, and provides structures for handling layers, groups, and hex colors.

Tokens
9.5K
Snippets
40
Records
51
Agent score
54%

What's inside go-tiled

  1. Install go-tiled

    main

    You can install go-tiled using the standard go get command. If you are using Go modules, you can also simply import the package in your code, and Go will download it during the first compilation.

    go get github.com/lafriks/go-tiled
  2. Use embedded filesystems with go-tiled

    main

    If your map assets are stored in a Go embed.FS, you must use the filesystem-aware initialization functions:

    1. For parsing the map: tiled.LoadFile(mapPath, tiled.WithFileSystem(yourFS)).
    2. For initializing the renderer: render.NewRendererWithFileSystem(tm, yourFS).
    // Assuming 'assets.Files' is an embed.FS
    tm, err := tiled.LoadFile(mapPath, tiled.WithFileSystem(assets.Files))
    ...
    r, err := render.NewRendererWithFileSystem(tm, assets.Files)
  3. Render a TMX map to an image

    main

    To render a map, follow these steps:

    1. Initialize a renderer using render.NewRenderer(gameMap).
    2. Render a specific layer using renderer.RenderLayer(layerIndex).
    3. Access the resulting image via renderer.Result (which is an image.NRGBA struct).
    4. Use renderer.Clear() if you need to reset the renderer for subsequent layer rendering.

    Note: Currently, the library only supports out-of-the-box rendering for orthogonal finite maps.

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/lafriks/go-tiled"
        "github.com/lafriks/go-tiled/render"
    )
    
    const mapPath = "maps/map.tmx"
    
    func main() {
        gameMap, err := tiled.LoadFile(mapPath)
        if err != nil {
            fmt.Printf("error parsing map: %s", err.Error())
            os.Exit(2)
        }
    
        renderer, err := render.NewRenderer(gameMap)
        if err != nil {
            fmt.Printf("map unsupported for rendering: %s", err.Error())
            os.Exit(2)
        }
    
        // Render layer 0
        err = renderer.RenderLayer(0)
        if err != nil {
            fmt.Printf("layer unsupported for rendering: %s", err.Error())
            os.Exit(2)
        }
    
        // Get the image.NRGBA result
        img := renderer.Result
    
        // Clear the result if you want to render another layer separately
        renderer.Clear()
    }
  4. Understand TilesetTile properties and metadata

    main

    A TilesetTile represents an individual tile within a tileset. Key fields include:

    • ID: The local tile ID within the tileset.
    • Class: The type of the tile (replaces the deprecated Type field).
    • X, Y, Width, Height: The sub-rectangle dimensions (if specified).
    • Terrain: A comma-separated string of terrain type indexes (top-left, top-right, bottom-left, bottom-right).
    • Probability: The chance (0.0 to 1.0) of this tile being chosen by terrain tools (defaults to 1).
    • Animation: A slice of AnimationFrame objects defining tile sequences.
  5. Use a custom FileSystem for loading resources

    main

    By default, go-tiled uses the local OS filesystem. You can provide a custom fs.FS (such as an embed.FS) using the WithFileSystem option. This is useful for embedding map and tileset assets directly into your Go binary.

    When using a custom filesystem, the loader will use fs.ToSlash to ensure path compatibility.

    // Example using an embedded filesystem
    import "embed"
    
    //go:embed assets/*
    var content embed.FS
    
    map, err := tiled.LoadFile("assets/map.tmx", tiled.WithFileSystem(content))
    if err != nil {
        // handle error
    }
  6. Parse a TMX map file

    main

    Use tiled.LoadFile(mapPath) to parse a Tiled Map Editor file (.tmx). This returns a map object and an error if the file cannot be parsed.

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/lafriks/go-tiled"
    )
    
    const mapPath = "maps/map.tmx"
    
    func main() {
        gameMap, err := tiled.LoadFile(mapPath)
        if err != nil {
            fmt.Printf("error parsing map: %s", err.Error())
            os.Exit(2)
        }
        fmt.Println(gameMap)
    }
  7. Handle ErrInvalidObjectPoint errors

    main
    The error ErrInvalidObjectPoint is returned when parsing the points attribute of a Polygon or PolyLine if the coordinate string is malformed (e.g., missing a comma or containing non-numeric values).
  8. Create a HexColor with NewHexColor

    main

    Use NewHexColor as a shorthand to manually construct a *HexColor using RGBA components. The components r, g, b, and a are passed as uint32 but are cast to uint8 internally.

    // Creates a color with R=255, G=0, B=0, A=255
    color := tiled.NewHexColor(255, 0, 0, 255)
  9. Use Data and DataTile for TMX tile layer information

    main

    The tiled package provides Data and DataTile types to represent tile layer data from TMX files.

    • Data: Represents the <data> element of a tile layer. It contains metadata about how the tile data is stored, including Encoding (e.g., "base64", "csv") and Compression (e.g., "gzip", "zlib").
    • DataTile: Represents an individual tile, containing a GID (Global ID).

    Depending on the Encoding used in the TMX file, the Data struct will be populated in one of two ways:

    1. Encoded Data: If Encoding is set to "base64" or "csv", the RawData field is populated with the raw bytes from the XML.
    2. XML Tile Elements: If Encoding is not set, the DataTiles slice is populated with individual DataTile objects parsed from <tile gid="N"/> elements.
    type Data struct {
    	Encoding    string     `xml:"encoding,attr"`    // e.g., "base64", "csv"
    	Compression string     `xml:"compression,attr"` // e.g., "gzip", "zlib"
    	RawData     []byte     `xml:",innerxml"`         // Populated if Encoding is "csv" or "base64"
    	DataTiles   []DataTile `xml:"tile"`              // Populated if Encoding is not set
    }
    
    type DataTile struct {
    	GID uint32 `xml:"gid,attr"` // The global tile ID
    }
  10. Load a TSX tileset from an io.Reader

    main

    Use LoadTilesetReader to load a TSX tileset from an io.Reader.

    Provide a baseDir string to locate relative paths to additional tileset data. If baseDir is empty, the current directory is used.

    // r is an io.Reader containing TSX data
    tileset, err := tiled.LoadTilesetReader("assets/tilesets", r)
    if err != nil {
        // handle error
    }
  11. Parse hex color strings with ParseHexColor

    main

    Use ParseHexColor to convert a hex color string into a *HexColor object.

    Important Format Note: This library uses the #AARRGGBB format (Alpha, Red, Green, Blue). This differs from standard CSS hex colors where Alpha is typically at the end.

    Supported formats:

    • #AARRGGBB (8 characters)
    • #RRGGBB (6 characters, Alpha defaults to 0xff)
    • #AARR (4 characters)
    • #RGB (3 characters, Alpha defaults to 0xff)

    The leading # character is optional.

    color, err := tiled.ParseHexColor("#FF00FF00") // Fully transparent red
    if err != nil {
        // handle error
    }
  12. Use Object to add custom data to tile maps

    main

    The Object type is used to define custom entities in a Tiled map, such as spawn points, collision areas, or triggers.

    Key properties include:

    • ID: Unique identifier.
    • Name: Arbitrary string name.
    • Class: The object class (replaces the deprecated Type).
    • X, Y, Width, Height, Rotation: Spatial properties.
    • GID: Reference to a tile (if the object is a tile).
    • Properties: Custom user-defined properties.
    • TemplateSource: Path to a Tiled template file used to instantiate the object.

    Objects can also contain geometric shapes like Ellipses, Polygons, PolyLines, or Text.