Tilemap
Since 0.6
Present on ctx.tilemap when the entity has a tilemap component: a grid of tiles in the entity's XY plane.
Cells are counted from (0, 0) at the top-left, x along the entity's +X and y down its -Y. A tile is its index on the sheet (0 up, row by row), or -1 for an empty cell. ts // Break the block the player head-butts, and open a door by clearing its column. const { x, y } = ctx.tilemap!.cellAt(hit.point) if (ctx.tilemap!.get("ground", x, y) === 3) ctx.tilemap!.set("ground", x, y, -1) for (let y = 4; y < 8; y++) ctx.tilemap!.set("ground", 12, y, ".")
Signature
export interface Tilemap {
/**
* The tile at column `x`, row `y` of `layer`, or -1 for an empty cell; a cell outside the layer
* reads as -1. A layer the tilemap does not have throws an `Error` whose `name` is
* `TilemapLayerError`; a coordinate that is not a whole number, a `RangeError`.
*/
get(layer: string, x: number, y: number): number
/**
* Sets the cell at column `x`, row `y` of `layer` to `tile`: a tile index (-1 empties it) or a
* legend character (`"."` empties it). Its chunk is redrawn next frame; on a `collision` layer
* the entity's body is rebuilt at once, so a cast straight after sees the change. Throws
* `TilemapLayerError` for a layer it does not have, `RangeError` for a cell outside the layer or
* a tile index not on the sheet, `TypeError` for a character not in the legend.
*/
set(layer: string, x: number, y: number, tile: number | string): void
/** The layers' names, in the component's order. */
readonly layers: string[]
/** A layer's size in cells. Throws `TilemapLayerError` for a layer it does not have. */
size(layer: string): { width: number; height: number }
/**
* The cell a world point is over, through the entity's transform (whole numbers; negative or
* past a layer's size when the point is off the map).
*/
cellAt(point: Vec3): { x: number; y: number }
/** The world point at the centre of cell (`x`, `y`), on the tilemap's plane. */
cellCenter(x: number, y: number): Vec3
}
Import: import type { Tilemap } from "@argus/api"
Members
| Member | Signature | Description |
|---|---|---|
get | get(layer: string, x: number, y: number): number | The tile at column x, row y of layer, or -1 for an empty cell; a cell outside the layer reads as -1. A layer the tilemap does not have throws an Error whose name is TilemapLayerError; a coordinate that is not a whole number, a RangeError. |
set | set(layer: string, x: number, y: number, tile: number | string): void | Sets the cell at column x, row y of layer to tile: a tile index (-1 empties it) or a legend character ("." empties it). Its chunk is redrawn next frame; on a collision layer the entity's body is rebuilt at once, so a cast straight after sees the change. Throws TilemapLayerError for a layer it does not have, RangeError for a cell outside the layer or a tile index not on the sheet, TypeError for a character not in the legend. |
layers | readonly layers: string[] | The layers' names, in the component's order. |
size | size(layer: string): { width: number; height: number } | A layer's size in cells. Throws TilemapLayerError for a layer it does not have. |
cellAt | cellAt(point: Vec3): { x: number; y: number } | The cell a world point is over, through the entity's transform (whole numbers; negative or past a layer's size when the point is off the map). |
cellCenter | cellCenter(x: number, y: number): Vec3 | The world point at the centre of cell (x, y), on the tilemap's plane. |
Example
The tested fixture fixtures/app/agent.ts.
import type { Behavior } from "@argus/api"
// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
init(ctx) {
ctx.state.arrived = false
ctx.nav?.goTo(ctx.props.target as [number, number, number])
},
update(ctx) {
if (ctx.nav?.arrived) ctx.state.arrived = true
},
} satisfies Behavior