# TileEngine(​properties)

A tile engine for managing and drawing tilesets.

Tileset image courtesy of Kenney.

### TileEngine Parameters

`properties`

  Object. Properties of the tile engine.

`properties.width`

  Number. Width of the tile map (in number of tiles).

`properties.height`

  Number. Height of the tile map (in number of tiles).

`properties.tilewidth`

  Number. Width of a single tile (in pixels).

`properties.tileheight`

  Number. Height of a single tile (in pixels).

`properties.context` Optional

  Canvas​Rendering​Context2D. The context the tile engine should draw to. Defaults to core.getContext()

`properties.tilesets`

  An Array of Objects. Array of tileset objects.

`properties.tilesetN.firstgid`

  Number. First tile index of the tileset. The first tileset will have a firstgid of 1 as 0 represents an empty tile.

`properties.tilesetN.image`

  String or HTMLImageElement. Relative path to the HTMLImageElement or an HTMLImageElement. If passing a relative path, the image file must have been loaded first.

`properties.tilesetN.margin` Optional

  Number. The amount of whitespace between each tile (in pixels). Defaults to `0`.

`properties.tilesetN.tilewidth` Optional

  Number. Width of the tileset (in pixels). Defaults to properties.tilewidth.

`properties.tilesetN.tileheight` Optional

  Number. Height of the tileset (in pixels). Defaults to properties.tileheight.

`properties.tilesetN.source` Optional

  String. Relative path to the source JSON file. The source JSON file must have been loaded first.

`properties.tilesetN.columns` Optional

  Number. Number of columns in the tileset image.

`properties.layers`

  An Array of Objects. Array of layer objects.

`properties.layerN.name`

  String. Unique name of the layer.

`properties.layerN.data`

  An Array of Numbers. 1D array of tile indices.

`properties.layerN.visible` Optional

  Boolean. If the layer should be drawn or not. Defaults to `true`.

`properties.layerN.opacity` Optional

  Number. Percent opacity of the layer. Defaults to `1`.

## Basic Use #

Creating a tile map requires three things:

1. Dimensions of the tile map and a tile
2. At least one tileset with an image
3. At least one layer with data

To set up the tile engine, you'll need to pass it the width and height of a tile (in pixels) and the width and height of the map (in number of tiles).

You'll then need to add at least one tileset with an image as well as firstgid, or first tile index of the tileset. The first tileset will always have a firstgid of 1 as 0 represents an empty tile.

Lastly, you'll need to add at least one named layer with data. A layer tells the tile engine which tiles from the tileset image to use at what position on the map.

Once all tileset images and all layers have been added, you can render the tile engine by calling its render() function.

    let { TileEngine } = kontra

    let img = new Image();
    img.src = 'assets/imgs/mapPack_tilesheet.png';
    img.onload = function() {
      let tileEngine = TileEngine({
        // tile size
        tilewidth: 64,
        tileheight: 64,

        // map size in tiles
        width: 9,
        height: 9,

        // tileset object
        tilesets: [{
          firstgid: 1,
          image: img
        }],

        // layer object
        layers: [{
          name: 'ground',
          data: [ 0,  0,  0,  0,  0,  0,  0,  0,  0,
                  0,  0,  6,  7,  7,  8,  0,  0,  0,
                  0,  6,  27, 24, 24, 25, 0,  0,  0,
                  0,  23, 24, 24, 24, 26, 8,  0,  0,
                  0,  23, 24, 24, 24, 24, 26, 8,  0,
                  0,  23, 24, 24, 24, 24, 24, 25, 0,
                  0,  40, 41, 41, 10, 24, 24, 25, 0,
                  0,  0,  0,  0,  40, 41, 41, 42, 0,
                  0,  0,  0,  0,  0,  0,  0,  0,  0 ]
        }]
      });

      tileEngine.render();
    }

    import { TileEngine } from 'path/to/kontra.mjs'

    let img = new Image();
    img.src = 'assets/imgs/mapPack_tilesheet.png';
    img.onload = function() {
      let tileEngine = TileEngine({
        // tile size
        tilewidth: 64,
        tileheight: 64,

        // map size in tiles
        width: 9,
        height: 9,

        // tileset object
        tilesets: [{
          firstgid: 1,
          image: img
        }],

        // layer object
        layers: [{
          name: 'ground',
          data: [ 0,  0,  0,  0,  0,  0,  0,  0,  0,
                  0,  0,  6,  7,  7,  8,  0,  0,  0,
                  0,  6,  27, 24, 24, 25, 0,  0,  0,
                  0,  23, 24, 24, 24, 26, 8,  0,  0,
                  0,  23, 24, 24, 24, 24, 26, 8,  0,
                  0,  23, 24, 24, 24, 24, 24, 25, 0,
                  0,  40, 41, 41, 10, 24, 24, 25, 0,
                  0,  0,  0,  0,  40, 41, 41, 42, 0,
                  0,  0,  0,  0,  0,  0,  0,  0,  0 ]
        }]
      });

      tileEngine.render();
    }

    import { TileEngine } from 'kontra';

    let img = new Image();
    img.src = 'assets/imgs/mapPack_tilesheet.png';
    img.onload = function() {
      let tileEngine = TileEngine({
        // tile size
        tilewidth: 64,
        tileheight: 64,

        // map size in tiles
        width: 9,
        height: 9,

        // tileset object
        tilesets: [{
          firstgid: 1,
          image: img
        }],

        // layer object
        layers: [{
          name: 'ground',
          data: [ 0,  0,  0,  0,  0,  0,  0,  0,  0,
                  0,  0,  6,  7,  7,  8,  0,  0,  0,
                  0,  6,  27, 24, 24, 25, 0,  0,  0,
                  0,  23, 24, 24, 24, 26, 8,  0,  0,
                  0,  23, 24, 24, 24, 24, 26, 8,  0,
                  0,  23, 24, 24, 24, 24, 24, 25, 0,
                  0,  40, 41, 41, 10, 24, 24, 25, 0,
                  0,  0,  0,  0,  40, 41, 41, 42, 0,
                  0,  0,  0,  0,  0,  0,  0,  0,  0 ]
        }]
      });

      tileEngine.render();
    }

## Advance Use #

Adding all the tileset images and layers to a tile engine can be tedious, especially if you have multiple layers. If you want a simpler way to create a tile engine, Kontra has been written to work directly with the JSON output of the Tiled Map Editor.

The one requirement is that you must preload all of the tileset images and tileset sources using the appropriate asset loader functions before you create the tile engine.

    let { load, TileEngine, dataAssets } = kontra

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_basic.json')
      .then(assets => {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_basic']);
        tileEngine.render();
      });

    import { load, TileEngine, dataAssets } from 'path/to/kontra.mjs'

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_basic.json')
      .then(assets => {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_basic']);
        tileEngine.render();
      });

    import { load, TileEngine, dataAssets } from 'kontra';

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_basic.json')
      .then(assets => {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_basic']);
        tileEngine.render();
      });

## Moving the Camera #

If your tilemap is larger than the canvas size, you can move the tilemap camera to change how the tilemap is drawn. Use the tile engines sx and sy properties to move the camera. Just like drawing an image, the cameras coordinates are the top left corner.

The `sx` and `sy` coordinates will never draw the tile map below 0 or beyond the last row or column of the tile map.

    let { load, TileEngine, dataAssets, GameLoop } = kontra

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_camera.json')
      .then(function() {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_camera']);

        let sx = 1;
        let loop = GameLoop({
          update: function() {
            tileEngine.sx += sx;

            if (tileEngine.sx <= 0 || tileEngine.sx >= 320) {
              sx = -sx;
            }
          },
          render: function() {
            tileEngine.render();
          }
        });

        loop.start();
      });

    import { load, TileEngine, dataAssets, GameLoop } from 'path/to/kontra.mjs'

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_camera.json')
      .then(function() {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_camera']);

        let sx = 1;
        let loop = GameLoop({
          update: function() {
            tileEngine.sx += sx;

            if (tileEngine.sx <= 0 || tileEngine.sx >= 320) {
              sx = -sx;
            }
          },
          render: function() {
            tileEngine.render();
          }
        });

        loop.start();
      });

    import { load, TileEngine, dataAssets, GameLoop } from 'kontra';

    load('assets/imgs/mapPack_tilesheet.png', 'assets/data/tile_engine_camera.json')
      .then(function() {
        let tileEngine = TileEngine(dataAssets['assets/data/tile_engine_camera']);

        let sx = 1;
        let loop = GameLoop({
          update: function() {
            tileEngine.sx += sx;

            if (tileEngine.sx <= 0 || tileEngine.sx >= 320) {
              sx = -sx;
            }
          },
          render: function() {
            tileEngine.render();
          }
        });

        loop.start();
      });

## TileEngine​.context #

The context the tile engine will draw to.

## TileEngine​.height #

The height of tile map (in tiles).

## TileEngine​.layerCollidesWith(​name, object) #

Check if the object collides with the layer (shares a gird coordinate with any positive tile index in layers data). The object being checked must have the properties `x`, `y`, `width`, and `height` so that its position in the grid can be calculated. Sprite defines these properties for you.

    let { TileEngine, Sprite } = kontra;

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    let sprite = Sprite({
      x: 50,
      y: 20,
      width: 5,
      height: 5
    });

    tileEngine.layerCollidesWith('collision', sprite);  //=> false

    sprite.y = 28;

    tileEngine.layerCollidesWith('collision', sprite);  //=> true

    import { TileEngine, Sprite } from 'path/to/kontra.mjs';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    let sprite = Sprite({
      x: 50,
      y: 20,
      width: 5,
      height: 5
    });

    tileEngine.layerCollidesWith('collision', sprite);  //=> false

    sprite.y = 28;

    tileEngine.layerCollidesWith('collision', sprite);  //=> true

    import { TileEngine, Sprite } from 'kontra';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    let sprite = Sprite({
      x: 50,
      y: 20,
      width: 5,
      height: 5
    });

    tileEngine.layerCollidesWith('collision', sprite);  //=> false

    sprite.y = 28;

    tileEngine.layerCollidesWith('collision', sprite);  //=> true

### layerCollidesWith Parameters

`name`

  String. The name of the layer to check for collision.

`object`

  Object. Object to check collision against.

### layerCollidesWith Return value

`true` if the object collides with a tile, `false` otherwise.

## TileEngine​.layers #

Array of all layers of the tile engine.

## TileEngine​.mapheight #

The height of the tile map (in pixels).

## TileEngine​.mapwidth #

The width of the tile map (in pixels).

## TileEngine​.render(​) #

Render all visible layers.

## TileEngine​.renderLayer(​name) #

Render a specific layer by name.

### renderLayer Parameters

`name`

  String. Name of the layer to render.

## TileEngine​.setTileAtLayer(​name, position, tile) #

Set the tile at the specified layer using either x and y coordinates or row and column coordinates.

    let { TileEngine } = kontra;

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.setTileAtLayer('collision', {row: 2, col: 1}, 10);
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 10

    import { TileEngine } from 'path/to/kontra.mjs';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.setTileAtLayer('collision', {row: 2, col: 1}, 10);
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 10

    import { TileEngine } from 'kontra';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.setTileAtLayer('collision', {row: 2, col: 1}, 10);
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 10

### setTileAtLayer Parameters

`name`

  String. Name of the layer.

`position`

  Object. Position of the tile in either {x, y} or {row, col} coordinates.

`tile`

  Number. Tile index to set.

## TileEngine​.sx #

X coordinate of the tile map camera.

## TileEngine​.sy #

Y coordinate of the tile map camera.

## TileEngine​.tileAtLayer(​name, position) #

Get the tile at the specified layer using either x and y coordinates or row and column coordinates.

    let { TileEngine } = kontra;

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.tileAtLayer('collision', {x: 50, y: 50});  //=> 1
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 2

    import { TileEngine } from 'path/to/kontra.mjs';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.tileAtLayer('collision', {x: 50, y: 50});  //=> 1
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 2

    import { TileEngine } from 'kontra';

    let tileEngine = TileEngine({
      tilewidth: 32,
      tileheight: 32,
      width: 4,
      height: 4,
      tilesets: [{
        // ...
      }],
      layers: [{
        name: 'collision',
        data: [ 0,0,0,0,
                0,1,4,0,
                0,2,5,0,
                0,0,0,0 ]
      }]
    });

    tileEngine.tileAtLayer('collision', {x: 50, y: 50});  //=> 1
    tileEngine.tileAtLayer('collision', {row: 2, col: 1});  //=> 2

### tileAtLayer Parameters

`name`

  String. Name of the layer.

`position`

  Object. Position of the tile in either {x, y} or {row, col} coordinates.

### tileAtLayer Return value

The tile index. Will return `-1` if no layer exists by the provided name.

## TileEngine​.tileheight #

The height of a tile (in pixels).

## TileEngine​.tilesets #

Array of all tilesets of the tile engine.

## TileEngine​.tilewidth #

The width a tile (in pixels).

## TileEngine​.width #

The width of tile map (in tiles).