API Docs for: v0.1.0
Show:

File: src\tilemap\Tileset.js

var utils = require('../utils/utils'),
    inherit = require('../utils/inherit'),
    math = require('../math/math'),
    Texture = require('../display/Texture'),
    Vector = require('../math/Vector'),
    PIXI = require('../vendor/pixi');

/**
 * This object represents a tileset used by a Tilemap.
 * There can be multiple Tilesets in a map
 *
 * @class Tileset
 * @extends Texture
 * @constructor
 * @param texture {Texture} The texture to use for the tileset
 * @param settings {Object} All the settings for the tileset
 * @param settings.tilewidth {Number} The width of a single tile in the set
 * @param settings.tileheight {Number} The height of a single tile in the set
 * @param [settings.firstgid=1] {Number} The id of the first tile in the set, defaults to 1
 * @param [settings.spacing=0] {Number} The spacing around tiles in the tileset (in pixels)
 * @param [settings.margin=0] {Number} The margin around a tile in the tileset (in pixels)
 * @param [settings.tileoffset] {Object} The offset to apply to a tile rendered from this tileset
 * @param [settings.tileoffset.x=0] {Number} The X offset to apply to the tile
 * @param [settings.tileoffset.y=0] {Number} The Y offset to apply to the tile
 * @param [settings.properties] {Object} User-defined, custom properties that apply to the tileset
 * @param [settings.tileproperties] {Object} User-defined, custom properties that apply to tiles in the tileset.
 *          The keys of this object should the tile id of the properties
 * @param [settings.imagewidth] {Number} An override for the image width
 * @param [settings.imageheight] {Number} An override for the image height
 */
//TODO: Support external tilesets (TSX files) via the "source" attribute
//see: https://github.com/bjorn/tiled/wiki/TMX-Map-Format#tileset
var Tileset = function(texture, settings) {
    //initialize the base Texture class
    Texture.call(this, texture.baseTexture || texture);

    //Tiled Editor properties

    /**
     * The first tileId in the tileset
     *
     * @property firstgid
     * @type Number
     */
    this.firstgid = settings.firstgid || 1;

    /**
     * The name of the tileset
     *
     * @property name
     * @type String
     */
    this.name = settings.name;

    /**
     * The size of a tile in the tileset
     *
     * @property tileSize
     * @type Vector
     */
    this.tileSize = new Vector(settings.tilewidth, settings.tileheight);

    /**
     * The spacing around a tile in the tileset
     *
     * @property spacing
     * @type Number
     */
    this.spacing = settings.spacing || 0;

    /**
     * The margin around a tile in the tileset
     *
     * @property margin
     * @type Number
     */
    this.margin = settings.margin || 0;

    /**
     * The offset of tile positions when rendered
     *
     * @property tileoffset
     * @type Number
     */
    this.tileoffset = new Vector(
        settings.tileoffset ? settings.tileoffset.x : 0,
        settings.tileoffset ? settings.tileoffset.y : 0
    );

    //TODO: Support for "terraintypes," "image"
    //see: https://github.com/bjorn/tiled/wiki/TMX-Map-Format#tileset

    //Custom/Optional properties

    /**
     * The number of tiles calculated based on size, margin, and spacing
     *
     * @property numTiles
     * @type Vector
     */
    this.numTiles = new Vector(
        math.floor((this.baseTexture.source.width - this.margin) / (this.tileSize.x - this.spacing)),
        math.floor((this.baseTexture.source.height - this.margin) / (this.tileSize.y - this.spacing))
    );

    /**
     * The last tileId in the tileset
     *
     * @property lastgid
     * @type Number
     */
    this.lastgid = this.firstgid + (((this.numTiles.x * this.numTiles.y) - 1) || 0);

    /**
     * The properties of the tileset
     *
     * @property properties
     * @type Object
     */
    this.properties = settings.properties || {};

    /**
     * The properties of the tiles in the tileset (like collision stuff)
     *
     * @property tileproperties
     * @type Object
     */
    this.tileproperties = settings.tileproperties || {};

    /**
     * The size of the tileset
     *
     * @property size
     * @type Vector
     */
    this.size = new Vector(
        settings.imagewidth || this.baseTexture.source.width,
        settings.imageheight || this.baseTexture.source.height
    );

    /**
     * The texture instances for each tile in the set
     *
     * @property textures
     * @type Array
     */
    this.textures = [];

    //massages strings into the values they should be
    //i.e. "true" becomes the value: true
    this.properties = utils.parseTiledProperties(this.properties);

    //massage tile properties
    for(var k in this.tileproperties) {
        this.tileproperties[k] = utils.parseTiledProperties(this.tileproperties[k]);
    }

    //generate tile textures
    for(var t = 0, tl = this.lastgid - this.firstgid + 1; t < tl; ++t) {
        //convert the tileId to x,y coords of the tile in the Texture
        var y = math.floor(t / this.numTiles.x),
            x = (t - (y * this.numTiles.x));

        //get location in pixels
        x = (x * this.tileSize.x) + (x * this.spacing) + this.margin;
        y = (y * this.tileSize.y) + (y * this.spacing) + this.margin;

        this.textures.push(
            new Texture(
                this.baseTexture,
                new PIXI.Rectangle(x, y, this.tileSize.x, this.tileSize.y)
            )
        );
    }
};

inherit(Tileset, Texture, {
    /**
     * Gets the tile properties for a tile based on it's ID
     *
     * @method getTileProperties
     * @param tileId {Number} The id of the tile to get the properties for
     * @return {Object} The properties of the tile
     */
    getTileProperties: function(tileId) {
        if(!tileId) return null;

        var flags = Tileset.FLAGS,
            flippedX = tileId & flags.FlippedX,
            flippedY = tileId & flags.FlippedY,
            rotatedCW = tileId & flags.RotatedCW;

        tileId = (tileId & ~Tileset.FLAGS.ALL) - this.firstgid;

        //if less than 0, then this id isn't in this tileset
        if(tileId < 0) return null;

        var props = this.tileproperties[tileId] ?
        //get this value
        this.tileproperties[tileId] :
        //set this id to default values and cache
        this.tileproperties[tileId] = {
            collidable: false,
            breakable: false
        };

        props.flippedX = flippedX;
        props.flippedY = flippedY;
        props.rotatedCW = rotatedCW;

        return props;
    },
    /**
     * Gets the tile texture for a tile based on it's ID
     *
     * @method getTileTexture
     * @param tileId {Number} The id of the tile to get the texture for
     * @return {Texture} The texture for the tile
     */
    getTileTexture: function(tileId) {
        if(!tileId) return null;

        //get the internal ID of the tile in this set (0 indexed)
        tileId = (tileId & ~Tileset.FLAGS.ALL) - this.firstgid;

        //if less than 0, then this id isn't in this tileset
        if(tileId < 0) return null;

        return this.textures[tileId];
    },
    /**
     * Returns whether or not this tileset contains the given tile guid
     *
     * @method contains
     * @param tileId {Number} The ID of the tile to check
     * @return {Boolean}
     */
    contains: function(tileId) {
        if(!tileId) return false;

        tileId &= ~Tileset.FLAGS.ALL;

        return (tileId >= this.firstgid && tileId <= this.lastgid);
    }
});

/**
 * Tileset GID flags, these flags are set on a tile's ID to give it a special property
 *
 * @property FLAGS
 * @static
 */
Tileset.FLAGS = {
    FlippedX: 0x80000000,
    FlippedY: 0x40000000,
    RotatedCW: 0x20000000
};

var mask = 0;
for(var f in Tileset.FLAGS) {
    mask |= Tileset.FLAGS[f];
}

Tileset.FLAGS.ALL = mask;

module.exports = Tileset;