Tilemaps
Volver a la referencia

Tilemaps

Tile layers, their source atlas, and reading a tile back.

20 símbolos

blocksBulletsAtfunctionnacatamalon

blocksBulletsAt(map: TTilemap, column: number, row: number) => boolean

Whether anything in that cell stops a shot. Follows solid unless a tile says otherwise, which is what lets water stop a tank and not a bullet.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

Ver el código · gameobjects/tilemap/tile_queries.ts:166

cellAtfunctionnacatamalon

cellAt(map: TTilemap, x: number, y: number) => { column, row }

Which cell of the map a point of the world falls in.

It answers for points outside the map too, with numbers below zero or past the edge: "off the map to the left" is something a game needs to be able to tell, and clamping would say "the first column" instead. tileAt and solidAt treat those as empty.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

xnumber

A point in the world.

ynumber

A point in the world.

Ejemplo

declare const map: TTilemap;
declare const bullet: TSprite;

const { column, row } = cellAt(map, bullet.transform.x, bullet.transform.y);
Ver el código · gameobjects/tilemap/tile_queries.ts:34

cellCornerfunctionnacatamalon

cellCorner(map: TTilemap, column: number, row: number) => { x, y }

Where the top-left corner of a cell sits in the world, which is what a game needs to line something up with the grid.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

Ver el código · gameobjects/tilemap/tile_queries.ts:51

createTilemapfunctionnacatamalon

createTilemap(options: TTilemapOptions) => TTilemap

Loads a map and draws it: one call per layer, however many cells it has.

A layer's cells go up as one batch of corners, each one already in its place and carrying the piece of the sheet it shows. That is what makes one call possible: a sprite says "this picture, here", and a thousand cells showing thirty different pieces cannot be said that way. A sprite per cell would cost a place, a colour and a picture per tile, and stops being sensible somewhere around the first map that is not tiny.

What comes back is 'loading' and fills itself in; its layers start drawing once the file and its sheet have arrived, so nothing has to be awaited. useLoader counts it like any other asset.

Call it in the body of a scene, like everything else. What it draws goes away with that scene.

Parámetros

optionsTTilemapOptions

The .tilemap file, where it goes, and how it is drawn: see TTilemapOptions.

Ejemplo

export const Level: TSceneFn = () => {
    const map = createTilemap({ src: '/maps/level1.tilemap' });
    const player = createSprite({ key: 'hero', zIndex: 0 });

    useUpdate((delta) => {
        // The ground layer is drawn under the player and the treetops over them, because the
        // file says 'under' and 'over' and the player never mentioned a number at all.
        if (!solidAtPoint(map, player.transform.x + 8, player.transform.y)) {
            player.transform.x += 60 * delta;
        }
    });

    return createScene();
};
Ver el código · gameobjects/tilemap/create_tilemap.ts:124

getTilemapfunctionnacatamalon

getTilemap(box: TBox) => TTilemap | null

The map an object carries, from the moment the scene is built, or null when it has none.

A map from a scene file is drawn by its object, but its layers only join the object once the file has arrived, so looking for them among what it draws finds nothing while the scene is being built. This hands back the map itself straight away, still loading, the same one the object will draw: a behaviour keeps it and waits for status to be 'ready' before reading tiles from it. When an object has more than one map, it is the first.

Parámetros

boxTBox

The object to ask about.

Ejemplo

const world = (self: TGameObject) => {
    const map = getTilemap(self);

    useUpdate(() => {
        if (map?.status === 'ready' && solidAt(map, 4, 12)) {
            // ...
        }
    });
};
Ver el código · gameobjects/tilemap/get_tilemap.ts:49

markLayerChangedfunctionnacatamalon

markLayerChanged(layer: TTilemapLayer) => void

Tells the engine that a layer's cells were written directly, so its corners have to be built again.

setTile says this for you, and for one cell at a time it is what you want. This is the other case: writing a whole grid back in one go (restoring a level, loading a save) through data, where going through setTile would mean one call per cell for an answer you already have.

The rebuild happens on the next frame and once, however many times this is said, so saying it after every row costs nothing extra.

Parámetros

layerTTilemapLayer

The layer whose data was changed by hand.

Ejemplo

declare const layer: TTilemapLayer;
declare const original: number[];

for (let cell = 0; cell < original.length; cell++) layer.data[cell] = original[cell];
markLayerChanged(layer);
Ver el código · gameobjects/tilemap/tile_queries.ts:214

parseTilemapDocfunctionnacatamalon

parseTilemapDoc(value: unknown, src: string) => TTilemapDoc

Reads a .tilemap file and says what is wrong with it, naming the file.

It throws where the project parser forgives, and the difference is who is looking: a project file is settings, and a game with a silly window size should still run. A map is content, and a map with a layer half the size of its grid cannot be drawn at all. Better to fail here, while the author is looking at that file, than to read past the end of an array three layers down inside a mesh builder.

Parámetros

valueunknown

The file, as JSON.parse left it.

srcstring

Where the file came from, only so the message can say it.

Ver el código · loaders/tilemap/parse_tilemap_doc.ts:21

setTilefunctionnacatamalon

setTile(map: TTilemap, layer: number, column: number, row: number, id: number) => boolean

Puts an id into a cell, and says whether anything changed.

This is how a tile is destroyed: a cell is a number, so a brick turning to rubble is writing another number, and a brick disappearing is writing 0. The layer is drawn again on the next frame, once, however many cells were changed.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

layernumber

Which of its layers, counting from 0.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

idnumber

The tile to put there. 0 empties the cell.

Ejemplo

declare const map: TTilemap;
declare const column: number;
declare const row: number;

const tile = tileInfoAt(map, 0, column, row);
if (tile?.becomes !== undefined) setTile(map, 0, column, row, tile.becomes);
Ver el código · gameobjects/tilemap/tile_queries.ts:119

solidAtfunctionnacatamalon

solidAt(map: TTilemap, column: number, row: number) => boolean

Whether anything in that cell stops things moving, in any layer: a wall painted on the treetops layer still stops the player.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

Ver el código · gameobjects/tilemap/tile_queries.ts:151

solidAtPointfunctionnacatamalon

solidAtPoint(map: TTilemap, x: number, y: number) => boolean

Whether the point of the world falls on something solid. The short way to ask, for a game that only wants to know whether it can walk there.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

xnumber

A point in the world.

ynumber

A point in the world.

Ver el código · gameobjects/tilemap/tile_queries.ts:184

tileAtfunctionnacatamalon

tileAt(map: TTilemap, layer: number, column: number, row: number) => number

The id in a cell of one layer. 0 for empty, and also for anything outside the map.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

layernumber

Which layer, numbered as the file wrote them.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

Ver el código · gameobjects/tilemap/tile_queries.ts:69

tileInfoAtfunctionnacatamalon

tileInfoAt(map: TTilemap, layer: number, column: number, row: number) => TTileDoc | undefined

What the tile in a cell means, or nothing when the cell is empty or off the map.

Parámetros

mapTTilemap

The map, as createTilemap or getTilemap gave it back.

layernumber

Which of its layers, counting from 0.

columnnumber

The cell's column, counting from 0.

rownumber

The cell's row, counting from 0.

Ver el código · gameobjects/tilemap/tile_queries.ts:89

TTileDoctypenacatamalon

What one tile id means. The grid holds numbers; this is the table those numbers point into.

A tile has no place and no identity: two bricks are two appearances of the same number, not two things. Whatever needs identity (a chest, where the player starts) is a sprite instead. That is the line this draws, and it is why destroying a tile is writing a number into a cell rather than removing something.

Propiedades

frameopcionalnumber | string

Which frame of the sheet to draw: its place in the count, or its name on a packed sheet. Exactly one of this and anim is given.

animopcionalstring

The name of a run of frames in the sheet to cycle: water, a torch. Exactly one of this and frame is given. The run lives in the .atlas, so one description drives both this and a sprite's animation.

solidopcionalboolean

Stops things moving through it. Default false.

blocksBulletsopcionalboolean

Stops shots. Follows solid when it does not say, which is right for nearly every tile: water is the exception that earns the field its place, solid to a tank and not to a bullet.

becomesopcionalnumber

What this tile turns into when it is destroyed, 0 for "nothing left".

Absent means it cannot be destroyed, which is a different thing from turning into nothing, and that is why it has no default.

Ver el código · loaders/tilemap/types/t_tilemap_doc.ts:25

TTileLayerOrdertypenacatamalon

TTileLayerOrder: 'under' | 'over' | number

Where a layer draws, next to everything else in the scene.

'under' and 'over' mean under and over the characters, and they turn into reserved numbers either side of zero. That step is the point: a map is drawn without knowing what numbers a game gives its sprites, and a sprite that never mentions one is already at zero, so a map saying "under" and "over" is right in any scene with nobody having agreed on a number first.

A plain number still works, because "above the characters but below the treetops" is a real thing to want and only a number can say it.

Ver el código · loaders/tilemap/types/t_tilemap_doc.ts:70

TTilemaptypenacatamalon

A map: the sheet its numbers point into, how big its cells are, what the numbers mean, and its layers.

It comes back straight away, empty and 'loading', and fills itself in when the file and its sheet arrive. Nothing has to be awaited, and useLoader counts it like any other asset.

Propiedades

type'tilemapAsset'
srcstring

Where the file is.

transformTTransform2d

Where the map's top-left corner sits. Shared by every layer: they sort apart, they do not move apart.

atlasTLoadedAtlas | null

The sheet, loaded with the map. null until the file has said which one.

cellnumber

How big a cell is, in pixels. 0 until it has loaded.

widthnumber

How many cells across and down. 0 until it has loaded.

heightnumber
tilesRecord<number, TTileDoc>

What each id means.

layersTTilemapLayer[]

Its layers, in the order the file wrote them.

tintTColor

Multiplies the colour of every layer.

smoothopcionalboolean

How the sheet is read. Left out, the game's own setting decides.

clocksMap<string, { elapsed, frame }>

Where each cycling tile is in its run, by the name of the run.

destroyedboolean

Set by destroy and never cleared.

Ver el código · gameobjects/tilemap/types/t_tilemap.ts:113

TTilemapDoctypenacatamalon

What a .tilemap file holds: which sheet, how big the cells and the grid are, what the numbers mean, and the layers.

The table of tiles is inside the map rather than in a file of its own. One file less to keep in step while a first level is being built, and the id is already what ties a number in the grid to what it means. When several levels need to share a table it comes back as an optional field replacing tiles: something added to a format that already reads, not a rewrite.

Propiedades

formatnumber
kind'tilemap'
atlasstring

Where the .atlas is whose frames the ids draw, relative to this file.

cellnumber

How big a cell is, in pixels. Square: a cell that is not is a different problem.

widthnumber

How many cells across.

heightnumber

How many cells down.

tilesRecord<number, TTileDoc>

Id to what it means. 0 is always empty and is never written here.

Ver el código · loaders/tilemap/types/t_tilemap_doc.ts:131

TTilemapLayertypenacatamalon

One layer of a map, and the thing the renderer actually draws.

A layer and not the map, because the order things are drawn in is per drawable and a layer's whole purpose is to sort on its own: the ground under the player, the treetops over them, both from one map. Making the map one drawable would have meant teaching the sorter about an order inside an order, when the one it has already does the job.

Its cells are split across two batches. The still one holds every cell whose tile shows a fixed picture, and is built once. The moving one holds the cells whose tile cycles, and only their corners are rewritten when the cycle turns. That split is what keeps a map with water cheap: a few dozen cells go up again four times a second while the several thousand still ones sit there.

Those two batches are not here. They are handles to memory on a device, and this is a record: plain data, and all of it writable to a file. They live in a side table instead, keyed by the layer, which is the same arrangement a particle emitter's pool uses. See layer_state.ts.

Propiedades

type'tilemap'
idstring
namestring
mapTTilemap

The map this belongs to, so a layer on its own is still enough to find everything.

transformTTransform2d

Where the map's top-left corner sits: the map's own placement, by reference, not a copy. Moving the map moves every layer, because they are all looking at the same object.

worldTransformopcionalTTransform2d

Where it ends up once everything above it has moved it, worked out once a frame while the tree is walked. Left off when nothing above it has a placement of its own, which is the ordinary case: then its own transform is already where it is.

Set by the engine every frame and never authored or saved. Ask worldOf rather than reading either field by hand.

textureTTexture | null

The sheet its cells take their pictures from: the map's, by reference.

tintTColor

Multiplies the colour of the layer: the map's, by reference.

smoothopcionalboolean

How the sheet is read. Left out, the game's own setting decides.

visibleopcionalboolean

Whether this layer is drawn. Omitted is drawn.

Per layer and not per map, for the same reason a layer is the drawable at all: "hide the treetops" is the useful sentence, and hiding every layer is that sentence repeated.

It keeps its corners on the graphics card, so showing it again costs nothing. Letting go of them is what destroying the map does.

datanumber[]

The ids of its cells, row by row. 0 is empty.

orderTTileLayerOrder

Where it draws. Read as zIndex by the same sort every drawable goes through.

zIndexnumber

Which number it sorts by. Worked out from order when the map loads, and kept on the layer because that is the field the renderer reads for everything else too.

destroyedboolean

Set by destroy and never cleared.

materialopcionalTSpriteMaterial

An effect of its own, from createMaterial. Omitted is the built-in shader.

Per layer and not per map, because that is the useful grain: a water layer ripples while the ground under it does not. It takes the same hook a sprite's material takes, so one effect can be written once and put on either.

uniformsopcionalTUniformValues

This layer's own values for that material's knobs, laid over the material's own.

Ver el código · gameobjects/tilemap/types/t_tilemap.ts:27

TTilemapLayerDoctypenacatamalon

One layer of the map: a flat grid of tile ids, row by row, and where it draws.

The order lives here and never on a tile: the same brick can be background in one layer and foreground in another.

Propiedades

namestring
orderTTileLayerOrder

Where it draws. Default 0, which is where the characters are.

datanumber[]

width × height ids, row by row from the top-left. 0 is empty.

Ver el código · loaders/tilemap/types/t_tilemap_doc.ts:106

TTilemapOptionstypenacatamalon

What createTilemap is asked for.

Propiedades

srcstring

Where the .tilemap file is.

keyopcionalstring

What to cache it under, so two scenes share one map. Defaults to src.

transformopcionalPartial<TTransform2d>

Where the map's top-left corner sits. What is left out takes its default (scale 1, no turn).

tintopcionalTColor

Multiplies the colour of every layer. Default white.

smoothopcionalboolean

Overrides the game's smooth for this map.

Ver el código · gameobjects/tilemap/types/t_tilemap.ts:171