TileGrid

fun IsometricScope.TileGrid(width: Int, height: Int, config: TileGridConfig = TileGridConfig(), onTileClick: (TileCoordinate) -> Unit? = null, content: @Composable IsometricScope.(TileCoordinate) -> Unit)

Renders an isometric tile grid and routes tap events to tile coordinates.

Tiles are arranged in a width × height grid. Each tile is rendered by the content lambda, which receives the TileCoordinate of the tile being drawn. Content is rendered in the coordinate space of the tile — a Shape with the default position renders at the tile's world origin without any additional positioning.

When onTileClick is provided, taps on the scene are automatically converted from screen coordinates to tile coordinates. Only taps within the grid bounds invoke the callback. No GestureConfig on the enclosing IsometricScene is required — gesture handling is enabled automatically.

IsometricScene(modifier = Modifier.fillMaxSize()) {
TileGrid(
width = 10,
height = 10,
onTileClick = { coord -> selectedTile = coord }
) { coord ->
Shape(
geometry = Prism(),
color = if (coord == selectedTile) IsoColor.BLUE else IsoColor.GRAY
)
}
}

Elevation and tap accuracy: onTileClick assumes a flat ground plane (z = 0) for hit-testing. For elevated terrain, tap routing may miss tiles whose visual surface is above z = 0. Use the escape hatch: configure GestureConfig.onTap on the scene and call IsometricEngine.screenToTile with the appropriate elevation using LocalIsometricEngine.

Parameters

width

Number of tile columns (must be ≥ 1)

height

Number of tile rows (must be ≥ 1)

config

Grid configuration: tile size, world origin, optional elevation function. Defaults to a 1-unit flat grid at world origin.

onTileClick

Called when the user taps a tile within this grid's bounds. Null by default (no tap handling).

content

Composable lambda for each tile. Receives the tile's TileCoordinate. Rendered in the tile's local coordinate space — the tile origin is at (0, 0, 0) relative to the group.

See also