diff --git a/build/phaser.js b/build/phaser.js index 260b2ec4..840dd354 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -9,7 +9,7 @@ * * Phaser - http://www.phaser.io * -* v1.0.7 - Built at: Wed, 16 Oct 2013 03:37:04 +0100 +* v1.0.7 - Built at: Wed, 16 Oct 2013 06:25:10 +0100 * * By Richard Davey http://www.photonstorm.com @photonstorm * @@ -15538,10 +15538,6 @@ Phaser.GameObjectFactory.prototype = { return group.create(x, y, key, frame); - // var child = new Phaser.Sprite(this.game, x, y, key, frame); - // parent.addChild(child); - // return child; - }, /** @@ -15687,17 +15683,43 @@ Phaser.GameObjectFactory.prototype = { * Description. * * @method tilemap - * @param {Description} x - Description. - * @param {Description} y - Description. * @param {Description} key - Description. - * @param {Description} resizeWorld - Description. - * @param {Description} tileWidth - Description. - * @param {Description} tileHeight - Description. * @return {Description} Description. */ - tilemap: function (x, y, key, resizeWorld, tileWidth, tileHeight) { + tilemap: function (key) { - return this.world.add(new Phaser.Tilemap(this.game, key, x, y, resizeWorld, tileWidth, tileHeight)); + return new Phaser.Tilemap(this.game, key); + + }, + + /** + * Description. + * + * @method tilemap + * @param {Description} key - Description. + * @return {Description} Description. + */ + tileset: function (key) { + + return this.game.cache.getTileset(key); + + }, + + /** + * Description. + * + * @method tileSprite + * @param {Description} x - Description. + * @param {Description} y - Description. + * @param {Description} width - Description. + * @param {Description} height - Description. + * @param {Description} key - Description. + * @param {Description} frame - Description. + * @return {Description} Description. + */ + tilemapLayer: function (x, y, width, height, tileset, tilemap, layer) { + + return this.world.add(new Phaser.TilemapLayer(this.game, x, y, width, height, tileset, tilemap, layer)); }, @@ -15997,16 +16019,6 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this.health = 1; - /** - * @property {Description} velocity - Description. - */ - // this.velocity = this.body.velocity; - - /** - * @property {Description} acceleration - Description. - */ - // this.acceleration = this.body.acceleration; - /** * @property {Description} inWorld - World bounds check. */ @@ -16575,18 +16587,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inCamera", { }); -/** -* -* @returns {boolean} -*/ -Object.defineProperty(Phaser.Sprite.prototype, "worldX", { - - get: function () { - return 1; - } - -}); - /** * Get the input enabled state of this Sprite. * @returns {Description} @@ -30155,6 +30155,7 @@ Phaser.Physics.Arcade = function (game) { this._newVelocity2 = 0; this._average = 0; this._mapData = []; + this._mapTiles = 0; this._result = false; this._total = 0; this._angle = 0; @@ -30301,9 +30302,9 @@ Phaser.Physics.Arcade.prototype = { { this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideSpriteVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } // GROUPS @@ -30317,21 +30318,21 @@ Phaser.Physics.Arcade.prototype = { { this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideGroupVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } - // TILEMAPS - else if (object1.type == Phaser.TILEMAP) + // TILEMAP LAYERS + else if (object1.type == Phaser.TILEMAPLAYER) { if (object2.type == Phaser.SPRITE) { - this.collideSpriteVsTilemap(object2, object1, collideCallback, processCallback, callbackContext); + this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); } else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) { - this.collideGroupVsTilemap(object2, object1, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); } } // EMITTER @@ -30345,9 +30346,9 @@ Phaser.Physics.Arcade.prototype = { { this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideGroupVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } } @@ -30356,6 +30357,70 @@ Phaser.Physics.Arcade.prototype = { }, + collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) { + + this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true); + + if (this._mapData.length > 1) + { + for (var i = 1; i < this._mapData.length; i++) + { + this.separateTile(sprite.body, this._mapData[i]); + + if (this._result) + { + // They collided, is there a custom process callback? + if (processCallback) + { + if (processCallback.call(callbackContext, sprite, this._mapData[i])) + { + this._total++; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, this._mapData[i]); + } + } + } + else + { + this._total++; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, this._mapData[i]); + } + } + } + } + } + + }, + + collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext) { + + if (group.length == 0) + { + return; + } + + if (group._container.first._iNext) + { + var currentNode = group._container.first._iNext; + + do + { + if (currentNode.exists) + { + this.collideSpriteVsTilemapLayer(currentNode, tilemapLayer, collideCallback, processCallback, callbackContext); + } + currentNode = currentNode._iNext; + } + while (currentNode != group._container.last._iNext); + } + + }, + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) { this.separate(sprite1.body, sprite2.body); @@ -30388,65 +30453,6 @@ Phaser.Physics.Arcade.prototype = { }, - collideGroupVsTilemap: function (group, tilemap, collideCallback, processCallback, callbackContext) { - - if (group.length == 0) - { - return; - } - - if (group._container.first._iNext) - { - var currentNode = group._container.first._iNext; - - do - { - if (currentNode.exists) - { - this.collideSpriteVsTilemap(currentNode, tilemap, collideCallback, processCallback, callbackContext); - } - currentNode = currentNode._iNext; - } - while (currentNode != group._container.last._iNext); - } - - }, - - collideSpriteVsTilemap: function (sprite, tilemap, collideCallback, processCallback, callbackContext) { - - this._mapData = tilemap.collisionLayer.getTileOverlaps(sprite); - - // If the sprite actually collided with the tilemap then _mapData contains an array of the tiles it collided with - var i = this._mapData.length; - - while (i--) - { - if (processCallback) - { - // We've got a custom process callback to hit first - if (processCallback.call(callbackContext, sprite, this._mapData[i].tile)) - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, this._mapData[i].tile); - } - } - } - else - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, this._mapData[i].tile); - } - } - } - - }, - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) { if (group.length == 0) @@ -30754,12 +30760,7 @@ Phaser.Physics.Arcade.prototype = { */ separateTile: function (body, tile) { - if (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)) - { - return true; - } - - return false; + this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)); }, @@ -32820,15 +32821,13 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, */ this.texture = new PIXI.Texture(this.baseTexture); - this.frame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid()); + this.textureFrame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid()); - /** - * @property {Description} sprite - Description. - * @default - */ - this.sprite = new Phaser.Sprite(this.game, x, y, this.texture, this.frame); - this.sprite.fixedToCamera = true; + Phaser.Sprite.call(this, this.game, x, y, this.texture, this.textureFrame); + this.type = Phaser.TILEMAPLAYER; + + this.fixedToCamera = true; /** * @property {Description} tileset - Description. @@ -32941,7 +32940,6 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, this._prevX = 0; this._prevY = 0; - this.dirty = true; if (tileset instanceof Phaser.Tileset || typeof tileset === 'string') @@ -32956,230 +32954,232 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, }; -Phaser.TilemapLayer.prototype = { +Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.Sprite.prototype, PIXI.Sprite.prototype); +Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer; - update: function () { - this.x = this.game.camera.x; - this.y = this.game.camera.y; +Phaser.TilemapLayer.prototype.update = function () { - }, + this.scrollX = this.game.camera.x; + this.scrollY = this.game.camera.y; - resizeWorld: function () { + this.render(); - this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels); +} - }, +Phaser.TilemapLayer.prototype.resizeWorld = function () { - updateTileset: function (tileset) { + this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels); - if (tileset instanceof Phaser.Tileset) - { - this.tileset = tileset; - } - else if (typeof tileset === 'string') - { - this.tileset = this.game.cache.getTileset('tiles'); - } - else - { - return; - } +} - this.tileWidth = this.tileset.tileWidth; - this.tileHeight = this.tileset.tileHeight; - - this.updateMax(); - - }, - - updateMapData: function (tilemap, layer) { - - if (typeof layer === 'undefined') - { - layer = 0; - } - - if (tilemap instanceof Phaser.Tilemap) - { - this.tilemap = tilemap; - this.layer = this.tilemap.layers[layer]; - this.updateMax(); - } - - }, - - /** - * - * @method getTileOverlaps - * @param {GameObject} object - Tiles you want to get that overlaps this. - * @return {array} Array with tiles informations (each contains x, y, and the tile). - */ - getTiles: function (x, y, width, height, collides) { - - if (this.tilemap === null) - { - return; - } - - // Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all) - if (typeof collides === 'undefined') { collides = false; } - - // Cap the values - - if (x < 0) - { - x = 0; - } - - if (y < 0) - { - y = 0; - } - - if (width > this.widthInPixels) - { - width = this.widthInPixels; - } - - if (height > this.heightInPixels) - { - height = this.heightInPixels; - } - - var tileWidth = this.tileWidth * this.sprite.scale.x; - var tileHeight = this.tileHeight * this.sprite.scale.y; - - // Convert the pixel values into tile coordinates - this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth; - this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; - this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; - - this._results.length = 0; - - this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); - - var _index = 0; - var _tile = null; - var sx = 0; - var sy = 0; - - for (var wy = this._ty; wy < this._ty + this._th; wy++) - { - for (var wx = this._tx; wx < this._tx + this._tw; wx++) - { - if (this.layer.data[wy] && this.layer.data[wy][wx]) - { - // Could combine - _index = this.layer.data[wy][wx] - 1; - _tile = this.tileset.getTile(_index); - - sx = _tile.width * this.sprite.scale.x; - sy = _tile.height * this.sprite.scale.y; - - if (collides == false || (collides && _tile.collideNone == false)) - { - // this._results.push({ x: wx * _tile.width, right: (wx * _tile.width) + _tile.width, y: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); - this._results.push({ x: wx * sx, right: (wx * sx) + sx, y: wy * sy, bottom: (wy * sy) + sy, width: sx, height: sy, tx: wx, ty: wy, tile: _tile }); - } - } - } - } - - return this._results; - - }, - - updateMax: function () { - - this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1; - this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1; - - if (this.layer) - { - if (this._maxX > this.layer.width) - { - this._maxX = this.layer.width; - } - - if (this._maxY > this.layer.height) - { - this._maxY = this.layer.height; - } - - this.widthInPixels = this.layer.width * this.tileWidth; - this.heightInPixels = this.layer.height * this.tileHeight; - } - - this.dirty = true; - - }, - - render: function () { - - if (!this.dirty || !this.tileset || !this.tilemap || !this.sprite.visible) - { - return; - } - - this._prevX = this._dx; - this._prevY = this._dy; - - this._dx = -(this._x - (this._startX * this.tileWidth)); - this._dy = -(this._y - (this._startY * this.tileHeight)); - - this._tx = this._dx; - this._ty = this._dy; - - this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - - for (var y = this._startY; y < this._startY + this._maxY; y++) - { - this._column = this.layer.data[y]; - - for (var x = this._startX; x < this._startX + this._maxX; x++) - { - // only -1 on TILED maps, not CSV - var tile = this.tileset.tiles[this._column[x]-1]; - - // if (this.tileset.checkTileIndex(tile)) - if (tile) - { - this.context.drawImage( - this.tileset.image, - tile.x, - tile.y, - this.tileWidth, - this.tileHeight, - Math.floor(this._tx), - Math.floor(this._ty), - this.tileWidth, - this.tileHeight - ); - } - - this._tx += this.tileWidth; - - } - - this._tx = this._dx; - this._ty += this.tileHeight; - } - - // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! - if (this.game.renderType == Phaser.WEBGL) - { - PIXI.texturesToUpdate.push(this.baseTexture); - } - - this.dirty = false; - - return true; +Phaser.TilemapLayer.prototype.updateTileset = function (tileset) { + if (tileset instanceof Phaser.Tileset) + { + this.tileset = tileset; + } + else if (typeof tileset === 'string') + { + this.tileset = this.game.cache.getTileset('tiles'); + } + else + { + return; } -}; + this.tileWidth = this.tileset.tileWidth; + this.tileHeight = this.tileset.tileHeight; + + this.updateMax(); + +} + +Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) { + + if (typeof layer === 'undefined') + { + layer = 0; + } + + if (tilemap instanceof Phaser.Tilemap) + { + this.tilemap = tilemap; + this.layer = this.tilemap.layers[layer]; + this.updateMax(); + } + +} + +/** +* +* @method getTileOverlaps +* @param {GameObject} object - Tiles you want to get that overlaps this. +* @return {array} Array with tiles informations (each contains x, y, and the tile). +*/ +Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) { + + if (this.tilemap === null) + { + return; + } + + // Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all) + if (typeof collides === 'undefined') { collides = false; } + + // Cap the values + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (width > this.widthInPixels) + { + width = this.widthInPixels; + } + + if (height > this.heightInPixels) + { + height = this.heightInPixels; + } + + var tileWidth = this.tileWidth * this.scale.x; + var tileHeight = this.tileHeight * this.scale.y; + + // Convert the pixel values into tile coordinates + this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth; + this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight; + this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; + this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; + + this._results.length = 0; + + this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); + + var _index = 0; + var _tile = null; + var sx = 0; + var sy = 0; + + for (var wy = this._ty; wy < this._ty + this._th; wy++) + { + for (var wx = this._tx; wx < this._tx + this._tw; wx++) + { + if (this.layer.data[wy] && this.layer.data[wy][wx]) + { + // Could combine + _index = this.layer.data[wy][wx] - 1; + _tile = this.tileset.getTile(_index); + + sx = _tile.width * this.scale.x; + sy = _tile.height * this.scale.y; + + if (collides == false || (collides && _tile.collideNone == false)) + { + // this._results.push({ x: wx * _tile.width, right: (wx * _tile.width) + _tile.width, y: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); + this._results.push({ x: wx * sx, right: (wx * sx) + sx, y: wy * sy, bottom: (wy * sy) + sy, width: sx, height: sy, tx: wx, ty: wy, tile: _tile }); + } + } + } + } + + return this._results; + +} + +Phaser.TilemapLayer.prototype.updateMax = function () { + + this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1; + this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1; + + if (this.layer) + { + if (this._maxX > this.layer.width) + { + this._maxX = this.layer.width; + } + + if (this._maxY > this.layer.height) + { + this._maxY = this.layer.height; + } + + this.widthInPixels = this.layer.width * this.tileWidth; + this.heightInPixels = this.layer.height * this.tileHeight; + } + + this.dirty = true; + +} + +Phaser.TilemapLayer.prototype.render = function () { + + if (!this.dirty || !this.tileset || !this.tilemap || !this.visible) + { + return; + } + + this._prevX = this._dx; + this._prevY = this._dy; + + this._dx = -(this._x - (this._startX * this.tileWidth)); + this._dy = -(this._y - (this._startY * this.tileHeight)); + + this._tx = this._dx; + this._ty = this._dy; + + this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + + for (var y = this._startY; y < this._startY + this._maxY; y++) + { + this._column = this.layer.data[y]; + + for (var x = this._startX; x < this._startX + this._maxX; x++) + { + // only -1 on TILED maps, not CSV + var tile = this.tileset.tiles[this._column[x]-1]; + + // if (this.tileset.checkTileIndex(tile)) + if (tile) + { + this.context.drawImage( + this.tileset.image, + tile.x, + tile.y, + this.tileWidth, + this.tileHeight, + Math.floor(this._tx), + Math.floor(this._ty), + this.tileWidth, + this.tileHeight + ); + } + + this._tx += this.tileWidth; + + } + + this._tx = this._dx; + this._ty += this.tileHeight; + } + + // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! + if (this.game.renderType == Phaser.WEBGL) + { + PIXI.texturesToUpdate.push(this.baseTexture); + } + + this.dirty = false; + + return true; + +} Phaser.TilemapLayer.prototype.deltaAbsX = function () { return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); @@ -33197,7 +33197,7 @@ Phaser.TilemapLayer.prototype.deltaY = function () { return this._dy - this._prevY; } -Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { +Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", { get: function () { return this._x; @@ -33205,7 +33205,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { set: function (value) { - if (value !== this._x && value >= 0) + if (value !== this._x && value >= 0 && this.layer) { this._x = value; @@ -33233,7 +33233,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { }); -Object.defineProperty(Phaser.TilemapLayer.prototype, "y", { +Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", { get: function () { return this._y; @@ -33241,7 +33241,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "y", { set: function (value) { - if (value !== this._y && value >= 0) + if (value !== this._y && value >= 0 && this.layer) { this._y = value; diff --git a/examples/particles/click burst.php b/examples/particles/click burst.php index 3c08026f..41b77b42 100644 --- a/examples/particles/click burst.php +++ b/examples/particles/click burst.php @@ -5,8 +5,6 @@ + + + + \ No newline at end of file diff --git a/src/gameobjects/Bullet.js b/src/gameobjects/Bullet.js index db43b354..4c131a3b 100644 --- a/src/gameobjects/Bullet.js +++ b/src/gameobjects/Bullet.js @@ -1,5 +1,625 @@ +/** +* @author Richard Davey +* @copyright 2013 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +* @module Phaser.Bullet +*/ + +/** +* Create a new Bullet. +* +* A Bullet is like a stripped-down Sprite, useful for when you just need to get something moving around the screen quickly with little of the extra +* features that a Sprite supports. +* Bullet is MISSING the following: +* +* animation, all input events, crop support, health/damage, loadTexture +* +* @class Phaser.Bullet +* @classdesc Description of class. +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {Description} x - Description. +* @param {Description} y - Description. +* @param {string} key - Description. +* @param {Description} frame - Description. +*/ Phaser.Bullet = function (game, x, y, key, frame) { + + x = x || 0; + y = y || 0; + key = key || null; + frame = frame || null; + + /** + * @property {Phaser.Game} game - A reference to the currently running Game. + */ + this.game = game; + + /** + * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all. + * @default + */ + this.exists = true; + + /** + * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering. + * @default + */ + this.alive = true; + + /** + * @property {Description} group - Description. + * @default + */ + this.group = null; + + /** + * @property {string} name - The user defined name given to this Sprite. + * @default + */ + this.name = ''; + + /** + * @property {Description} type - Description. + */ + this.type = Phaser.BULLET; + + /** + * @property {number} renderOrderID - Description. + * @default + */ + this.renderOrderID = -1; + + /** + * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc. + * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called. + * @property {number} lifespan + * @default + */ + this.lifespan = 0; + + /** + * @property {Events} events - The Signals you can subscribe to that are dispatched when certain things happen on this Sprite or its components + */ + this.events = new Phaser.Events(this); + + /** + * @property {Description} key - Description. + */ + this.key = key; + + if (key instanceof Phaser.RenderTexture) + { + PIXI.Sprite.call(this, key); + + this.currentFrame = this.game.cache.getTextureFrame(key.name); + } + else if (key instanceof PIXI.Texture) + { + PIXI.Sprite.call(this, key); + + this.currentFrame = frame; + } + else + { + if (key == null || this.game.cache.checkImageKey(key) == false) + { + key = '__default'; + } + + PIXI.Sprite.call(this, PIXI.TextureCache[key]); + + if (this.game.cache.isSpriteSheet(key)) + { + /* + this.animations.loadFrameData(this.game.cache.getFrameData(key)); + + if (frame !== null) + { + if (typeof frame === 'string') + { + this.frameName = frame; + } + else + { + this.frame = frame; + } + } + */ + } + else + { + this.currentFrame = this.game.cache.getFrame(key); + } + } + + /** + * The anchor sets the origin point of the texture. + * The default is 0,0 this means the textures origin is the top left + * Setting than anchor to 0.5,0.5 means the textures origin is centered + * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right + * + * @property {Phaser.Point} anchor + */ + this.anchor = new Phaser.Point(); + + /** + * @property {number} x - Description. + */ + this.x = x; + + /** + * @property {number} y - Description. + */ + this.y = y; + + /** + * @property {Description} position - Description. + */ + this.position.x = x; + this.position.y = y; + + /** + * Should this Sprite be automatically culled if out of range of the camera? + * A culled sprite has its visible property set to 'false'. + * Note that this check doesn't look at this Sprites children, which may still be in camera range. + * So you should set autoCull to false if the Sprite will have children likely to still be in camera range. + * + * @property {boolean} autoCull + * @default + */ + this.autoCull = false; + + /** + * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. + */ + this.scale = new Phaser.Point(1, 1); + + /** + * @property {Phaser.Point} _cache - A mini cache for storing all of the calculated values. + * @private + */ + this._cache = { + + dirty: false, + + // Transform cache + a00: -1, a01: -1, a02: -1, a10: -1, a11: -1, a12: -1, id: -1, + + // Input specific transform cache + i01: -1, i10: -1, idi: -1, + + // Bounds check + left: null, right: null, top: null, bottom: null, + + // The previous calculated position + x: -1, y: -1, + + // The actual scale values based on the worldTransform + scaleX: 1, scaleY: 1, + + // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size + width: this.currentFrame.sourceSizeW, height: this.currentFrame.sourceSizeH, + + // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size + halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2), halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2), + + boundsX: 0, boundsY: 0, + + // If this sprite visible to the camera (regardless of being set to visible or not) + cameraVisible: true + + }; + + /** + * @property {Phaser.Point} offset - Corner point defaults. + */ + this.offset = new Phaser.Point; + + /** + * @property {Phaser.Point} center - Description. + */ + this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2)); + + /** + * @property {Phaser.Point} topLeft - Description. + */ + this.topLeft = new Phaser.Point(x, y); + + /** + * @property {Phaser.Point} topRight - Description. + */ + this.topRight = new Phaser.Point(x + this._cache.width, y); + + /** + * @property {Phaser.Point} bottomRight - Description. + */ + this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height); + + /** + * @property {Phaser.Point} bottomLeft - Description. + */ + this.bottomLeft = new Phaser.Point(x, y + this._cache.height); + + /** + * @property {Phaser.Rectangle} bounds - Description. + */ + this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height); + + /** + * @property {Phaser.Physics.Arcade.Body} body - Set-up the physics body. + */ + this.body = new Phaser.Physics.Arcade.Body(this); + + /** + * @property {Description} inWorld - World bounds check. + */ + this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds); + + /** + * @property {number} inWorldThreshold - World bounds check. + * @default + */ + this.inWorldThreshold = 0; + + /** + * @property {boolean} outOfBoundsKill - Kills this sprite as soon as it goes outside of the World bounds. + * @default + */ + this.outOfBoundsKill = false; + + /** + * @property {boolean} _outOfBoundsFired - Description. + * @private + * @default + */ + this._outOfBoundsFired = false; + + /** + * A Sprite that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. + * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera. + * @default + */ + this.fixedToCamera = false; + }; Phaser.Bullet.prototype = Object.create(PIXI.Sprite.prototype); Phaser.Bullet.prototype.constructor = Phaser.Bullet; + +/** +* Automatically called by World.preUpdate. You can create your own update in Objects that extend Phaser.Sprite. +* @method Phaser.Sprite.prototype.preUpdate +*/ +Phaser.Bullet.prototype.preUpdate = function() { + + if (!this.exists) + { + this.renderOrderID = -1; + return; + } + + if (this.lifespan > 0) + { + this.lifespan -= this.game.time.elapsed; + + if (this.lifespan <= 0) + { + this.kill(); + return; + } + } + + this._cache.dirty = false; + + if (this.visible) + { + this.renderOrderID = this.game.world.currentRenderOrderID++; + } + + this.prevX = this.x; + this.prevY = this.y; + + // |a c tx| + // |b d ty| + // |0 0 1| + + if (this.worldTransform[1] != this._cache.i01 || this.worldTransform[3] != this._cache.i10) + { + this._cache.a00 = this.worldTransform[0]; // scaleX a + this._cache.a01 = this.worldTransform[1]; // skewY c + this._cache.a10 = this.worldTransform[3]; // skewX b + this._cache.a11 = this.worldTransform[4]; // scaleY d + + this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks) + this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks) + + this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit? + this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit? + + this._cache.a01 *= -1; + this._cache.a10 *= -1; + + this._cache.dirty = true; + } + + if (this.worldTransform[2] != this._cache.a02 || this.worldTransform[5] != this._cache.a12) + { + this._cache.a02 = this.worldTransform[2]; // translateX tx + this._cache.a12 = this.worldTransform[5]; // translateY ty + this._cache.dirty = true; + } + + // Re-run the camera visibility check + if (this._cache.dirty) + { + this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0); + + if (this.autoCull == true) + { + // Won't get rendered but will still get its transform updated + this.renderable = this._cache.cameraVisible; + } + + // Update our physics bounds + if (this.body) + { + this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); + } + } + + if (this.body) + { + this.body.preUpdate(); + } + +} + +Phaser.Bullet.prototype.postUpdate = function() { + + if (this.exists) + { + // The sprite is positioned in this call, after taking into consideration motion updates and collision + if (this.body) + { + this.body.postUpdate(); + } + + if (this.fixedToCamera) + { + this._cache.x = this.game.camera.view.x + this.x; + this._cache.y = this.game.camera.view.y + this.y; + } + else + { + this._cache.x = this.x; + this._cache.y = this.y; + } + + if (this.position.x != this._cache.x || this.position.y != this._cache.y) + { + this.position.x = this._cache.x; + this.position.y = this._cache.y; + } + } + +} + +Phaser.Bullet.prototype.deltaAbsX = function () { + return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); +} + +Phaser.Bullet.prototype.deltaAbsY = function () { + return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); +} + +Phaser.Bullet.prototype.deltaX = function () { + return this.x - this.prevX; +} + +Phaser.Bullet.prototype.deltaY = function () { + return this.y - this.prevY; +} + +/** +* Description. +* +* @method Phaser.Bullet.prototype.revive +*/ +Phaser.Bullet.prototype.revive = function(health) { + + if (typeof health === 'undefined') { health = 1; } + + this.alive = true; + this.exists = true; + this.visible = true; + this.health = health; + + this.events.onRevived.dispatch(this); + +} + +/** +* Description. +* +* @method Phaser.Bullet.prototype.kill +*/ +Phaser.Bullet.prototype.kill = function() { + + this.alive = false; + this.exists = false; + this.visible = false; + this.events.onKilled.dispatch(this); + +} + +/** +* Description. +* +* @method Phaser.Bullet.prototype.destroy +*/ +Phaser.Bullet.prototype.destroy = function() { + + if (this.group) + { + this.group.remove(this); + } + + this.events.destroy(); + + this.alive = false; + this.exists = false; + this.visible = false; + + this.game = null; + +} + +/** +* Description. +* +* @method Phaser.Sprite.prototype.reset +*/ +Phaser.Bullet.prototype.reset = function(x, y) { + + this.x = x; + this.y = y; + this.position.x = this.x; + this.position.y = this.y; + this.alive = true; + this.exists = true; + this.visible = true; + this.renderable = true; + this._outOfBoundsFired = false; + + if (this.body) + { + this.body.reset(); + } + +} + +/** +* Description. +* +* @method Phaser.Sprite.prototype.updateBounds +*/ +Phaser.Bullet.prototype.updateBounds = function() { + + // Update the edge points + + this.offset.setTo(this._cache.a02 - (this.anchor.x * this._cache.width), this._cache.a12 - (this.anchor.y * this._cache.height)); + + this.getLocalPosition(this.center, this.offset.x + this._cache.halfWidth, this.offset.y + this._cache.halfHeight); + this.getLocalPosition(this.topLeft, this.offset.x, this.offset.y); + this.getLocalPosition(this.topRight, this.offset.x + this._cache.width, this.offset.y); + this.getLocalPosition(this.bottomLeft, this.offset.x, this.offset.y + this._cache.height); + this.getLocalPosition(this.bottomRight, this.offset.x + this._cache.width, this.offset.y + this._cache.height); + + this._cache.left = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x); + this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x); + this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y); + this._cache.bottom = Phaser.Math.max(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y); + + this.bounds.setTo(this._cache.left, this._cache.top, this._cache.right - this._cache.left, this._cache.bottom - this._cache.top); + + // This is the coordinate the Bullet was at when the last bounds was created + this._cache.boundsX = this._cache.x; + this._cache.boundsY = this._cache.y; + + if (this.inWorld == false) + { + // Bullet WAS out of the screen, is it still? + this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold); + + if (this.inWorld) + { + // It's back again, reset the OOB check + this._outOfBoundsFired = false; + } + } + else + { + // Bullet WAS in the screen, has it now left? + this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold); + + if (this.inWorld == false) + { + this.events.onOutOfBounds.dispatch(this); + this._outOfBoundsFired = true; + + if (this.outOfBoundsKill) + { + this.kill(); + } + } + } + +} + +/** +* Description. +* +* @method Phaser.Bullet.prototype.getLocalPosition +* @param {Description} p - Description. +* @param {number} x - Description. +* @param {number} y - Description. +* @return {Description} Description. +*/ +Phaser.Bullet.prototype.getLocalPosition = function(p, x, y) { + + p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this._cache.scaleX) + this._cache.a02; + p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this._cache.scaleY) + this._cache.a12; + + return p; + +} + +/** +* Description. +* +* @method Phaser.Bullet.prototype.bringToTop +*/ +Phaser.Bullet.prototype.bringToTop = function() { + + if (this.group) + { + this.group.bringToTop(this); + } + else + { + this.game.world.bringToTop(this); + } + +} + +/** +* Indicates the rotation of the Bullet, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. +* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. +* If you wish to work in radians instead of degrees use the property Bullet.rotation instead. +* @name Phaser.Bullet#angle +* @property {number} angle - Gets or sets the Bullets angle of rotation in degrees. +*/ +Object.defineProperty(Phaser.Bullet.prototype, 'angle', { + + get: function() { + return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation)); + }, + + set: function(value) { + this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); + } + +}); + +/** +* Is this sprite visible to the camera or not? +* @returns {boolean} +*/ +Object.defineProperty(Phaser.Bullet.prototype, "inCamera", { + + get: function () { + return this._cache.cameraVisible; + } + +}); diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js index 1a7419d0..3095d1d7 100644 --- a/src/gameobjects/GameObjectFactory.js +++ b/src/gameobjects/GameObjectFactory.js @@ -83,10 +83,6 @@ Phaser.GameObjectFactory.prototype = { return group.create(x, y, key, frame); - // var child = new Phaser.Sprite(this.game, x, y, key, frame); - // parent.addChild(child); - // return child; - }, /** @@ -232,17 +228,43 @@ Phaser.GameObjectFactory.prototype = { * Description. * * @method tilemap - * @param {Description} x - Description. - * @param {Description} y - Description. * @param {Description} key - Description. - * @param {Description} resizeWorld - Description. - * @param {Description} tileWidth - Description. - * @param {Description} tileHeight - Description. * @return {Description} Description. */ - tilemap: function (x, y, key, resizeWorld, tileWidth, tileHeight) { + tilemap: function (key) { - return this.world.add(new Phaser.Tilemap(this.game, key, x, y, resizeWorld, tileWidth, tileHeight)); + return new Phaser.Tilemap(this.game, key); + + }, + + /** + * Description. + * + * @method tilemap + * @param {Description} key - Description. + * @return {Description} Description. + */ + tileset: function (key) { + + return this.game.cache.getTileset(key); + + }, + + /** + * Description. + * + * @method tileSprite + * @param {Description} x - Description. + * @param {Description} y - Description. + * @param {Description} width - Description. + * @param {Description} height - Description. + * @param {Description} key - Description. + * @param {Description} frame - Description. + * @return {Description} Description. + */ + tilemapLayer: function (x, y, width, height, tileset, tilemap, layer) { + + return this.world.add(new Phaser.TilemapLayer(this.game, x, y, width, height, tileset, tilemap, layer)); }, diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index 1efe45e8..249d95de 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -274,16 +274,6 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this.health = 1; - /** - * @property {Description} velocity - Description. - */ - // this.velocity = this.body.velocity; - - /** - * @property {Description} acceleration - Description. - */ - // this.acceleration = this.body.acceleration; - /** * @property {Description} inWorld - World bounds check. */ @@ -852,18 +842,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inCamera", { }); -/** -* -* @returns {boolean} -*/ -Object.defineProperty(Phaser.Sprite.prototype, "worldX", { - - get: function () { - return 1; - } - -}); - /** * Get the input enabled state of this Sprite. * @returns {Description} diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index c38ce7f5..62999ae5 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -36,6 +36,7 @@ Phaser.Physics.Arcade = function (game) { this._newVelocity2 = 0; this._average = 0; this._mapData = []; + this._mapTiles = 0; this._result = false; this._total = 0; this._angle = 0; @@ -182,9 +183,9 @@ Phaser.Physics.Arcade.prototype = { { this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideSpriteVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } // GROUPS @@ -198,21 +199,21 @@ Phaser.Physics.Arcade.prototype = { { this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideGroupVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } - // TILEMAPS - else if (object1.type == Phaser.TILEMAP) + // TILEMAP LAYERS + else if (object1.type == Phaser.TILEMAPLAYER) { if (object2.type == Phaser.SPRITE) { - this.collideSpriteVsTilemap(object2, object1, collideCallback, processCallback, callbackContext); + this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); } else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) { - this.collideGroupVsTilemap(object2, object1, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); } } // EMITTER @@ -226,9 +227,9 @@ Phaser.Physics.Arcade.prototype = { { this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); } - else if (object2.type == Phaser.TILEMAP) + else if (object2.type == Phaser.TILEMAPLAYER) { - this.collideGroupVsTilemap(object1, object2, collideCallback, processCallback, callbackContext); + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } } @@ -237,6 +238,70 @@ Phaser.Physics.Arcade.prototype = { }, + collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) { + + this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true); + + if (this._mapData.length > 1) + { + for (var i = 1; i < this._mapData.length; i++) + { + this.separateTile(sprite.body, this._mapData[i]); + + if (this._result) + { + // They collided, is there a custom process callback? + if (processCallback) + { + if (processCallback.call(callbackContext, sprite, this._mapData[i])) + { + this._total++; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, this._mapData[i]); + } + } + } + else + { + this._total++; + + if (collideCallback) + { + collideCallback.call(callbackContext, sprite, this._mapData[i]); + } + } + } + } + } + + }, + + collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext) { + + if (group.length == 0) + { + return; + } + + if (group._container.first._iNext) + { + var currentNode = group._container.first._iNext; + + do + { + if (currentNode.exists) + { + this.collideSpriteVsTilemapLayer(currentNode, tilemapLayer, collideCallback, processCallback, callbackContext); + } + currentNode = currentNode._iNext; + } + while (currentNode != group._container.last._iNext); + } + + }, + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) { this.separate(sprite1.body, sprite2.body); @@ -269,65 +334,6 @@ Phaser.Physics.Arcade.prototype = { }, - collideGroupVsTilemap: function (group, tilemap, collideCallback, processCallback, callbackContext) { - - if (group.length == 0) - { - return; - } - - if (group._container.first._iNext) - { - var currentNode = group._container.first._iNext; - - do - { - if (currentNode.exists) - { - this.collideSpriteVsTilemap(currentNode, tilemap, collideCallback, processCallback, callbackContext); - } - currentNode = currentNode._iNext; - } - while (currentNode != group._container.last._iNext); - } - - }, - - collideSpriteVsTilemap: function (sprite, tilemap, collideCallback, processCallback, callbackContext) { - - this._mapData = tilemap.collisionLayer.getTileOverlaps(sprite); - - // If the sprite actually collided with the tilemap then _mapData contains an array of the tiles it collided with - var i = this._mapData.length; - - while (i--) - { - if (processCallback) - { - // We've got a custom process callback to hit first - if (processCallback.call(callbackContext, sprite, this._mapData[i].tile)) - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, this._mapData[i].tile); - } - } - } - else - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, this._mapData[i].tile); - } - } - } - - }, - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) { if (group.length == 0) @@ -635,12 +641,7 @@ Phaser.Physics.Arcade.prototype = { */ separateTile: function (body, tile) { - if (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)) - { - return true; - } - - return false; + this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)); }, diff --git a/src/tilemap/TilemapLayer.js b/src/tilemap/TilemapLayer.js index ce861de4..5454b121 100644 --- a/src/tilemap/TilemapLayer.js +++ b/src/tilemap/TilemapLayer.js @@ -30,15 +30,13 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, */ this.texture = new PIXI.Texture(this.baseTexture); - this.frame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid()); + this.textureFrame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid()); - /** - * @property {Description} sprite - Description. - * @default - */ - this.sprite = new Phaser.Sprite(this.game, x, y, this.texture, this.frame); - this.sprite.fixedToCamera = true; + Phaser.Sprite.call(this, this.game, x, y, this.texture, this.textureFrame); + this.type = Phaser.TILEMAPLAYER; + + this.fixedToCamera = true; /** * @property {Description} tileset - Description. @@ -151,7 +149,6 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, this._prevX = 0; this._prevY = 0; - this.dirty = true; if (tileset instanceof Phaser.Tileset || typeof tileset === 'string') @@ -166,230 +163,232 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, }; -Phaser.TilemapLayer.prototype = { +Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.Sprite.prototype, PIXI.Sprite.prototype); +Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer; - update: function () { - this.x = this.game.camera.x; - this.y = this.game.camera.y; +Phaser.TilemapLayer.prototype.update = function () { - }, + this.scrollX = this.game.camera.x; + this.scrollY = this.game.camera.y; - resizeWorld: function () { + this.render(); - this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels); +} - }, +Phaser.TilemapLayer.prototype.resizeWorld = function () { - updateTileset: function (tileset) { + this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels); - if (tileset instanceof Phaser.Tileset) - { - this.tileset = tileset; - } - else if (typeof tileset === 'string') - { - this.tileset = this.game.cache.getTileset('tiles'); - } - else - { - return; - } +} - this.tileWidth = this.tileset.tileWidth; - this.tileHeight = this.tileset.tileHeight; - - this.updateMax(); - - }, - - updateMapData: function (tilemap, layer) { - - if (typeof layer === 'undefined') - { - layer = 0; - } - - if (tilemap instanceof Phaser.Tilemap) - { - this.tilemap = tilemap; - this.layer = this.tilemap.layers[layer]; - this.updateMax(); - } - - }, - - /** - * - * @method getTileOverlaps - * @param {GameObject} object - Tiles you want to get that overlaps this. - * @return {array} Array with tiles informations (each contains x, y, and the tile). - */ - getTiles: function (x, y, width, height, collides) { - - if (this.tilemap === null) - { - return; - } - - // Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all) - if (typeof collides === 'undefined') { collides = false; } - - // Cap the values - - if (x < 0) - { - x = 0; - } - - if (y < 0) - { - y = 0; - } - - if (width > this.widthInPixels) - { - width = this.widthInPixels; - } - - if (height > this.heightInPixels) - { - height = this.heightInPixels; - } - - var tileWidth = this.tileWidth * this.sprite.scale.x; - var tileHeight = this.tileHeight * this.sprite.scale.y; - - // Convert the pixel values into tile coordinates - this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth; - this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; - this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; - - this._results.length = 0; - - this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); - - var _index = 0; - var _tile = null; - var sx = 0; - var sy = 0; - - for (var wy = this._ty; wy < this._ty + this._th; wy++) - { - for (var wx = this._tx; wx < this._tx + this._tw; wx++) - { - if (this.layer.data[wy] && this.layer.data[wy][wx]) - { - // Could combine - _index = this.layer.data[wy][wx] - 1; - _tile = this.tileset.getTile(_index); - - sx = _tile.width * this.sprite.scale.x; - sy = _tile.height * this.sprite.scale.y; - - if (collides == false || (collides && _tile.collideNone == false)) - { - // this._results.push({ x: wx * _tile.width, right: (wx * _tile.width) + _tile.width, y: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); - this._results.push({ x: wx * sx, right: (wx * sx) + sx, y: wy * sy, bottom: (wy * sy) + sy, width: sx, height: sy, tx: wx, ty: wy, tile: _tile }); - } - } - } - } - - return this._results; - - }, - - updateMax: function () { - - this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1; - this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1; - - if (this.layer) - { - if (this._maxX > this.layer.width) - { - this._maxX = this.layer.width; - } - - if (this._maxY > this.layer.height) - { - this._maxY = this.layer.height; - } - - this.widthInPixels = this.layer.width * this.tileWidth; - this.heightInPixels = this.layer.height * this.tileHeight; - } - - this.dirty = true; - - }, - - render: function () { - - if (!this.dirty || !this.tileset || !this.tilemap || !this.sprite.visible) - { - return; - } - - this._prevX = this._dx; - this._prevY = this._dy; - - this._dx = -(this._x - (this._startX * this.tileWidth)); - this._dy = -(this._y - (this._startY * this.tileHeight)); - - this._tx = this._dx; - this._ty = this._dy; - - this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - - for (var y = this._startY; y < this._startY + this._maxY; y++) - { - this._column = this.layer.data[y]; - - for (var x = this._startX; x < this._startX + this._maxX; x++) - { - // only -1 on TILED maps, not CSV - var tile = this.tileset.tiles[this._column[x]-1]; - - // if (this.tileset.checkTileIndex(tile)) - if (tile) - { - this.context.drawImage( - this.tileset.image, - tile.x, - tile.y, - this.tileWidth, - this.tileHeight, - Math.floor(this._tx), - Math.floor(this._ty), - this.tileWidth, - this.tileHeight - ); - } - - this._tx += this.tileWidth; - - } - - this._tx = this._dx; - this._ty += this.tileHeight; - } - - // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! - if (this.game.renderType == Phaser.WEBGL) - { - PIXI.texturesToUpdate.push(this.baseTexture); - } - - this.dirty = false; - - return true; +Phaser.TilemapLayer.prototype.updateTileset = function (tileset) { + if (tileset instanceof Phaser.Tileset) + { + this.tileset = tileset; + } + else if (typeof tileset === 'string') + { + this.tileset = this.game.cache.getTileset('tiles'); + } + else + { + return; } -}; + this.tileWidth = this.tileset.tileWidth; + this.tileHeight = this.tileset.tileHeight; + + this.updateMax(); + +} + +Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) { + + if (typeof layer === 'undefined') + { + layer = 0; + } + + if (tilemap instanceof Phaser.Tilemap) + { + this.tilemap = tilemap; + this.layer = this.tilemap.layers[layer]; + this.updateMax(); + } + +} + +/** +* +* @method getTileOverlaps +* @param {GameObject} object - Tiles you want to get that overlaps this. +* @return {array} Array with tiles informations (each contains x, y, and the tile). +*/ +Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) { + + if (this.tilemap === null) + { + return; + } + + // Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all) + if (typeof collides === 'undefined') { collides = false; } + + // Cap the values + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (width > this.widthInPixels) + { + width = this.widthInPixels; + } + + if (height > this.heightInPixels) + { + height = this.heightInPixels; + } + + var tileWidth = this.tileWidth * this.scale.x; + var tileHeight = this.tileHeight * this.scale.y; + + // Convert the pixel values into tile coordinates + this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth; + this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight; + this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; + this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; + + this._results.length = 0; + + this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); + + var _index = 0; + var _tile = null; + var sx = 0; + var sy = 0; + + for (var wy = this._ty; wy < this._ty + this._th; wy++) + { + for (var wx = this._tx; wx < this._tx + this._tw; wx++) + { + if (this.layer.data[wy] && this.layer.data[wy][wx]) + { + // Could combine + _index = this.layer.data[wy][wx] - 1; + _tile = this.tileset.getTile(_index); + + sx = _tile.width * this.scale.x; + sy = _tile.height * this.scale.y; + + if (collides == false || (collides && _tile.collideNone == false)) + { + // this._results.push({ x: wx * _tile.width, right: (wx * _tile.width) + _tile.width, y: wy * _tile.height, bottom: (wy * _tile.height) + _tile.height, width: _tile.width, height: _tile.height, tx: wx, ty: wy, tile: _tile }); + this._results.push({ x: wx * sx, right: (wx * sx) + sx, y: wy * sy, bottom: (wy * sy) + sy, width: sx, height: sy, tx: wx, ty: wy, tile: _tile }); + } + } + } + } + + return this._results; + +} + +Phaser.TilemapLayer.prototype.updateMax = function () { + + this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1; + this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1; + + if (this.layer) + { + if (this._maxX > this.layer.width) + { + this._maxX = this.layer.width; + } + + if (this._maxY > this.layer.height) + { + this._maxY = this.layer.height; + } + + this.widthInPixels = this.layer.width * this.tileWidth; + this.heightInPixels = this.layer.height * this.tileHeight; + } + + this.dirty = true; + +} + +Phaser.TilemapLayer.prototype.render = function () { + + if (!this.dirty || !this.tileset || !this.tilemap || !this.visible) + { + return; + } + + this._prevX = this._dx; + this._prevY = this._dy; + + this._dx = -(this._x - (this._startX * this.tileWidth)); + this._dy = -(this._y - (this._startY * this.tileHeight)); + + this._tx = this._dx; + this._ty = this._dy; + + this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + + for (var y = this._startY; y < this._startY + this._maxY; y++) + { + this._column = this.layer.data[y]; + + for (var x = this._startX; x < this._startX + this._maxX; x++) + { + // only -1 on TILED maps, not CSV + var tile = this.tileset.tiles[this._column[x]-1]; + + // if (this.tileset.checkTileIndex(tile)) + if (tile) + { + this.context.drawImage( + this.tileset.image, + tile.x, + tile.y, + this.tileWidth, + this.tileHeight, + Math.floor(this._tx), + Math.floor(this._ty), + this.tileWidth, + this.tileHeight + ); + } + + this._tx += this.tileWidth; + + } + + this._tx = this._dx; + this._ty += this.tileHeight; + } + + // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! + if (this.game.renderType == Phaser.WEBGL) + { + PIXI.texturesToUpdate.push(this.baseTexture); + } + + this.dirty = false; + + return true; + +} Phaser.TilemapLayer.prototype.deltaAbsX = function () { return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); @@ -407,7 +406,7 @@ Phaser.TilemapLayer.prototype.deltaY = function () { return this._dy - this._prevY; } -Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { +Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", { get: function () { return this._x; @@ -415,7 +414,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { set: function (value) { - if (value !== this._x && value >= 0) + if (value !== this._x && value >= 0 && this.layer) { this._x = value; @@ -443,7 +442,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "x", { }); -Object.defineProperty(Phaser.TilemapLayer.prototype, "y", { +Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", { get: function () { return this._y; @@ -451,7 +450,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "y", { set: function (value) { - if (value !== this._y && value >= 0) + if (value !== this._y && value >= 0 && this.layer) { this._y = value;