TileMaps can be useful tools to build levels for platformers or top down games.
Excalibur supports building tile based games, often referred to as "TileMaps." Excalibur has a Tiled plugin to support the popular Tiled editor map files.
Tilemaps consist of a uniform grid of cells that can be solid or not. Each cell can have it's own graphics.
Tile maps are made up of Cells which can draw Graphics. Tile maps support multiple layers of Graphics and work well for building tile-based games such as RPGs, adventure games, strategy games, and others. Cells can be solid so that Actors can't pass through them.
// Load your favorite tileset (maybe from Kenny.nl)
const kennyRougeLikePack = new ex.ImageSource(rougeLikeImageSrc);
// Create a sprite sheet
const rougeLikeSpriteSheet = ex.SpriteSheet.fromImageSource({
image: kennyRougeLikePack,
grid: {
rows: 31,
columns: 51,
spriteHeight: 16,
spriteWidth: 16
},
spacing: {
margin: {
x: 1,
y: 1
}
}
});
// Create a tilemap
const tilemap = new ex.TileMap({
x: 0,
y: 0,
rows: 10,
cols: 10,
cellWidth: 16,
cellHeight: 16,
});
// loop through tilemap cells
for (let cell of tilemap.data) {
const sprite = rougeLikeSpriteSheet.getSprite(0, 0);
if (sprite) {
cell.addGraphic(sprite);
}
}
Excalibur has a Tiled map plugin https://github.com/excaliburjs/excalibur-tiled/ for loading .tmx
maps.
We recommend using the Tiled map editor to build your maps and export them to JSON. You can then load them using a Generic Resource and process them to create your levels. A TileMap can then be used as part of a level or map class that adds enemies and builds game objects from the Tiled map.
import * as ex from 'excalibur'
import * as tiled from '@excaliburjs/plugin-tiled';
import exampleCityUrl from './example-city.tmx';
import tileset from './assets/kenny-rpg-urban-pack/tilemap_packed.png';
const game = new ex.Engine({
width: 600,
height: 400,
displayMode: ex.DisplayMode.FitScreen
});
const tiledMapResource = new tiled.TiledMapResource(exampleCityUrl);
// Only necessary for parcel v2 rearranging assets at the root
// or if you have a build system that moves resources linked by the .tmx
tiledMapResource.convertPath = (tmxLocation, relativePath) => {
const resourceName = relativePath.split('/').at(-1)?.split('.')[0];
// for each linked tileset
if (tileset.includes(resourceName)) {
return tileset;
}
}
const loader = new ex.Loader([tiledMapResource])
game.start(loader).then(() => {
tiledMapResource.addTiledMapToScene(game.currentScene);
game.currentScene.camera.zoom = 2;
});
Hexagonal and Isometric TileMaps are not yet supported out of the box (but they are in our plans), but with some engenuity you can replicate them.
We recommend reading some of the material on Red Blob Games for algorithms around Hexagonal and Isometric