@@ -5,7 +5,7 @@ title: Tilemaps
55
66# Tilemaps
77
8- Tilemaps let you paint 2D levels quickly using a tileset (a grid of sprites).
8+ Tilemaps let you paint 2D levels quickly using a tileset (a grid of sprites) or colored-square tiles .
99A ** Tilemap** entity is a regular entity, so you can move, scale, parent,
1010and duplicate it like anything else.
1111
@@ -30,7 +30,6 @@ and duplicate it like anything else.
3030
3131Need procedural generation or an in-game brush?
3232Just cast your entity as a Tilemap and call its helper methods.
33-
3433``` ts
3534import { Behavior , Rng , syncedValue , Tilemap } from " @dreamlab/engine" ;
3635
@@ -47,10 +46,9 @@ export default class Generate extends Behavior {
4746 seed: number = 0 ;
4847
4948 /** Grass‑only palette IDs. */
50- static readonly #GRASS = [1 ,2 , 3 , 8 , 9 , 10 ,11 ,16 ,17 ,18 ,19 ,24 ,25 ,26 ,27 ] as const ;
49+ static readonly #GRASS = [1 , 2 , 3 , 8 , 9 , 10 , 11 , 16 , 17 , 18 , 19 , 24 , 25 , 26 , 27 ] as const ;
5150 /** Flower‑only palette IDs. */
52- static readonly #FLOWER = [4 ,5 ,6 ,7 ,12 ,13 ,14 ,20 ,21 ,22 ,23 ,28 ,29 ,30 ,31 ] as const ;
53-
51+ static readonly #FLOWER = [4 , 5 , 6 , 7 , 12 , 13 , 14 , 20 , 21 , 22 , 23 , 28 , 29 , 30 , 31 ] as const ;
5452
5553 /** Deterministic RNG tied to `seed`. */
5654 #prng! : () => number ;
@@ -64,9 +62,9 @@ export default class Generate extends Behavior {
6462 const roll = this .#prng (); // 0 … 1
6563 if (roll < 0.05 ) return 0 ; // empty
6664 if (roll < 0.8 ) { // grass
67- return sampleArray (Generate .#GRASS_TILES , this .#prng );
65+ return sampleArray (Generate .#GRASS , this .#prng );
6866 }
69- return sampleArray (Generate .#FLOWER_TILES , this .#prng );
67+ return sampleArray (Generate .#FLOWER , this .#prng );
7068 }
7169
7270 clearData(): void {
@@ -102,48 +100,80 @@ export default class Generate extends Behavior {
102100 const right = this .inputs .getKey (" MouseRight" );
103101 if (! left && ! right ) return ;
104102
105- const tile = this .#tilemap .getTileAtPoint (world );
103+ const tile = this .#tilemap .getTileCoordinatesAtPoint (world );
106104 if (! tile ) return ;
107105
108106 const id = left ? 33 /* hard‑coded brush */ : this .#getTile ();
109107 this .#tilemap .setTile (tile .x , tile .y , id );
110108 }
111109}
112110```
113-
114111---
115112
116- ## Core API
113+ ## Example — Colored Square Tilemap
117114
118- | Method | Purpose |
119- | ------------------------------------------| -------------------------------------------------------------|
120- | ` getTile(x, y) ` | Returns ` TileData ` \| ` undefined ` for that coordinate. |
121- | ` getTilePaletteId(x, y) ` | Returns palette index (` number ` ) or ` undefined ` . |
122- | ` setTile(x, y, paletteId?) ` | Sets tile; pass ` undefined ` to erase. |
123- | ` getTileAtPoint(worldPos) ` | Ray-casts the cursor; returns ` { x, y, …tile } ` or ` undefined ` . |
124- | ` clearTiles() ` | Removes every tile from the map. |
125- | ` tiles() ` | Generator that yields ` { x, y, tile } ` for each filled cell.|
126- | ` bounds ` * (getter)* | ` { width, height, offset } ` in tile units. |
115+ If you want a simple colored checkerboard pattern instead of an atlas,
116+ you can set per-tile colors:
117+ ``` ts
118+ import { Behavior , Tilemap } from " @dreamlab/engine" ;
127119
128- ### ` TileData ` union
120+ export default class Checkerboard extends Behavior {
121+ #tm = this .entity .cast (Tilemap );
122+
123+ static readonly WHITE = 0xffffff ;
124+ static readonly GREY = 0xcccccc ;
125+ static readonly N = 256 ;
126+
127+ #fill(): void {
128+ this .#tm .clearTiles ();
129+ for (let y = 0 ; y < Checkerboard .N ; y ++ ) {
130+ for (let x = 0 ; x < Checkerboard .N ; x ++ ) {
131+ const color = ((x + y ) & 1 ) === 0 ? Checkerboard .WHITE : Checkerboard .GREY ;
132+ this .#tm .setColor (x , y , color );
133+ }
134+ }
135+ }
136+
137+ onInitialize(): void {
138+ if (this .game .isServer ()) this .#fill ();
139+ }
140+ }
141+ ```
142+ ---
143+
144+ ## Core API
129145
146+ | Method | Purpose |
147+ | -----------------------------------------------| ---------|
148+ | ` getTile(x, y) ` | Get atlas tile ID at ` (x, y) ` , or ` undefined ` . |
149+ | ` setTile(x, y, atlasId?) ` | Set atlas tile ID; pass ` undefined ` to erase. |
150+ | ` setTiles(xs[], ys[], atlasIds[]) ` | Set multiple atlas tiles at once. |
151+ | ` getColor(x, y) ` | Get solid color at ` (x, y) ` , or ` undefined ` . |
152+ | ` setColor(x, y, color?) ` | Set solid color; pass ` undefined ` to erase. |
153+ | ` getTileInfo(x, y) ` | Get ` TileInfo ` (either ` { type: "atlas", id } ` or ` { type: "color", color } ` ). |
154+ | ` setTileInfo(x, y, info?) ` | Set a full ` TileInfo ` object. |
155+ | ` getTileCoordinatesAtPoint(worldPos) ` | Convert world coordinates to tile ` (x, y) ` . |
156+ | ` clearTile(x, y) ` | Remove any tile (atlas or color) at ` (x, y) ` . |
157+ | ` clearTiles() ` | Remove all tiles. |
158+ | ` tiles() ` | Iterate all filled tiles. |
159+ | ` bounds ` * (getter)* | ` { width, height, offset } ` in tile units. |
160+
161+ ### ` TileInfo ` union
130162``` ts
131- type TileData =
132- | { type: " color" ; color: string ; alpha? : number }
133- | { type: " texture" ; texture: string }
134- | { type: " spritesheet" ; spritesheet: string ; frame: number }
135- | { type: " texture-slice" ; texture: string ; x: number ; y: number };
163+ type TileInfo =
164+ | { type: " atlas" ; id: number }
165+ | { type: " color" ; color: number };
136166```
137167
138168---
139169
140170### FAQ
141171
142172** How big can a tilemap be?**
143- Technically unlimited, but performance is tuned for ≤ 10 000 drawn tiles.
173+ Technically unlimited, but performance is optimized for ≤ 20 million drawn tiles (similar to large Terraria worlds) .
144174
145175** Can I swap atlases at runtime?**
146- Yes — just assign a new path to ** Atlas** ; all visuals update automatically.
176+ Yes — assign a new path to ** Atlas** ; visuals update automatically.
147177
148178** How do I force pixel-perfect textures?**
149- Set ** Scale filter mode** to “ nearest” on the Tilemap * or* on the Camera.
179+ Set ** Scale filter mode** to " nearest" on the Tilemap * or* Camera.
0 commit comments