Tilemap
A tile-grid node: one atlas texture sliced into cells and laid out on a uniform grid, drawn as one
node with view culling — the way to build a 2D level from tiles. It holds atlas indices as given;
for grass edges, roads and fences picked by rules, paint material ids with
Autotile2D; for a level in a .scene2d.ts file, use its
tilemap block. Extends Node2D (transform, hierarchy, layer).
- build a 2D level from a tilemap and a tile atlas
- lay out a level as rows of tile numbers in code
- change, add or clear one tile while the game runs
- place the map in the world
- turn or mirror a tile without editing the atlas
- add collision or animated tiles to a tile level
Platforms: iOS, Android, desktop, the web player and the le.codes viewer app; not on the web (Web Lite); headless tests build it but never draw it.
At a glance
async function main() {
const scene = new Scene2D()
const tiles = await Texture2D.load(asset('./tiles.png'))
const map = new Tilemap({
texture: tiles,
cols: 6, rows: 3, // map size in tiles
tile: 32, // each cell 32×32 world units
atlas: [8, 4], // the texture holds 8×4 tiles
data: [ // row 0 = TOP row; -1 = empty
-1, -1, -1, -1, 12, -1,
-1, 0, 1, 2, -1, -1,
8, 8, 8, 8, 8, 8,
],
})
map.position = [0, 0] // the map's BOTTOM-LEFT corner
scene.add(map)
scene.open()
}
main()Create a tile grid from an atlas: new Tilemap
new Tilemap(options: {
texture: Texture2D
cols: number // map width in tiles
rows: number // map height in tiles
tile: number | [w, h] // on-screen cell size in world units (number = square)
atlas: [atlasCols, atlasRows] // how the texture is sliced into tiles
data: number[] | Int32Array // row-major atlas indices, length cols*rows; -1 (any negative) = empty
})
map.cols, map.rows // readonlyThe grid is uploaded once; the texture comes from Texture2D.load.
Cell order and where the map sits
datais row-major with row 0 at the top of the map (reads like level text in source code), even though world Y points up.- Atlas indices also count row-major through the atlas grid: 0 is the atlas's top-left tile.
- The node's
positionis the map's bottom-left corner. - An index may carry a rotation / mirror (
rot90(12),flipX(12),packTile(12, turns, flip)) — the renderer turns that tile; see rotated tiles.
Change or clear one tile at runtime: setTile
map.setTile(x: number, y: number, index: number): this // grid coords as in data (row 0 = top)Sets one cell to an atlas index (-1 clears it). Cheap — the grid lives natively. Coordinates
outside the grid are ignored.
async function main() {
const scene = new Scene2D()
const tiles = await Texture2D.load(asset('./tiles.png'))
const map = new Tilemap({ texture: tiles, cols: 4, rows: 2, tile: 32, atlas: [8, 4],
data: [-1, -1, -1, -1, 8, 8, 8, 8] })
scene.add(map)
scene.open()
map.setTile(1, 0, 12) // put a crate (atlas tile 12) on the top row
map.setTile(2, 1, -1) // dig a hole in the ground row
map.setTile(3, 1, rot90(8)) // the same ground tile, turned a quarter clockwise
}
main()Remove a tilemap: destroy()
A Tilemap is not collected when you drop it: it lives until destroy() (its own, or an
ancestor's).
Collision and animated tiles (not provided)
The tilemap is a static uniform grid. Not provided (as of the current source):
- animated tiles — swap cells yourself with
setTileif needed - per-tile collision — build level collision separately, e.g. invisible
Node2Ds withShape2Dboxes/segments and staticPhysics2Dbodies
See also
- Node2D — transform, layer (inherited)
- Texture2D — loading the atlas
- Tilesets — autotile materials, oriented tile values
- Scene files — the
tilemapblock of a.scene2d.ts - 2D physics — static collision geometry for levels
- Scene2D — layers, Y-sort