From a01cc2e1ca6ccafc22534c22a37e2b142b134892 Mon Sep 17 00:00:00 2001 From: photonstorm Date: Fri, 11 Apr 2014 00:06:22 +0100 Subject: [PATCH] Objects with an InputHandler now deactivate it when the object is removed from a Group but not destroyed (fix #672) Lots of jsdoc fixes in Body and World. Removed un-used events from World (such as onImpact). --- README.md | 4 +++ src/core/Group.js | 31 +++++++++++++++++++++--- src/input/InputHandler.js | 51 ++++++++++++++++++++++++++++++++++++--- src/physics/p2/Body.js | 22 ++++++++--------- src/physics/p2/World.js | 51 ++++++++++++++++++++++++--------------- 5 files changed, 121 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index e184a6695..d667c318a 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,9 @@ New Features * Emitter.bringToTop and Emitter.sendToBack are booleans that let you optionally set the display order of the Particle when emitted. * Emitter now calls the Phaser.Particle.onEmit function, which is left empty for you to override and add in custom behaviours. * p2.World has a new contactMaterial property, which can be configured like a normal P2 Contact Material and is applied when two bodies hit that don't have defined materials. +* Group.remove has a new 'destroy' parameter (false by default), which will optionally call destroy on the item removed from the Group. +* Group.removeAll has a new 'destroy' parameter (false by default), which will optionally call destroy on the items removed from the Group. +* Group.removeBetween has a new 'destroy' parameter (false by default), which will optionally call destroy on the items removed from the Group. Bug Fixes @@ -140,6 +143,7 @@ Bug Fixes * Emitter.minParticleScale and maxParticleScale wasn't resetting the Body size correctly. * Group.removeBetween now properly iterates through the children. * P2.World had a type in the restitution method title. Now fixed. +* Objects with an InputHandler now deactivate it when the object is removed from a Group but not destroyed (fix #672) p2.js v0.5.0 diff --git a/src/core/Group.js b/src/core/Group.js index cafb7ba7d..e91b6d621 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -1394,13 +1394,16 @@ Phaser.Group.prototype.getRandom = function (startIndex, length) { * * @method Phaser.Group#remove * @param {Any} child - The child to remove. +* @param {boolean} [destroy=false] - You can optionally call destroy on the child that was removed. * @return {boolean} true if the child was removed from this Group, otherwise false. */ -Phaser.Group.prototype.remove = function (child) { +Phaser.Group.prototype.remove = function (child, destroy) { + + if (typeof destroy === 'undefined') { destroy = false; } if (this.children.length === 0) { - return; + return false; } if (child.events) @@ -1417,6 +1420,11 @@ Phaser.Group.prototype.remove = function (child) { this.next(); } + if (destroy) + { + child.destroy(); + } + return true; }; @@ -1426,8 +1434,11 @@ Phaser.Group.prototype.remove = function (child) { * The Group container remains on the display list. * * @method Phaser.Group#removeAll +* @param {boolean} [destroy=false] - You can optionally call destroy on the child that was removed. */ -Phaser.Group.prototype.removeAll = function () { +Phaser.Group.prototype.removeAll = function (destroy) { + + if (typeof destroy === 'undefined') { destroy = false; } if (this.children.length === 0) { @@ -1442,6 +1453,11 @@ Phaser.Group.prototype.removeAll = function () { } this.removeChild(this.children[0]); + + if (destroy) + { + this.children[0].destroy(); + } } while (this.children.length > 0); @@ -1455,10 +1471,12 @@ Phaser.Group.prototype.removeAll = function () { * @method Phaser.Group#removeBetween * @param {number} startIndex - The index to start removing children from. * @param {number} [endIndex] - The index to stop removing children at. Must be higher than startIndex. If undefined this method will remove all children between startIndex and the end of the Group. +* @param {boolean} [destroy=false] - You can optionally call destroy on the child that was removed. */ -Phaser.Group.prototype.removeBetween = function (startIndex, endIndex) { +Phaser.Group.prototype.removeBetween = function (startIndex, endIndex, destroy) { if (typeof endIndex === 'undefined') { endIndex = this.children.length; } + if (typeof destroy === 'undefined') { destroy = false; } if (this.children.length === 0) { @@ -1481,6 +1499,11 @@ Phaser.Group.prototype.removeBetween = function (startIndex, endIndex) { this.removeChild(this.children[i]); + if (destroy) + { + this.children[i].destroy(); + } + if (this.cursor === this.children[i]) { this.cursor = null; diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js index f2efbbc2e..639039da4 100644 --- a/src/input/InputHandler.js +++ b/src/input/InputHandler.js @@ -162,6 +162,12 @@ Phaser.InputHandler = function (sprite) { */ this.consumePointerEvent = false; + /** + * @property {boolean} _wasEnabled - Internal cache var. + * @private + */ + this._wasEnabled = false; + /** * @property {Phaser.Point} _tempPoint - Internal cache var. * @private @@ -235,6 +241,7 @@ Phaser.InputHandler.prototype = { this.snapOffset = new Phaser.Point(); this.enabled = true; + this._wasEnabled = true; // Create the signals the Input component will emit if (this.sprite.events && this.sprite.events.onInputOver === null) @@ -248,10 +255,48 @@ Phaser.InputHandler.prototype = { } } + this.sprite.events.onAddedToGroup.add(this.addedToGroup, this); + this.sprite.events.onRemovedFromGroup.add(this.removedFromGroup, this); + return this.sprite; }, + /** + * Handles when the parent Sprite is added to a new Group. + * + * @method Phaser.InputHandler#addedToGroup + * @private + */ + addedToGroup: function () { + + if (this._wasEnabled && !this.enabled) + { + this.start(); + } + + }, + + /** + * Handles when the parent Sprite is removed from a Group. + * + * @method Phaser.InputHandler#removedFromGroup + * @private + */ + removedFromGroup: function () { + + if (this.enabled) + { + this._wasEnabled = true; + this.stop(); + } + else + { + this._wasEnabled = false; + } + + }, + /** * Resets the Input Handler and disables it. * @method Phaser.InputHandler#reset @@ -553,7 +598,7 @@ Phaser.InputHandler.prototype = { */ checkPointerDown: function (pointer) { - if (this.enabled === false || this.sprite.visible === false || this.sprite.parent.visible === false) + if (!this.enabled || !this.sprite || !this.sprite.parent || !this.sprite.visible || !this.sprite.parent.visible) { return false; } @@ -583,7 +628,7 @@ Phaser.InputHandler.prototype = { */ checkPointerOver: function (pointer) { - if (this.enabled === false || this.sprite.visible === false || this.sprite.parent.visible === false) + if (!this.enabled || !this.sprite || !this.sprite.parent || !this.sprite.visible || !this.sprite.parent.visible) { return false; } @@ -665,7 +710,7 @@ Phaser.InputHandler.prototype = { */ update: function (pointer) { - if (this.sprite === null) + if (this.sprite === null || this.sprite.parent === undefined) { // Abort. We've been destroyed. return; diff --git a/src/physics/p2/Body.js b/src/physics/p2/Body.js index e2ed6641b..397ffe8d2 100644 --- a/src/physics/p2/Body.js +++ b/src/physics/p2/Body.js @@ -57,6 +57,7 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { * @protected */ this.data = new p2.Body({ position: [ this.world.pxmi(x), this.world.pxmi(y) ], mass: mass }); + this.data.parent = this; /** @@ -74,12 +75,6 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { */ this.gravity = new Phaser.Point(); - /** - * Dispatched when the shape/s of this Body impact with another. The event will be sent 2 parameters, this Body and the impact Body. - * @property {Phaser.Signal} onImpact - */ - this.onImpact = new Phaser.Signal(); - /** * Dispatched when a first contact is created between shapes in two bodies. This event is fired during the step, so collision has already taken place. * The event will be sent 4 parameters: The body it is in contact with, the shape from this body that caused the contact, the shape from the contact body and the contact equation data array. @@ -96,7 +91,6 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { /** * @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with. - * @private */ this.collidesWith = []; @@ -105,6 +99,15 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { */ this.removeNextStep = false; + /** + * @property {Phaser.Physics.P2.BodyDebug} debugBody - Reference to the debug body. + */ + this.debugBody = null; + + /** + * @property {boolean} _collideWorldBounds - Internal var that determines if this Body collides with the world bounds or not. + * @private + */ this._collideWorldBounds = true; /** @@ -131,11 +134,6 @@ Phaser.Physics.P2.Body = function (game, sprite, x, y, mass) { */ this._groupCallbackContext = {}; - /** - * @property {Phaser.Physics.P2.BodyDebug} debugBody - Reference to the debug body. - */ - this.debugBody = null; - // Set-up the default shape if (sprite) { diff --git a/src/physics/p2/World.js b/src/physics/p2/World.js index c72d8c5a9..e76ce5f14 100644 --- a/src/physics/p2/World.js +++ b/src/physics/p2/World.js @@ -28,7 +28,7 @@ Phaser.Physics.P2 = function (game, config) { } /** - * @property {p2.World} game - The p2 World in which the simulation is run. + * @property {p2.World} world - The p2 World in which the simulation is run. * @protected */ this.world = new p2.World(config); @@ -52,7 +52,7 @@ Phaser.Physics.P2 = function (game, config) { this.materials = []; /** - * @property {Phaser.InversePointProxy} gravity - The gravity applied to all bodies each step. + * @property {Phaser.Physics.P2.InversePointProxy} gravity - The gravity applied to all bodies each step. */ this.gravity = new Phaser.Physics.P2.InversePointProxy(this, this.world.gravity); @@ -102,16 +102,14 @@ Phaser.Physics.P2 = function (game, config) { this.onContactMaterialRemoved = new Phaser.Signal(); /** - * @property {Phaser.Signal} onPostBroadphase - Dispatched after the Broadphase has collected collision pairs in the world. + * @property {function} postBroadphaseCallback - A postBroadphase callback. */ this.postBroadphaseCallback = null; - this.callbackContext = null; /** - * @property {Phaser.Signal} onImpact - Dispatched when a first contact is created between two bodies. This event is fired after the step has been done. + * @property {object} callbackContext - The context under which the callbacks are fired. */ - // this.onImpact = new Phaser.Signal(); - this.impactCallback = null; + this.callbackContext = null; /** * @property {Phaser.Signal} onBeginContact - Dispatched when a first contact is created between two bodies. This event is fired before the step has been done. @@ -137,27 +135,42 @@ Phaser.Physics.P2 = function (game, config) { this.world.on("endContact", this.endContactHandler, this); /** - * @property {array} _toRemove - Internal var used to hold references to bodies to remove from the world on the next step. - */ - this._toRemove = []; - - /** - * @property {array} collisionGroups - Internal var. + * @property {array} collisionGroups - An array containing the collision groups that have been defined in the World. */ this.collisionGroups = []; + /** + * @property {Phaser.Physics.P2.CollisionGroup} nothingCollisionGroup - A default collision group. + */ + this.nothingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(1); + + /** + * @property {Phaser.Physics.P2.CollisionGroup} boundsCollisionGroup - A default collision group. + */ + this.boundsCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2); + + /** + * @property {Phaser.Physics.P2.CollisionGroup} everythingCollisionGroup - A default collision group. + */ + this.everythingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2147483648); + + /** + * @property {array} boundsCollidesWith - An array of the bodies the world bounds collides with. + */ + this.boundsCollidesWith = []; + + /** + * @property {array} _toRemove - Internal var used to hold references to bodies to remove from the world on the next step. + * @private + */ + this._toRemove = []; + /** * @property {number} _collisionGroupID - Internal var. * @private */ this._collisionGroupID = 2; - this.nothingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(1); - this.boundsCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2); - this.everythingCollisionGroup = new Phaser.Physics.P2.CollisionGroup(2147483648); - - this.boundsCollidesWith = []; - // By default we want everything colliding with everything this.setBoundsToWorld(true, true, true, true, false);