Skip to content

Commit 47c49b1

Browse files
committed
Tilemap - Tiled image size calculation
Addresses phaserjs#1371 - where Tiled used floor calculations and Phaser used round calculations. There are no breaking changes with the demos; however, if there was code that relied on behavior that _deviated_ from the defactor Tilemap behavior then may be prone to "incorrect results" if using tileset images that are not correctly aligned to tilesize multiples. This also adds/corrects some warnings: - A warning when the tileset size is not an even multiple (it was suppressed due to using `round` prior to the checks. - A warning if loading an image changes the cols/rows of a Tileset - A specific warning for Tileset Image Collections which are not yet supported
1 parent 2488359 commit 47c49b1

2 files changed

Lines changed: 49 additions & 23 deletions

File tree

src/tilemap/TilemapParser.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ Phaser.TilemapParser = {
189189

190190
if (json.orientation !== 'orthogonal')
191191
{
192-
console.warn('TilemapParser.parseTiledJSON: Only orthogonal map types are supported in this version of Phaser');
192+
console.warn('TilemapParser.parseTiledJSON - Only orthogonal map types are supported in this version of Phaser');
193193
return null;
194194
}
195195

@@ -320,25 +320,27 @@ Phaser.TilemapParser = {
320320
{
321321
// name, firstgid, width, height, margin, spacing, properties
322322
var set = json.tilesets[i];
323-
var newSet = new Phaser.Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
324323

325-
if (set.tileproperties)
324+
if (!set.tiles)
326325
{
327-
newSet.tileProperties = set.tileproperties;
328-
}
326+
var newSet = new Phaser.Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
329327

330-
newSet.rows = Math.round((set.imageheight - set.margin) / (set.tileheight + set.spacing));
331-
newSet.columns = Math.round((set.imagewidth - set.margin) / (set.tilewidth + set.spacing));
332-
newSet.total = newSet.rows * newSet.columns;
328+
if (set.tileproperties)
329+
{
330+
newSet.tileProperties = set.tileproperties;
331+
}
333332

334-
if (newSet.rows % 1 !== 0 || newSet.columns % 1 !== 0)
335-
{
336-
console.warn('TileSet image dimensions do not match expected dimensions. Tileset width/height must be evenly divisible by Tilemap tile width/height.');
333+
// For a normal sliced tileset the row/count/size information is computed when updated.
334+
// This is done (again) after the image is set.
335+
newSet.updateTileData(set.imagewidth, set.imageheight);
336+
tilesets.push(newSet);
337337
}
338338
else
339339
{
340-
tilesets.push(newSet);
340+
// TODO: Handle Tileset Image Collections (multiple images in a tileset, no slicing into each image)
341+
console.warn("Phaser.TilemapParser - Image Collection Tilesets are not support");
341342
}
343+
342344
}
343345

344346
map.tilesets = tilesets;

src/tilemap/Tileset.js

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, prope
6666
* The spacing between each tile in the sheet (in pixels).
6767
* Use `setSpacing` to change.
6868
* @property {integer} tileSpacing
69+
* @readonly
6970
*/
7071
this.tileSpacing = spacing | 0;
7172

@@ -76,31 +77,31 @@ Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, prope
7677
this.properties = properties || {};
7778

7879
/**
79-
* The cached image that contains the individual tiles. Use `setImage` to set.
80+
* The cached image that contains the individual tiles. Use {@link Phaser.Tileset.setImage setImage} to set.
8081
* @property {?object} image
8182
* @readonly
8283
*/
8384
// Modified internally
8485
this.image = null;
8586

8687
/**
87-
* The number of rows in the tile sheet.
88+
* The number of tile rows in the the tileset.
8889
* @property {integer}
8990
* @readonly
9091
*/
9192
// Modified internally
9293
this.rows = 0;
9394

9495
/**
95-
* The number of columns in the sheet.
96+
* The number of tile columns in the tileset.
9697
* @property {integer} columns
9798
* @readonly
9899
*/
99100
// Modified internally
100101
this.columns = 0;
101102

102103
/**
103-
* The total number of tiles in the sheet.
104+
* The total number of tiles in the tileset.
104105
* @property {integer} total
105106
* @readonly
106107
*/
@@ -178,7 +179,7 @@ Phaser.Tileset.prototype = {
178179
setImage: function (image) {
179180

180181
this.image = image;
181-
this.updateTileData();
182+
this.updateTileData(image.width, image.height);
182183

183184
},
184185

@@ -195,7 +196,10 @@ Phaser.Tileset.prototype = {
195196
this.tileMargin = margin | 0;
196197
this.tileSpacing = spacing | 0;
197198

198-
this.updateTileData();
199+
if (this.image)
200+
{
201+
this.updateTileData(this.image.width, this.image.height);
202+
}
199203

200204
},
201205

@@ -204,13 +208,33 @@ Phaser.Tileset.prototype = {
204208
*
205209
* @method Phaser.Tileset#updateTileData
206210
* @private
211+
* @param {integer} imageWidth - The (expected) width of the image to slice.
212+
* @param {integer} imageHeight - The (expected) height of the image to slice.
207213
*/
208-
updateTileData: function () {
214+
updateTileData: function (imageWidth, imageHeight) {
215+
216+
// May be fractional values
217+
var rowCount = (imageHeight - this.tileMargin) / (this.tileHeight + this.tileSpacing);
218+
var colCount = (imageWidth - this.tileMargin) / (this.tileWidth + this.tileSpacing);
219+
220+
if (rowCount % 1 !== 0 || colCount % 1 !== 0)
221+
{
222+
console.warn("Phaser.Tileset - image tile area is not an even multiple of tile size");
223+
}
224+
225+
// In Tiled a tileset image that is not an even multiple of the tile dimensions
226+
// is truncated - hence the floor when calculating the rows/columns.
227+
rowCount = Math.floor(rowCount);
228+
colCount = Math.floor(colCount);
229+
230+
if ((this.rows && this.rows !== rowCount) || (this.columns && this.columns !== colCount))
231+
{
232+
console.warn("Phaser.Tileset - actual and expected number of tile rows and columns differ");
233+
}
209234

210-
var image = this.image;
211-
this.rows = Math.round((image.height - this.tileMargin) / (this.tileHeight + this.tileSpacing));
212-
this.columns = Math.round((image.width - this.tileMargin) / (this.tileWidth + this.tileSpacing));
213-
this.total = this.rows * this.columns;
235+
this.rows = rowCount;
236+
this.columns = colCount;
237+
this.total = rowCount * colCount;
214238

215239
this.drawCoords.length = 0;
216240

0 commit comments

Comments
 (0)