Skip to content

Tilemaps

Tilemaps allow you to render large tile-based environments efficiently using chunked rendering. The TileMap2D class handles maps with multiple layers and automatic chunking for performance.

Creating a Tilemap

import { TileMap2D, TiledLoader } from 'three-flatland';
// Load a Tiled map
const mapData = await TiledLoader.load('/maps/level1.json');
// Create tilemap
const tilemap = new TileMap2D({
data: mapData,
chunkSize: 16, // Tiles per chunk (default: 16)
});
scene.add(tilemap);
// In your animation loop
function animate() {
tilemap.update(deltaMs); // Update animated tiles
renderer.render(scene, camera);
}

Map Data Structure

The TileMapData interface describes the map format:

interface TileMapData {
width: number; // Map width in tiles
height: number; // Map height in tiles
tileWidth: number; // Tile width in pixels
tileHeight: number; // Tile height in pixels
orientation: 'orthogonal' | 'isometric' | 'staggered' | 'hexagonal';
renderOrder: 'right-down' | 'right-up' | 'left-down' | 'left-up';
infinite: boolean; // Infinite map flag
tilesets: TilesetData[];
tileLayers: TileLayerData[];
objectLayers: ObjectLayerData[];
properties?: Record<string, unknown>;
}

Loading Maps

Tiled Editor (.json/.tmj)

Load maps created with the Tiled Map Editor:

import { TileMap2D, TiledLoader } from 'three-flatland';
const mapData = await TiledLoader.load('/maps/level1.json');
const tilemap = new TileMap2D({ data: mapData });
scene.add(tilemap);

LDtk Editor (.ldtk)

Load maps created with LDtk:

import { TileMap2D, LDtkLoader } from 'three-flatland';
// Load a specific level by name
const mapData = await LDtkLoader.load('/maps/world.ldtk', 'Level_0');
const tilemap = new TileMap2D({ data: mapData });
scene.add(tilemap);
// List all levels in project
const levelIds = await LDtkLoader.getLevelIds('/maps/world.ldtk');

Working with Layers

Access and manipulate tile layers:

// Get layer by index
const groundLayer = tilemap.getLayerAt(0);
const wallsLayer = tilemap.getLayerAt(1);
// Toggle visibility
groundLayer.visible = false;
// Get layer count
console.log(tilemap.layerCount);

Tile Operations

Read and modify tiles at runtime:

// Get layer
const layer = tilemap.getLayerAt(0);
// Read tile at position
const tileGid = layer.getTileAt(x, y);
// Set tile at position
layer.setTileAt(x, y, newTileGid);

Coordinate Conversion

Convert between world and tile coordinates:

// World position to tile position
const tilePos = tilemap.worldToTile(worldX, worldY);
console.log(tilePos.x, tilePos.y);
// Tile position to world position
const worldPos = tilemap.tileToWorld(tileX, tileY);
console.log(worldPos.x, worldPos.y);

Statistics

Get information about the tilemap:

console.log('Total tiles:', tilemap.totalTileCount);
console.log('Total chunks:', tilemap.totalChunkCount);
console.log('Layer count:', tilemap.layerCount);

Chunked Rendering

Tilemaps use chunked rendering for performance. Configure the chunk size based on your needs:

const tilemap = new TileMap2D({
data: mapData,
chunkSize: 16, // 16x16 tiles per chunk (default)
});

Smaller chunks = more draw calls but finer culling. Larger chunks = fewer draw calls but coarser culling. The default of 16 works well for most cases.

Animated Tiles

Tiles with animation data (from Tiled) are automatically animated. Call update() each frame:

function animate() {
const deltaMs = /* time since last frame */;
tilemap.update(deltaMs);
renderer.render(scene, camera);
}

Disposing

Clean up resources when done:

scene.remove(tilemap);
tilemap.dispose();