···20202121NPM is the most common way to install Excalibur
2222```sh
2323-npm install excalibur@latest`
2323+npm install excalibur@latest
2424```
25252626But there are several ways you can start from scratch with Excalibur
+98-6
site/docs/08-tile-maps/07-isometricmap.mdx
···44section: TileMaps
55---
6677-Excalibur can produce isometric style tile maps! Isometric tilemaps, also known as 2.5D, provide a way to draw maps from a simulated 45 degree camera view.
77+Excalibur can produce isometric style tile maps! Isometric tilemaps, also known as 2.5D, provide a way to draw maps from
88+a simulated 45 degree camera view.
99+1010+Excalibur has a [Tiled plugin](https://github.com/excaliburjs/excalibur-tiled) to automatically create tilemaps from
1111+isometric maps created in the popular [Tiled](https://www.mapeditor.org/) editor. We generally recommend using the
1212+plugin, however, read on to understand how isometric tilemaps function in Excalibur.
813914
1015···14191520## Isometric Map Usage
16211717-Use the excalibur type [[IsometricMap]] for drawing isometric grids! (They also support custom colliders via the same mechanism as `ex.TileMap`)
2222+Use the Excalibur [[IsometricMap]] class for drawing isometric grids! (They also support custom colliders via the same mechanism as `ex.TileMap`)
18231924```typescript
2025const game = new ex.Engine({...});
···2328 pos: ex.vec(250, 10),
2429 tileWidth: 32,
2530 tileHeight: 16,
2626- columns: 15,
2727- rows: 15
3131+ columns: 5,
3232+ rows: 5
2833});
29343035game.currentScene.add(isoMap);
···35403641The [[IsometricEntitySystem]] generates a new z-index based on the `elevation` and [[y position|TransformComponent]] of an entity with [[IsometricEntityComponent]].
37424343+The 5x5 IsometricMap map from the above example snippet will contain 25 `IsometricTile`'s. These are accessible via the `tiles` property on the `IsometricMap` instance. e.g. `isoMap.tiles`. The IsometricMap represents a single layer in an isometric scene.
4444+4545+At this stage the `IsometricTile`'s do not have graphics attached, so they are invisible to the human eye. But the `IsometricMap` that has been added to the scene can be thought of as:
4646+4747+
4848+3849## Selecting an appropriate Tile Height
39504051When defining the `tileHeight` there are a few considerations you should make relative to your asset. Usually the `tileHeight` is half your graphics total height. With other art assets the `tileHeight` can be different, in this case roughly half the height of the asset. This height will depend on your art assets.
···70817182## Adding Graphics to IsometricTiles
72837373-Graphics can be added to an [[IsometricTile]], graphics are drawn differently from other parts of excalibur. They are drawn from the bottom left, this is done to help preserve the illusion of placing tiles on top of a grid.
8484+Graphics can be added to an [[IsometricTile]]. Graphics are drawn differently from other parts of Excalibur, they are drawn from the bottom left, this is done to help preserve the illusion of placing tiles on top of a grid.
74857575-
8686+
76877788```typescript
7889const isoMap = new ex.IsometricMap({...});
···95106 renderFromTopOfGraphic: true;
96107});
97108```
109109+110110+## Working with depth and elevation
111111+112112+As noted above, an `IsometricMap` represents a single layer in an isometric scene. To add some depth to a scene we can "stack" multiple `IsometricMap`'s, adjusting the `elevation` and `y` of each subsequent `IsometricMap`. This will give the desired effect of tiles appearing on top of another.
113113+114114+For more advanced maps, with multiple layers, we recommend using the [Tiled plugin](https://github.com/excaliburjs/excalibur-tiled) which handles the complexity automatically.
115115+116116+```typescript
117117+export class MyLevel extends Scene {
118118+ private layers = [
119119+ [ // Floor
120120+ [0, 0, 1, 1, 0],
121121+ [3, 3, 3, 3, 3],
122122+ [3, 3, 3, 3, 3],
123123+ [3, 3, 3, 3, 3],
124124+ [3, 3, 3, 3, 3],
125125+ ],
126126+ [ // Wall layer 1
127127+ [1, 0, 0, 0, 0],
128128+ [1, 1, 0, 0, 1],
129129+ [1, 2, 0, 0, 2],
130130+ [1, 0, 0, 0, 0],
131131+ [1, 0, 0, 0, 0],
132132+ ],
133133+ [ // Wall layer 2
134134+ [0, 0, 0, 0, 0],
135135+ [1, 1, 0, 0, 1],
136136+ [1, 0, 0, 0, 0],
137137+ [1, 0, 0, 0, 0],
138138+ [1, 0, 0, 0, 0],
139139+ ],
140140+ ];
141141+142142+ override onInitialize(): void {
143143+ const image = SpriteSheet.fromImageSource({
144144+ image: Resources.Tiles,
145145+ grid: {
146146+ rows: 3,
147147+ columns: 6,
148148+ spriteWidth: 32,
149149+ spriteHeight: 32,
150150+ },
151151+ });
152152+153153+ this.layers.forEach((layer, index) => {
154154+ const isoMap = new IsometricMap({
155155+ pos: vec(300, 184 + index * -16),
156156+ tileWidth: 32,
157157+ tileHeight: 16,
158158+ columns: layer.length,
159159+ rows: layer[0].length,
160160+ elevation: index,
161161+ });
162162+163163+ this.add(isoMap);
164164+165165+ // This is a primitive approach of manually assigning a tile based
166166+ // on the input data. In reality, you will probably use more
167167+ // advanced techniques such as using information contained in a
168168+ // Tiled map file
169169+ //
170170+ isoMap.tiles.forEach((tile) => {
171171+ if (layer[tile.y][tile.x] === 1) {
172172+ tile.addGraphic(image.getSprite(0, 0));
173173+ }
174174+ if (layer[tile.y][tile.x] === 2) {
175175+ tile.addGraphic(image.getSprite(3, 0));
176176+ }
177177+ if (layer[tile.y][tile.x] === 3) {
178178+ tile.addGraphic(image.getSprite(5, 0));
179179+ }
180180+ });
181181+ });
182182+ }
183183+}
184184+185185+186186+```
187187+188188+
189189+9819099191## Adding Colliders to IsometricTiles
100192