Package github.com/matjam/bunyip/tiled
tiled
Package tiled reads maps saved by the Tiled editor and builds drawable levels from them. It decodes the JSON form (.tmj or .json maps, .tsj tilesets) and the XML form (.tmx maps, .tsx tilesets) into plain Go types. Parse distinguishes the forms by their first byte, and a map in one form may name an external tileset in the other. Parse and Load need no GPU. Build turns a Map into gfx tilemaps for drawing.
A Map has tile layers (CSV or base64 with zlib, gzip or zstd compression, flipped and rotated tiles), object layers (rectangles, ellipses, points, polygons and polylines with their names, types and custom properties, for spawn points, triggers and collision shapes), image layers and groups, and tilesets embedded or external with per-tile animations, collision shapes, properties and terrain sets from the terrain tool (a WangSet converts to grid/autotile rules with its Rules method, or RulesFor with the layout Map.Layout gives a hexagonal map). Build loads the tilesets' images, makes one gfx.Tilemap per tile layer with the animations wired up, and returns a Level whose Draw draws the layers in order on a rectangular grid. Parsing a map's orientation does not make Build render isometric or hexagonal layouts. Image layers and image-collection tilesets are parsed but not drawn by Build. Keep the object layers to place your own entities. Properties are typed (string, int, float, bool, colour, file, object) and read with the accessors on Properties.
Index
- Constants
- Variables
func ParseColor(s string) (color.RGBA, bool)func SplitGID(gid uint32) (id uint32, flipX, flipY, diagonal bool)- type Frame
- type Images
- type Layer
- type LayerKind
- type Level
- type LevelLayer
- type Map
func Load(name string) (*Map, error)func LoadFS(fs *asset.FS, name string) (*Map, error)func Parse(data []byte, resolve Resolver) (*Map, error)func (m *Map) FindLayer(name string) *Layerfunc (m *Map) Layout() autotile.Layoutfunc (m *Map) ObjectLayers() []*Layerfunc (m *Map) TileLayers() []*Layerfunc (m *Map) TileProperties(gid uint32) Propertiesfunc (m *Map) Tileset(gid uint32) (*Tileset, int)func (m *Map) WangSet(name string) (*Tileset, *WangSet)
- type Object
- type Properties
func (p Properties) Bool(name string) boolfunc (p Properties) Class(name string) Propertiesfunc (p Properties) Color(name string) color.RGBAfunc (p Properties) Float(name string) float64func (p Properties) Has(name string) boolfunc (p Properties) Int(name string) intfunc (p Properties) String(name string) string
- type Resolver
- type Tile
- type Tileset
- type WangColor
- type WangSet
- type WangSetTile
Constants
const (
FlipX uint32 = 0x80000000
FlipY uint32 = 0x40000000
FlipDiag uint32 = 0x20000000
)
Flip bits Tiled stores above the tile id in a global id.
Variables
var ErrUnsupported = errors.New("tiled: unsupported")
ErrUnsupported reports a map feature this package does not read, such as a layer encoding Tiled has added since.
Functions
ParseColor source
func ParseColor(s string) (color.RGBA, bool)
ParseColor reads Tiled's #AARRGGBB or #RRGGBB colour text.
SplitGID source
func SplitGID(gid uint32) (id uint32, flipX, flipY, diagonal bool)
SplitGID separates a global id into the tile id and its horizontal, vertical and diagonal flip bits for rectangular maps. It strips the hexagonal 120-degree rotation bit without returning it; callers drawing hexagonal maps must interpret rotation flags from the original gid.
Types
type Frame source
type Frame struct {
TileID int
Duration float32 // seconds
}
Frame is one step of a tile animation.
type Images source
type Images func(path string) (image.Image, error)
Images fetches a tileset or image layer picture by the path the map names, relative to the map's directory.
ImagesFrom source
func ImagesFrom(fs *asset.FS, dir string) Images
ImagesFrom reads images through an asset FS, with paths joined to the map's directory.
type Layer source
type Layer struct {
ID int
Name string
Kind LayerKind
Width, Height int // tile layers, in tiles
// StartX and StartY are the map coordinates of Data[0]; they are
// zero except for infinite maps, whose chunks are flattened into
// Data and may begin at negative coordinates.
StartX, StartY int
// Data holds one global id per cell, row-major, with Tiled's flip
// bits still set; zero is empty. SplitGID separates the parts.
Data []uint32
Objects []Object
Image string // image layers, relative to the map's directory
Layers []Layer
Visible bool // parser default true; inherited visibility is applied by Build
Opacity float32 // 0..1; parser default 1, multiplied through groups by Build
OffsetX float32 // pixels relative to the parent group
OffsetY float32 // pixels relative to the parent group
Properties Properties
}
Layer is one layer of a map. A tile layer holds Data; an object layer holds Objects; an image layer names an Image; a group holds Layers.
type Level source
type Level struct {
Map *Map
Layers []LevelLayer
// Sheets index Map.Tilesets; an image-collection tileset has none.
Sheets []*gfx.Sheet
// contains filtered or unexported fields
}
Level is a map uploaded for drawing: one tilemap per tileset a layer uses, in the map's layer order.
Build source
func Build(g *gfx.Graphics, m *Map, images Images) (*Level, error)
Build uploads a map's tileset images (nearest filtered, no mipmaps), fills tilemaps from its tile layers, and registers tile animations. Image layers and image-collection tilesets are not drawn. The Level owns the textures; Destroy frees them. Drawing uses a rectangular grid regardless of Map.Orientation; isometric and hexagonal layouts need a custom drawing path. Object layers are retained for the game to process. Infinite tile layers are flattened by Parse, but Build does not apply their StartX/StartY cell origin. Apply that origin in a custom drawing path when infinite-map chunks do not start at (0, 0).
Advance source
func (lv *Level) Advance(dt float64)
Advance moves every tile animation forward by dt seconds.
Draw source
func (lv *Level) Draw(g *gfx.Graphics, x, y float32, tint gfx.Color)
Draw draws every visible tile layer in order with the map's origin at (x, y). Layer opacity scales the tint's alpha.
type LevelLayer source
type LevelLayer struct {
Name string
Kind LayerKind
// Maps hold the layer's cells split by tileset, in first-use order
// in the layer's cell data; a cell belonging to another
// tileset is -1 in each.
Maps []*gfx.Tilemap
Objects []Object
Visible bool
Opacity float32
Offset lin.Vec2
}
LevelLayer is one tile or object layer with the group state above it applied: a layer inside a hidden group is hidden, offsets add, and opacities multiply.
type Map source
type Map struct {
Width, Height int // in tiles; the chunk bounds for infinite maps
TileWidth, TileHeight int // in pixels
// Orientation is "orthogonal", "isometric", "staggered" or
// "hexagonal".
Orientation string
// StaggerAxis is "x" or "y" on a hexagonal or staggered map: which
// axis the shifted rows or columns run along. It is empty otherwise.
StaggerAxis string
// StaggerIndex is "odd" or "even" on a hexagonal or staggered map:
// which rows or columns are shifted. It is empty otherwise.
StaggerIndex string
// HexSideLength is the length in pixels of the hexagon side that lies
// along the stagger axis. It is zero except on hexagonal maps.
HexSideLength int
BackgroundColor color.RGBA // zero when the map has none
Infinite bool
Layers []Layer
Tilesets []Tileset // sorted by FirstGID
Properties Properties
}
Map is one Tiled map: its grid, layers in draw order, and tilesets.
Load source
func Load(name string) (*Map, error)
Load reads a map in either form (.tmj or .json, .tmx), resolving external tilesets next to it.
LoadFS source
func LoadFS(fs *asset.FS, name string) (*Map, error)
LoadFS reads a map through an asset FS, resolving external tilesets relative to the map's directory.
Parse source
func Parse(data []byte, resolve Resolver) (*Map, error)
Parse decodes a map from memory, JSON or XML by its first byte. resolve may be nil when every tileset is embedded; an external tileset may be in either form whatever the map's. Paths in the result (tileset images, image layers) are relative to the map's directory, as the resolver's are.
FindLayer source
func (m *Map) FindLayer(name string) *Layer
FindLayer returns the first layer with the name at any depth, or nil.
Layout source
func (m *Map) Layout() autotile.Layout
Layout returns the autotile layout that matches the map's shape, for the Mapper that walks its cells and for WangSet.RulesFor. A hexagonal map gives the rows or columns layout its stagger axis and stagger index name. Every other orientation gives autotile.Square, isometric maps included: Tiled's terrain tool matches an isometric map on the plain grid neighbours, so a set painted there lines up with Square. A game whose isometric tiles are drawn by their direction on screen sets autotile.IsoDiamond on the Mapper itself.
ObjectLayers source
func (m *Map) ObjectLayers() []*Layer
ObjectLayers returns every object layer in order, descending into groups.
TileLayers source
func (m *Map) TileLayers() []*Layer
TileLayers returns every tile layer in draw order, descending into groups.
TileProperties source
func (m *Map) TileProperties(gid uint32) Properties
TileProperties returns the custom properties of the tile behind a global id, or nil when the tile has none.
type Object source
type Object struct {
ID int
Name string
Class string
X, Y float32
Width float32
Height float32
Rotation float32 // degrees, clockwise
GID uint32 // tile objects, with flip bits
Visible bool
Point bool
Ellipse bool
Polygon []lin.Vec2 // closed, relative to X and Y
Polyline []lin.Vec2 // open, relative to X and Y
Text string
// Properties are the object's custom properties.
Properties Properties
}
Object is a shape placed on an object layer or a tile's collision group. X and Y are pixels; a tile object (GID set) is anchored at its bottom-left, everything else at its top-left.
type Properties source
type Properties map[string]any
Properties are custom properties by name. Values are bool, int, float64, string, or Properties for class values; colours and files are strings.
Class source
func (p Properties) Class(name string) Properties
Class returns a nested class property, or nil.
Color source
func (p Properties) Color(name string) color.RGBA
Color returns a colour property, or zero.
Float source
func (p Properties) Float(name string) float64
Float returns a float property, or zero. Int values are converted.
type Resolver source
type Resolver func(path string) ([]byte, error)
Resolver fetches the bytes behind a path an external tileset names, relative to the map's directory.
type Tile source
type Tile struct {
ID int
Animation []Frame
Properties Properties
Collision []Object // from the tile's object group
Image string // image-collection tilesets
ImageWidth int
ImageHeight int
}
Tile is the extra data a tileset attaches to one of its tiles.
type Tileset source
type Tileset struct {
FirstGID uint32
Name string
Image string // relative to the map's directory
ImageWidth int
ImageHeight int
TileWidth, TileHeight int
Columns int
TileCount int
Margin, Spacing int
Tiles map[int]Tile // by local id; only tiles with extra data
WangSets []WangSet // terrain sets from the Tiled terrain tool
Properties Properties
}
Tileset is a grid of tiles cut from one image, or a collection of tile images when Image is empty.
ParseTileset source
func ParseTileset(data []byte) (*Tileset, error)
ParseTileset decodes a standalone tileset (.tsj or .json, .tsx) from memory. FirstGID is zero; paths stay relative to the tileset's own directory.
type WangColor source
type WangColor struct {
Name string
Color color.RGBA
Tile int // a representative tile id, or -1
Probability float64 // relative chance among variants; zero counts as 1
}
WangColor is one terrain colour of a set. Colours are numbered from 1 in WangSetTile.WangID, in the order they appear here.
type WangSet source
type WangSet struct {
Name string
// Type is "corner", "edge" or "mixed", saying which positions the
// set paints.
Type string
Colors []WangColor
Tiles []WangSetTile
}
WangSet is one terrain set of a tileset, as drawn in the Tiled editor's terrain tool: named colours and, for each participating tile, the colour at each of its eight positions.
Rules source
func (ws *WangSet) Rules() *autotile.Rules
Rules converts the set to autotile rules for a square grid, with tile ids as frames: a tileset cut with gfx.NewSheet uses them directly. A "corner" set matches corners, an "edge" set edges, anything else all eight positions. A tile's weight is the product of its colours' probabilities, so variants keep the balance set in the editor. It is RulesFor(autotile.Square); a hexagonal map wants RulesFor(m.Layout()).
RulesFor source
func (ws *WangSet) RulesFor(layout autotile.Layout) *autotile.Rules
RulesFor converts the set to autotile rules for a layout, which the map supplies through Map.Layout. On a hexagonal layout it moves each colour into the direction slot the layout uses: Tiled stores a hexagon's six sides in the eight-slot wangid one place back, so the slot the editor calls the top holds the north-east side of a rows hexagon. Give the same layout to the Mapper that applies the rules.
type WangSetTile source
type WangSetTile struct {
TileID int
WangID [8]int
}
WangSetTile gives one tile's colours, clockwise from north: N, NE, E, SE, S, SW, W, NW. Zero means the position has no colour.
Source files
bench_test.go fuzz_test.go level.go parse.go review_test.go tiled.go tiled_test.go wang.go xml.go xml_test.go zstd_test.go