From ff7cad102c787edaf3ead9e5489d63688534bb1a Mon Sep 17 00:00:00 2001 From: photonstorm Date: Tue, 14 Jan 2014 11:58:00 +0000 Subject: [PATCH] All of the setCollision methods now have a 'collides' parameter so you can enable or disable collision, not only enable it. Also fixed Loader example. --- examples/loader/load tilemap json.js | 23 +-- src/tilemap/Tilemap.js | 210 ++++++++++++++++----------- 2 files changed, 136 insertions(+), 97 deletions(-) diff --git a/examples/loader/load tilemap json.js b/examples/loader/load tilemap json.js index 9447c153..eae8be89 100644 --- a/examples/loader/load tilemap json.js +++ b/examples/loader/load tilemap json.js @@ -3,7 +3,6 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p function preload() { - // Tilemaps are split into two parts: The actual map data (usually stored in a CSV or JSON file) // and the tileset/s used to render the map. @@ -16,27 +15,33 @@ function preload() { // The final one tells Phaser the foramt of the map data, in this case it's a JSON file exported from the Tiled map editor. // This could be Phaser.Tilemap.CSV too. - game.load.tilemap('mario', 'assets/maps/mario1.json', null, Phaser.Tilemap.TILED_JSON); + game.load.tilemap('mario', 'assets/tilemaps/maps/super_mario.json', null, Phaser.Tilemap.TILED_JSON); - // Next we load the tileset. This consists of an image and a set of values that determine the size of the tiles within the image. - // In this case we give it a unique key, the URL to the PNG file and tell Phaser the tiles are all 16x16 pixels in size. + // Next we load the tileset. This is just an image, loaded in via the normal way we load images: - game.load.tileset('tiles', 'assets/maps/mario1.png', 16, 16); + game.load.image('tiles', 'assets/tilemaps/tiles/super_mario.png'); } var map; -var tileset; var layer; function create() { game.stage.backgroundColor = '#787878'; + // The 'mario' key here is the Loader key given in game.load.tilemap map = game.add.tilemap('mario'); - - tileset = game.add.tileset('tiles'); - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + // The first parameter is the tileset name, as specified in the Tiled map editor (and in the tilemap json file) + // The second parameter maps this name to the Phaser.Cache key 'tiles' + map.addTilesetImage('SuperMarioBros-World1-1', 'tiles'); + + // Creates a layer from the World1 layer in the map data. + // A Layer is effectively like a Phaser.Sprite, so is added to the display list. + layer = map.createLayer('World1'); + + // This resizes the game world to match the layer dimensions + layer.resizeWorld(); } diff --git a/src/tilemap/Tilemap.js b/src/tilemap/Tilemap.js index ad3352be..2f40e186 100644 --- a/src/tilemap/Tilemap.js +++ b/src/tilemap/Tilemap.js @@ -357,26 +357,98 @@ Phaser.Tilemap.prototype = { }, + setTileCallback: function (indexes, layer, callback, callbackContext) { + + + + }, + + /** + * Sets collision the given tile or tiles. You can pass in either a single numeric index or an array of indexes: [ 2, 3, 15, 20]. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tileset#setCollision + * @param {number|array} indexes - Either a single tile index, or an array of tile IDs to be checked for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setCollision: function (indexes, collides, layer) { + + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); + + if (typeof indexes === 'number') + { + return this.setCollisionByIndex(indexes, collides, layer, true); + } + else + { + // Collide all of the IDs given in the indexes array + for (var i = 0, len = indexes.length; i < len; i++) + { + this.setCollisionByIndex(indexes[i], collides, layer, false); + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + } + + }, + + /** + * Sets collision on a range of tiles where the tile IDs increment sequentially. + * Calling this with a start value of 10 and a stop value of 14 would set collision for tiles 10, 11, 12, 13 and 14. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tileset#setCollisionBetween + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setCollisionBetween: function (start, stop, collides, layer) { + + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); + + if (start > stop) + { + return; + } + + for (var index = start; index <= stop; index++) + { + this.setCollisionByIndex(index, collides, layer, false); + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + + }, + /** * Sets collision on all tiles in the given layer, except for the IDs of those in the given array. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). * * @method Phaser.Tileset#setCollisionByExclusion * @param {array} indexes - An array of the tile IDs to not be counted for collision. - * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. */ - setCollisionByExclusion: function (indexes, layer) { + setCollisionByExclusion: function (indexes, collides, layer) { - if (typeof layer === 'undefined') - { - layer = this.currentLayer; - } + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); // Collide everything, except the IDs given in the indexes array for (var i = 0, len = this.tiles.length; i < len; i++) { if (indexes.indexOf(i) === -1) { - this.setCollisionByIndex(i, layer, false); + this.setCollisionByIndex(i, collides, layer, false); } } @@ -385,85 +457,23 @@ Phaser.Tilemap.prototype = { }, - /** - * Sets collision the given tile index, or array of tiles indexes. - * - * @method Phaser.Tileset#setCollision - * @param {number|array} indexes - Either a single tile index, or an array of tile IDs to be checked for collision. - * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. - */ - setCollision: function (indexes, layer) { - - if (typeof layer === 'undefined') - { - layer = this.currentLayer; - } - - if (typeof indexes === 'number') - { - return this.setCollisionByIndex(indexes, layer); - } - - // Collide all of the IDs given in the indexes array - for (var i = 0, len = indexes.length; i < len; i++) - { - this.setCollisionByIndex(indexes[i], layer, false); - } - - // Now re-calculate interesting faces - this.calculateFaces(layer); - - }, - - /** - * Sets collision on a range of tiles. - * - * @method Phaser.Tileset#setCollisionBetween - * @param {number} start - The first index of the tile to be set for collision. - * @param {number} stop - The last index of the tile to be set for collision. - * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. - */ - setCollisionBetween: function (start, stop, layer) { - - if (start > stop) - { - return; - } - - for (var i = start; i <= stop; i++) - { - var index = this.setCollisionByIndex(i, layer, false); - } - - // Now re-calculate interesting faces - this.calculateFaces(index); - - }, - /** * Sets collision values on a tile in the set. + * You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion. * * @method Phaser.Tileset#setCollisionByIndex + * @protected * @param {number} index - The index of the tile on the layer. - * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. + * @param {boolean} [collides=true] - If true it will enable collision on the tile. If false it will clear collision values from the tile. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. * @param {boolean} [recalculate=true] - Recalculates the tile faces after the update. */ - setCollisionByIndex: function (index, layer, recalculate) { + setCollisionByIndex: function (index, collides, layer, recalculate) { - if (typeof layer === 'undefined') - { - layer = this.currentLayer; - } - else if (typeof layer === 'string') - { - layer = this.getLayerIndex(layer); - } - else if (layer instanceof Phaser.TilemapLayer) - { - layer = layer.index; - } + if (typeof collides === 'undefined') { collides = true; } + if (typeof recalculate === 'undefined') { recalculate = true; } - if (typeof recalculate === "undefined") { recalculate = true; } + layer = this.getLayer(layer); for (var y = 0; y < this.layers[layer].height ; y++) { @@ -473,11 +483,11 @@ Phaser.Tilemap.prototype = { if (tile && tile.index === index) { - tile.collides = true; - tile.faceTop = true; - tile.faceBottom = true; - tile.faceLeft = true; - tile.faceRight = true; + tile.collides = collides; + tile.faceTop = collides; + tile.faceBottom = collides; + tile.faceLeft = collides; + tile.faceRight = collides; } } } @@ -492,12 +502,39 @@ Phaser.Tilemap.prototype = { }, + /** + * Gets the TilemapLayer index as used in the setCollision calls. + * + * @method Phaser.Tileset#getLayer + * @protected + * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. + * @return {number} The TilemapLayer index. + */ + getLayer: function (layer) { + + if (typeof layer === 'undefined') + { + layer = this.currentLayer; + } + else if (typeof layer === 'string') + { + layer = this.getLayerIndex(layer); + } + else if (layer instanceof Phaser.TilemapLayer) + { + layer = layer.index; + } + + return layer; + + }, + /** * Internal function. * * @method Phaser.Tileset#calculateFaces * @protected - * @param {number} layer - The layer to operate on. + * @param {number} layer - The index of the TilemapLayer to operate on. */ calculateFaces: function (layer) { @@ -680,7 +717,7 @@ Phaser.Tilemap.prototype = { * @param {number} tileHeight - The height of the tile in pixels. * @param {number} [layer] - The Tilemap Layer to operate on. */ - putTileWorldXY: function (index, x, y, tileWidth, tileHeight, layer) { + putTileWorldXY: function (tile, x, y, tileWidth, tileHeight, layer) { if (typeof layer === "undefined") { layer = this.currentLayer; } @@ -725,10 +762,7 @@ Phaser.Tilemap.prototype = { x = this.game.math.snapToFloor(x, tileWidth) / tileWidth; y = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height) - { - return this.layers[layer].data[y][x]; - } + return this.getTile(x, y, layer); },