Options
All
  • Public
  • Public/Protected
  • All
Menu

Class TileMap

The TileMap class provides a lightweight way to do large complex scenes with collision without the overhead of actors.

Tile maps are made up of Cells which can draw TileSprites. Tile maps support multiple layers 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.

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.

Creating a tile map

A TileMap is meant to be used in conjunction with a map editor. Creating a tile map is fairly straightforward.

You need a tile sheet (see SpriteSheet) that holds all the available tiles to draw. TileMap supports multiple sprite sheets, letting you organize tile sheets to your liking.

Next, you need to populate each Cell with one or more TileSprites using Cell.pushSprite.

Once the TileMap is added to a Scene, it will be drawn and updated.

You can then add Actors to the Scene and interact with the TileMap.

In this example, we take in a map configuration that we designed (for example, based on the exported structure of a JSON file).

// define TypeScript interfaces to make our life easier
public interface IMapDefinition {
  cells: IMapCellDefinition[];
  tileSheets: IMapTileSheet[];
  width: number;
  height: number;
  tileWidth: number;
  tileHeight: number;
}

public interface IMapCellDefinition {
  x: number;
  y: number;
  tileId: number;
  sheetId: number;
}

public interface IMapTileSheet {
  id: number;
  path: string;
  columns: number;
  rows: number;
}

// create a Map class that creates a game map
// based on JSON configuration
public class Map extends ex.Scene {
  private _mapDefinition: IMapDefinition;
  private _tileMap: ex.TileMap;
  constructor(mapDef: IMapDefinition) {
    // store reference to definition
    this._mapDefinition = mapDef;
    // create a tile map
    this._tileMap = new ex.TileMap(0, 0, mapDef.tileWidth, mapDef.tileHeight, 
      mapDef.width / mapDef.tileWidth, mapDef.height / mapDef.tileHeight);
  }
  public onInitialize() {
    // build our map based on JSON config
    // build sprite sheets
    this._mapDefinition.tileSheets.forEach(sheet => {

      // register sprite sheet with the tile map
      // normally, you will want to ensure you load the Texture before
      // creating the SpriteSheet
      // this can be done outside the Map class, in a Loader
      this._tileMap.registerSpriteSheet(sheet.id.toString(), 
        new ex.SpriteSheet(new ex.Texture(sheet.path), sheet.columns, sheet.rows, 
          this._mapDefinition.tileWidth, this._mapDefinition.tileHeight));
    });
    // fill cells with sprites
    this._mapDefinition.cells.forEach(cell => {
      // create a TileSprite
      // assume tileId is the index of the frame in the sprite sheet
      var ts = new ex.TileSprite(cell.sheetId.toString(), cell.spriteId);
      // add to cell
      this._tileMap.getCell(cell.x, cell.y).pushSprite(ts);
    }
  }
}

// create a game
var game = new ex.Engine();

// add our level (JSON from external source)
var map1 = new Map({ ... });
game.add("map1", map1);
game.start();

In a real game, you will want to ensure all the textures for the sprite sheets have been loaded. You could do this in the [[Resource.processDownload]] function of the generic resource when loading your JSON, before creating your Map object.

Off-screen culling

The TileMap takes care of only drawing the portion of the map that is on-screen. This significantly improves performance and essentially means Excalibur can support huge maps. Since Actors off-screen are not drawn, this also means maps can support many actors.

Collision checks

You can use TileMap.collides to check if a given Actor is colliding with a solid Cell. This method returns an intersection Vector that represents the smallest overlap with colliding cells.

Hierarchy

  • TileMap

Index

Constructors

constructor

  • new TileMap(x: number, y: number, cellWidth: number, cellHeight: number, rows: number, cols: number): TileMap
  • Parameters

    • x: number

      The x coordinate to anchor the TileMap's upper left corner (should not be changed once set)

    • y: number

      The y coordinate to anchor the TileMap's upper left corner (should not be changed once set)

    • cellWidth: number

      The individual width of each cell (in pixels) (should not be changed once set)

    • cellHeight: number

      The individual height of each cell (in pixels) (should not be changed once set)

    • rows: number

      The number of rows in the TileMap (should not be changed once set)

    • cols: number

      The number of cols in the TileMap (should not be changed once set)

    Returns TileMap

Properties

Private _collidingX

_collidingX: number = -1

Private _collidingY

_collidingY: number = -1

Private _onScreenXEnd

_onScreenXEnd: number = 9999

Private _onScreenXStart

_onScreenXStart: number = 0

Private _onScreenYEnd

_onScreenYEnd: number = 9999

Private _onScreenYStart

_onScreenYStart: number = 0

Private _spriteSheets

_spriteSheets: object

Type declaration

cellHeight

cellHeight: number

The individual height of each cell (in pixels) (should not be changed once set)

cellWidth

cellWidth: number

The individual width of each cell (in pixels) (should not be changed once set)

cols

cols: number

The number of cols in the TileMap (should not be changed once set)

data

data: Cell[] = []

logger

logger: Logger = Logger.getInstance()

rows

rows: number

The number of rows in the TileMap (should not be changed once set)

x

x: number

The x coordinate to anchor the TileMap's upper left corner (should not be changed once set)

y

y: number

The y coordinate to anchor the TileMap's upper left corner (should not be changed once set)

Methods

collides

  • Returns the intersection vector that can be used to resolve collisions with actors. If there is no collision null is returned.

    Parameters

    Returns Vector

debugDraw

  • debugDraw(ctx: CanvasRenderingContext2D): void
  • Draws all the tile map's debug info. Called by the Scene.

    Parameters

    • ctx: CanvasRenderingContext2D

      The current rendering context

    Returns void

draw

  • draw(ctx: CanvasRenderingContext2D, delta: number): void
  • Draws the tile map to the screen. Called by the Scene.

    Parameters

    • ctx: CanvasRenderingContext2D

      The current rendering context

    • delta: number

      The number of milliseconds since the last draw

    Returns void

getCell

  • getCell(x: number, y: number): Cell
  • Returns the Cell by its x and y coordinates

    Parameters

    • x: number
    • y: number

    Returns Cell

getCellByIndex

  • getCellByIndex(index: number): Cell
  • Returns the Cell by index (row major order)

    Parameters

    • index: number

    Returns Cell

getCellByPoint

  • getCellByPoint(x: number, y: number): Cell
  • Returns the Cell by testing a point in global coordinates, returns null if no cell was found.

    Parameters

    • x: number
    • y: number

    Returns Cell

registerSpriteSheet

  • registerSpriteSheet(key: string, spriteSheet: SpriteSheet): void
  • Parameters

    Returns void

update

  • update(engine: Engine, delta: number): void
  • Parameters

    • engine: Engine
    • delta: number

    Returns void