phaser/src/tilemaps/Tileset.js

415 lines
13 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2024 Phaser Studio Inc.
2019-05-10 15:15:04 +00:00
* @license {@link https://opensource.org/licenses/MIT|MIT License}
2018-02-12 16:01:20 +00:00
*/
2018-02-07 17:10:01 +00:00
var Class = require('../utils/Class');
var Vector2 = require('../math/Vector2');
2017-11-10 21:56:14 +00:00
2018-02-07 15:27:21 +00:00
/**
* @classdesc
2023-04-03 17:35:25 +00:00
* A Tileset is a combination of a single image containing the tiles and a container for data about
2018-02-07 15:27:21 +00:00
* each tile.
*
* @class Tileset
2018-10-10 09:49:13 +00:00
* @memberof Phaser.Tilemaps
2018-02-07 15:27:21 +00:00
* @constructor
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2018-02-07 15:27:21 +00:00
*
* @param {string} name - The name of the tileset in the map data.
2020-11-23 10:22:13 +00:00
* @param {number} firstgid - The first tile index this tileset contains.
* @param {number} [tileWidth=32] - Width of each tile (in pixels).
* @param {number} [tileHeight=32] - Height of each tile (in pixels).
* @param {number} [tileMargin=0] - The margin around all tiles in the sheet (in pixels).
* @param {number} [tileSpacing=0] - The spacing between each tile in the sheet (in pixels).
2018-02-07 15:27:21 +00:00
* @param {object} [tileProperties={}] - Custom properties defined per tile in the Tileset.
* These typically are custom properties created in Tiled when editing a tileset.
* @param {object} [tileData={}] - Data stored per tile. These typically are created in Tiled when editing a tileset, e.g. from Tiled's tile collision editor or terrain editor.
* @param {object} [tileOffset={x: 0, y: 0}] - Tile texture drawing offset.
2018-02-07 15:27:21 +00:00
*/
2017-11-10 21:56:14 +00:00
var Tileset = new Class({
initialize:
function Tileset (name, firstgid, tileWidth, tileHeight, tileMargin, tileSpacing, tileProperties, tileData, tileOffset)
2017-11-10 21:56:14 +00:00
{
if (tileWidth === undefined || tileWidth <= 0) { tileWidth = 32; }
if (tileHeight === undefined || tileHeight <= 0) { tileHeight = 32; }
if (tileMargin === undefined) { tileMargin = 0; }
if (tileSpacing === undefined) { tileSpacing = 0; }
2017-11-29 20:39:30 +00:00
if (tileProperties === undefined) { tileProperties = {}; }
if (tileData === undefined) { tileData = {}; }
2017-11-10 21:56:14 +00:00
2017-11-29 20:39:30 +00:00
/**
* The name of the Tileset.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#name
* @type {string}
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.name = name;
2017-11-29 20:39:30 +00:00
/**
* The starting index of the first tile index this Tileset contains.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#firstgid
2020-11-23 10:22:13 +00:00
* @type {number}
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.firstgid = firstgid;
2017-11-29 20:39:30 +00:00
/**
* The width of each tile (in pixels). Use setTileSize to change.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileWidth
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.tileWidth = tileWidth;
2017-11-29 20:39:30 +00:00
/**
* The height of each tile (in pixels). Use setTileSize to change.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileHeight
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.tileHeight = tileHeight;
2017-11-29 20:39:30 +00:00
/**
* The margin around the tiles in the sheet (in pixels). Use `setSpacing` to change.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileMargin
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.tileMargin = tileMargin;
2017-11-29 20:39:30 +00:00
/**
* The spacing between each the tile in the sheet (in pixels). Use `setSpacing` to change.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileSpacing
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.tileSpacing = tileSpacing;
2017-11-29 20:39:30 +00:00
/**
2018-02-07 23:27:01 +00:00
* Tileset-specific properties per tile that are typically defined in the Tiled editor in the
* Tileset editor.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileProperties
* @type {object}
* @since 3.0.0
*/
2017-11-29 20:39:30 +00:00
this.tileProperties = tileProperties;
/**
2018-02-07 23:27:01 +00:00
* Tileset-specific data per tile that are typically defined in the Tiled editor, e.g. within
* the Tileset collision editor. This is where collision objects and terrain are stored.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#tileData
* @type {object}
* @since 3.0.0
*/
this.tileData = tileData;
2017-11-29 20:39:30 +00:00
/**
* Controls the drawing offset from the tile origin.
* Defaults to 0x0, no offset.
*
* @name Phaser.Tilemaps.Tileset#tileOffset
* @type {Phaser.Math.Vector2}
* @since 3.60.0
*/
this.tileOffset = new Vector2();
if (tileOffset !== undefined)
{
this.tileOffset.set(tileOffset.x, tileOffset.y);
}
2017-11-29 20:39:30 +00:00
/**
* The cached image that contains the individual tiles. Use setImage to set.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#image
2018-03-20 11:36:35 +00:00
* @type {?Phaser.Textures.Texture}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.image = null;
2017-11-29 20:39:30 +00:00
/**
* The gl texture used by the WebGL renderer.
*
* @name Phaser.Tilemaps.Tileset#glTexture
* @type {?Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper}
2018-10-09 12:40:00 +00:00
* @readonly
* @since 3.11.0
*/
this.glTexture = null;
2017-11-29 20:39:30 +00:00
/**
* The number of tile rows in the the tileset.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#rows
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.rows = 0;
2017-11-29 20:39:30 +00:00
/**
* The number of tile columns in the tileset.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#columns
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.columns = 0;
2017-11-29 20:39:30 +00:00
/**
* The total number of tiles in the tileset.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#total
2020-11-23 10:22:13 +00:00
* @type {number}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.total = 0;
2017-11-29 20:39:30 +00:00
/**
* The look-up table to specific tile image texture coordinates (UV in pixels). Each element
* contains the coordinates for a tile in an object of the form {x, y}.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @name Phaser.Tilemaps.Tileset#texCoordinates
* @type {object[]}
2018-10-09 12:40:00 +00:00
* @readonly
2018-02-07 23:27:01 +00:00
* @since 3.0.0
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
this.texCoordinates = [];
},
2017-11-29 20:39:30 +00:00
/**
2018-02-07 23:27:01 +00:00
* Get a tiles properties that are stored in the Tileset. Returns null if tile index is not
* contained in this Tileset. This is typically defined in Tiled under the Tileset editor.
2017-11-29 20:39:30 +00:00
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#getTileProperties
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
2018-03-20 11:36:35 +00:00
*
* @return {?(object|undefined)}
2017-11-29 20:39:30 +00:00
*/
getTileProperties: function (tileIndex)
{
if (!this.containsTileIndex(tileIndex)) { return null; }
2018-02-07 23:27:01 +00:00
2017-11-29 20:39:30 +00:00
return this.tileProperties[tileIndex - this.firstgid];
},
2017-11-29 20:39:30 +00:00
/**
* Get a tile's data that is stored in the Tileset. Returns null if tile index is not contained
* in this Tileset. This is typically defined in Tiled and will contain both Tileset collision
* info and terrain mapping.
2017-11-29 20:39:30 +00:00
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#getTileData
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
2018-03-20 11:36:35 +00:00
*
* @return {?object|undefined}
2017-11-29 20:39:30 +00:00
*/
getTileData: function (tileIndex)
{
if (!this.containsTileIndex(tileIndex)) { return null; }
2018-02-07 23:27:01 +00:00
return this.tileData[tileIndex - this.firstgid];
},
/**
* Get a tile's collision group that is stored in the Tileset. Returns null if tile index is not
* contained in this Tileset. This is typically defined within Tiled's tileset collision editor.
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#getTileCollisionGroup
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
2018-03-20 11:36:35 +00:00
*
* @return {?object}
*/
getTileCollisionGroup: function (tileIndex)
{
var data = this.getTileData(tileIndex);
2018-02-07 23:27:01 +00:00
return (data && data.objectgroup) ? data.objectgroup : null;
},
2017-11-29 20:39:30 +00:00
/**
* Returns true if and only if this Tileset contains the given tile index.
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#containsTileIndex
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @return {boolean}
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
containsTileIndex: function (tileIndex)
{
return (
tileIndex >= this.firstgid &&
tileIndex < (this.firstgid + this.total)
);
},
2017-11-29 20:39:30 +00:00
/**
* Returns the texture coordinates (UV in pixels) in the Tileset image for the given tile index.
* Returns null if tile index is not contained in this Tileset.
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#getTileTextureCoordinates
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
2018-03-20 11:36:35 +00:00
*
* @return {?object} Object in the form { x, y } representing the top-left UV coordinate
2017-11-29 20:39:30 +00:00
* within the Tileset image.
*/
2017-11-10 21:56:14 +00:00
getTileTextureCoordinates: function (tileIndex)
{
if (!this.containsTileIndex(tileIndex)) { return null; }
2018-02-07 23:27:01 +00:00
2017-11-10 21:56:14 +00:00
return this.texCoordinates[tileIndex - this.firstgid];
},
2017-11-29 20:39:30 +00:00
/**
* Sets the image associated with this Tileset and updates the tile data (rows, columns, etc.).
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#setImage
* @since 3.0.0
*
* @param {Phaser.Textures.Texture} texture - The image that contains the tiles.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
2017-11-29 20:39:30 +00:00
*/
setImage: function (texture)
{
this.image = texture;
2018-02-07 23:27:01 +00:00
this.glTexture = texture.get().source.glTexture;
2017-11-29 20:39:30 +00:00
this.updateTileData(this.image.source[0].width, this.image.source[0].height);
2018-02-07 23:27:01 +00:00
2017-11-29 20:39:30 +00:00
return this;
},
/**
* Sets the tile width & height and updates the tile data (rows, columns, etc.).
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#setTileSize
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} [tileWidth] - The width of a tile in pixels.
* @param {number} [tileHeight] - The height of a tile in pixels.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
2017-11-29 20:39:30 +00:00
*/
setTileSize: function (tileWidth, tileHeight)
{
if (tileWidth !== undefined) { this.tileWidth = tileWidth; }
if (tileHeight !== undefined) { this.tileHeight = tileHeight; }
if (this.image)
{
this.updateTileData(this.image.source[0].width, this.image.source[0].height);
}
2017-11-29 20:39:30 +00:00
return this;
},
2017-11-29 20:39:30 +00:00
/**
* Sets the tile margin & spacing and updates the tile data (rows, columns, etc.).
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#setSpacing
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} [margin] - The margin around the tiles in the sheet (in pixels).
* @param {number} [spacing] - The spacing between the tiles in the sheet (in pixels).
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
2017-11-29 20:39:30 +00:00
*/
2017-11-16 21:25:45 +00:00
setSpacing: function (margin, spacing)
{
if (margin !== undefined) { this.tileMargin = margin; }
if (spacing !== undefined) { this.tileSpacing = spacing; }
2017-11-16 21:25:45 +00:00
if (this.image)
{
this.updateTileData(this.image.source[0].width, this.image.source[0].height);
}
2017-11-29 20:39:30 +00:00
return this;
2017-11-16 21:25:45 +00:00
},
2017-11-29 20:39:30 +00:00
/**
* Updates tile texture coordinates and tileset data.
*
2018-02-07 23:27:01 +00:00
* @method Phaser.Tilemaps.Tileset#updateTileData
* @since 3.0.0
*
2020-11-23 10:22:13 +00:00
* @param {number} imageWidth - The (expected) width of the image to slice.
* @param {number} imageHeight - The (expected) height of the image to slice.
2018-03-20 11:36:35 +00:00
*
2018-02-07 23:27:01 +00:00
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
2017-11-29 20:39:30 +00:00
*/
2017-11-10 21:56:14 +00:00
updateTileData: function (imageWidth, imageHeight)
{
var rowCount = (imageHeight - this.tileMargin * 2 + this.tileSpacing) / (this.tileHeight + this.tileSpacing);
var colCount = (imageWidth - this.tileMargin * 2 + this.tileSpacing) / (this.tileWidth + this.tileSpacing);
if (rowCount % 1 !== 0 || colCount % 1 !== 0)
{
2018-09-27 10:34:13 +00:00
console.warn('Image tile area not tile size multiple in: ' + this.name);
2017-11-10 21:56:14 +00:00
}
2017-11-29 20:39:30 +00:00
// In Tiled a tileset image that is not an even multiple of the tile dimensions is truncated
// - hence the floor when calculating the rows/columns.
2017-11-10 21:56:14 +00:00
rowCount = Math.floor(rowCount);
colCount = Math.floor(colCount);
this.rows = rowCount;
this.columns = colCount;
// In Tiled, "empty" spaces in a tileset count as tiles and hence count towards the gid
this.total = rowCount * colCount;
this.texCoordinates.length = 0;
var tx = this.tileMargin;
var ty = this.tileMargin;
for (var y = 0; y < this.rows; y++)
{
for (var x = 0; x < this.columns; x++)
{
this.texCoordinates.push({ x: tx, y: ty });
tx += this.tileWidth + this.tileSpacing;
}
tx = this.tileMargin;
ty += this.tileHeight + this.tileSpacing;
}
2017-11-29 20:39:30 +00:00
return this;
2017-11-10 21:56:14 +00:00
}
2018-02-07 23:27:01 +00:00
2017-11-10 21:56:14 +00:00
});
module.exports = Tileset;